commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pste...@apache.org
Subject cvs commit: jakarta-commons/math/src/java/org/apache/commons/math/linear RealMatrixImpl.java
Date Thu, 08 Apr 2004 07:01:17 GMT
psteitz     2004/04/08 00:01:17

  Modified:    math/src/java/org/apache/commons/math/linear
                        RealMatrixImpl.java
  Log:
  Modified luDecompose to require that the matrix be square.
  Added RealMatrix preMultiply(RealMatrix).
  Modified preMultiply(double[]) to return a double[].
  Renamed private pivot[] array to permutation[].
  Exposed lu decomposition matrix and associated permutation
  array as protected properties.
  
  Revision  Changes    Path
  1.16      +100 -32   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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- RealMatrixImpl.java	3 Apr 2004 22:18:04 -0000	1.15
  +++ RealMatrixImpl.java	8 Apr 2004 07:01:17 -0000	1.16
  @@ -49,19 +49,19 @@
   	/** Entries of the matrix */
   	private double data[][] = null;
   
  -	/** Entries of LU decomposition.
  -	 * All updates to data (other than luDecompostion) *must* set this to null
  +	/** Entries of cached LU decomposition.
  +	 *  All updates to data (other than luDecompose()) *must* set this to null
   	 */
   	private double lu[][] = null;
   
  -	/** Pivot array associated with LU decompostion */
  -	private int[] pivot = 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 */
  -	private static double TOO_SMALL = 10E-12;
  +	protected static double TOO_SMALL = 10E-12;
   
   	/** 
   	 * Creates a matrix with no data
  @@ -240,6 +240,17 @@
   		}
   		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.
  @@ -422,7 +433,7 @@
   			return det;
   		}
   	}
  -
  +    
   	/**
   	 * @return true if the matrix is square (rowDimension = columnDimension)
   	 */
  @@ -436,7 +447,7 @@
   	public boolean isSingular() {
   		if (lu == null) {
   			try {
  -				LUDecompose();
  +				luDecompose();
   				return false;
   			} catch (InvalidMatrixException ex) {
   				return true;
  @@ -502,15 +513,21 @@
   	 * @throws IllegalArgumentException if rowDimension != v.length
   	 * @return resulting matrix
   	 */
  -	public RealMatrix preMultiply(double[] v) throws IllegalArgumentException {
  -		int nCols = this.getColumnDimension();
  -		if (v.length != nCols) {
  +	public double[] preMultiply(double[] v) throws IllegalArgumentException {
  +		int nRows = this.getRowDimension();
  +		if (v.length != nRows) {
   			throw new IllegalArgumentException("vector has wrong length");
   		}
  -		// being a bit lazy here -- probably should implement directly, like
  -		// operate
  -		RealMatrix pm = new RealMatrixImpl(v).transpose();
  -		return pm.multiply(this);
  +        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;
   	}
   
   	/**
  @@ -569,7 +586,7 @@
   		double[][] bp = new double[nRowB][nColB];
   		for (int row = 0; row < nRowB; row++) {
   			for (int col = 0; col < nColB; col++) {
  -				bp[row][col] = bv[pivot[row]][col];
  +				bp[row][col] = bv[permutation[row]][col];
   			}
   		}
   		bv = null;
  @@ -602,7 +619,7 @@
   	/**
   	 * 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.
  +	 * 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/
  @@ -616,22 +633,21 @@
   	 * made using setXxx methods will trigger recomputation when needed
   	 * automatically.
   	 *
  -	 * @throws InvalidMatrixException if the matrix is singular or if the matrix has more
rows than columns
  +	 * @throws InvalidMatrixException if the matrix is non-square or singular.
   	 */
  -	public void LUDecompose() throws InvalidMatrixException {
  -		// @TODO Bad method name - get rid of leading capitals
  -		
  +	public void luDecompose() throws InvalidMatrixException {
  +		 
   		int nRows = this.getRowDimension();
   		int nCols = this.getColumnDimension();
  -		if (nRows < nCols) {
  -			throw new InvalidMatrixException("LU decomposition requires row dimension >= column
dimension");
  +		if (nRows != nCols) {
  +			throw new InvalidMatrixException("LU decomposition requires that the matrix be square.");
   		}
   		lu = this.getData();
   
  -		// Initialize pivot array and parity
  -		pivot = new int[nRows];
  +		// Initialize permutation array and parity
  +		permutation = new int[nRows];
   		for (int row = 0; row < nRows; row++) {
  -			pivot[row] = row;
  +			permutation[row] = row;
   		}
   		parity = 1;
   
  @@ -650,7 +666,7 @@
   			}
   
   			// lower
  -			int max = col; // pivot row
  +			int max = col; // permutation row
   			double largest = 0d;
   			for (int row = col; row < nRows; row++) {
   				sum = lu[row][col];
  @@ -659,7 +675,7 @@
   				}
   				lu[row][col] = sum;
   
  -				// maintain best pivot choice
  +				// maintain best permutation choice
   				if (Math.abs(sum) > largest) {
   					largest = Math.abs(sum);
   					max = row;
  @@ -680,9 +696,9 @@
   					lu[max][i] = lu[col][i];
   					lu[col][i] = tmp;
   				}
  -				int temp = pivot[max];
  -				pivot[max] = pivot[col];
  -				pivot[col] = temp;
  +				int temp = permutation[max];
  +				permutation[max] = permutation[col];
  +				permutation[col] = temp;
   				parity = -parity;
   			}
   
  @@ -733,6 +749,58 @@
   		}
   		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
   
  @@ -778,5 +846,5 @@
   
   		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


Mime
View raw message