You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ps...@apache.org on 2004/06/06 00:31:16 UTC

cvs commit: jakarta-commons/math/src/java/org/apache/commons/math/linear RealMatrixImpl.java

psteitz     2004/06/05 15:31:16

  Modified:    math/src/java/org/apache/commons/math/linear
                        RealMatrixImpl.java
  Log:
  Converted tabs to spaces.
  
  Revision  Changes    Path
  1.23      +764 -764  jakarta-commons/math/src/java/org/apache/commons/math/linear/RealMatrixImpl.java
  
  Index: RealMatrixImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/linear/RealMatrixImpl.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- RealMatrixImpl.java	5 Jun 2004 22:28:10 -0000	1.22
  +++ RealMatrixImpl.java	5 Jun 2004 22:31:16 -0000	1.23
  @@ -45,190 +45,190 @@
       /** Serializable version identifier */
       static final long serialVersionUID = 4237564493130426188L;
       
  -	/** Entries of the matrix */
  -	private double data[][] = null;
  +    /** 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 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);
  -	}
  +    /** 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 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>.
  @@ -241,272 +241,272 @@
           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, 1 ) ) {
  -			throw new MatrixIndexException("illegal row argument");
  -		}
  -		int ncols = this.getColumnDimension();
  -		double[] out = new double[ncols];
  -		System.arraycopy(data[row - 1], 0, out, 0, ncols);
  -		return 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(1, 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 - 1];
  -		}
  -		return 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 - 1][column - 1];
  -	}
  -
  -	/**
  -	 * 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 - 1][column - 1] = 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 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, 1 ) ) {
  +            throw new MatrixIndexException("illegal row argument");
  +        }
  +        int ncols = this.getColumnDimension();
  +        double[] out = new double[ncols];
  +        System.arraycopy(data[row - 1], 0, out, 0, ncols);
  +        return 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(1, 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 - 1];
  +        }
  +        return 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 - 1][column - 1];
  +    }
  +
  +    /**
  +     * 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 - 1][column - 1] = 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 = (double) parity;
  -			for (int i = 0; i < this.getRowDimension(); i++) {
  -				det *= lu[i][i];
  -			}
  -			return det;
  -		}
  -	}
  +     * @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 = (double) 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");
  -		}
  +    /**
  +     * @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++) {
  @@ -517,324 +517,324 @@
               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.");
  +        }
   
  -	/**
  -	 * 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];
  -			}
  -		}
  -	}
  -
  -	/**
  -	 * 
  -	 * @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 < 1 || row > nRows || col < 1 || col > nCols);
  -	}
  -	
  +        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];
  +            }
  +        }
  +    }
  +
  +    /**
  +     * 
  +     * @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 < 1 || row > nRows || col < 1 || col > nCols);
  +    }
  +    
   }
  
  
  

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