📄 bigmatriximpl.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.math.linear;import java.io.Serializable;import java.math.BigDecimal;/** * Implementation of {@link BigMatrix} using a BigDecimal[][] array to store entries * and <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> * LU decompostion</a> to support linear system * solution and inverse. * <p> * The LU decompostion is performed as needed, to support the following operations: <ul> * <li>solve</li> * <li>isSingular</li> * <li>getDeterminant</li> * <li>inverse</li> </ul></p> * <p>* <strong>Usage notes</strong>:<br> * <ul><li> * The LU decomposition is stored and reused on subsequent calls. If matrix * data are modified using any of the public setXxx methods, the saved * decomposition is discarded. If data are modified via references to the * underlying array obtained using <code>getDataRef()</code>, then the stored * LU decomposition will not be discarded. In this case, you need to * explicitly invoke <code>LUDecompose()</code> to recompute the decomposition * before using any of the methods above.</li> * <li> * As specified in the {@link BigMatrix} interface, matrix element indexing * is 0-based -- e.g., <code>getEntry(0, 0)</code> * returns the element in the first row, first column of the matrix.</li></ul></p> * * @version $Revision: 617953 $ $Date: 2008-02-02 22:54:00 -0700 (Sat, 02 Feb 2008) $ */public class BigMatrixImpl implements BigMatrix, Serializable { /** Serialization id */ private static final long serialVersionUID = -1011428905656140431L; /** Entries of the matrix */ private BigDecimal data[][] = null; /** Entries of cached LU decomposition. * All updates to data (other than luDecompose()) *must* set this to null */ private BigDecimal lu[][] = null; /** Permutation associated with LU decomposition */ private int[] permutation = null; /** Parity of the permutation associated with the LU decomposition */ private int parity = 1; /** Rounding mode for divisions **/ private int roundingMode = BigDecimal.ROUND_HALF_UP; /*** BigDecimal scale ***/ private int scale = 64; /** Bound to determine effective singularity in LU decomposition */ protected static BigDecimal TOO_SMALL = new BigDecimal(10E-12); /** BigDecimal 0 */ static final BigDecimal ZERO = new BigDecimal(0); /** BigDecimal 1 */ static final BigDecimal ONE = new BigDecimal(1); /** * Creates a matrix with no data */ public BigMatrixImpl() { } /** * Create a new BigMatrix 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 * @throws IllegalArgumentException if row or column dimension is not * positive */ public BigMatrixImpl(int rowDimension, int columnDimension) { if (rowDimension <=0 || columnDimension <=0) { throw new IllegalArgumentException ("row and column dimensions must be positive"); } data = new BigDecimal[rowDimension][columnDimension]; lu = null; } /** * Create a new BigMatrix using the <code>data</code> as the underlying * data array. * <p> * The input array is copied, not referenced.</p> * * @param d data for new matrix * @throws IllegalArgumentException if <code>d</code> is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if <code>d</code> is null */ public BigMatrixImpl(BigDecimal[][] d) { this.copyIn(d); lu = null; } /** * Create a new BigMatrix using the <code>data</code> as the underlying * data array. * <p> * The input array is copied, not referenced.</p> * * @param d data for new matrix * @throws IllegalArgumentException if <code>d</code> is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if <code>d</code> is null */ public BigMatrixImpl(double[][] d) { int nRows = d.length; if (nRows == 0) { throw new IllegalArgumentException( "Matrix must have at least one row."); } int nCols = d[0].length; if (nCols == 0) { throw new IllegalArgumentException( "Matrix must have at least one column."); } for (int row = 1; row < nRows; row++) { if (d[row].length != nCols) { throw new IllegalArgumentException( "All input rows must have the same length."); } } this.copyIn(d); lu = null; } /** * Create a new BigMatrix using the values represented by the strings in * <code>data</code> as the underlying data array. * * @param d data for new matrix * @throws IllegalArgumentException if <code>d</code> is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if <code>d</code> is null */ public BigMatrixImpl(String[][] d) { int nRows = d.length; if (nRows == 0) { throw new IllegalArgumentException( "Matrix must have at least one row."); } int nCols = d[0].length; if (nCols == 0) { throw new IllegalArgumentException( "Matrix must have at least one column."); } for (int row = 1; row < nRows; row++) { if (d[row].length != nCols) { throw new IllegalArgumentException( "All input rows must have the same length."); } } this.copyIn(d); lu = null; } /** * Create a new (column) BigMatrix 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.</p> * * @param v column vector holding data for new matrix */ public BigMatrixImpl(BigDecimal[] v) { int nRows = v.length; data = new BigDecimal[nRows][1]; for (int row = 0; row < nRows; row++) { data[row][0] = v[row]; } } /** * Create a new BigMatrix which is a copy of this. * * @return the cloned matrix */ public BigMatrix copy() { return new BigMatrixImpl(this.copyOut()); } /** * Compute the sum of this and <code>m</code>. * * @param m matrix to be added * @return this + m * @exception IllegalArgumentException if m is not the same size as this */ public BigMatrix add(BigMatrix 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(); BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col].add(m.getEntry(row, col)); } } return new BigMatrixImpl(outData); } /** * Compute this minus <code>m</code>. * * @param m matrix to be subtracted * @return this + m * @exception IllegalArgumentException if m is not the same size as *this */ public BigMatrix subtract(BigMatrix 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(); BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col].subtract(m.getEntry(row, col)); } } return new BigMatrixImpl(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 BigMatrix scalarAdd(BigDecimal d) { int rowCount = this.getRowDimension(); int columnCount = this.getColumnDimension(); BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col].add(d); } } return new BigMatrixImpl(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 BigMatrix scalarMultiply(BigDecimal d) { int rowCount = this.getRowDimension(); int columnCount = this.getColumnDimension(); BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col].multiply(d); } } return new BigMatrixImpl(outData); } /** * Returns the result of postmultiplying this by <code>m</code>. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public BigMatrix multiply(BigMatrix 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(); BigDecimal[][] outData = new BigDecimal[nRows][nCols]; BigDecimal sum = ZERO; for (int row = 0; row < nRows; row++) { for (int col = 0; col < nCols; col++) { sum = ZERO; for (int i = 0; i < nSum; i++) { sum = sum.add(data[row][i].multiply(m.getEntry(i, col))); } outData[row][col] = sum; } } return new BigMatrixImpl(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 BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException { return m.multiply(this); } /** * Returns matrix entries as a two-dimensional array.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -