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