📄 realmatriximpl.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 org.apache.commons.math.util.MathUtils;/** * Implementation of RealMatrix using a double[][] array to store entries and * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> * LU decomposition</a> to support linear system * solution and inverse. * <p> * The LU decomposition 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 cached and reused on subsequent calls. * 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 RealMatrix} 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 RealMatrixImpl implements RealMatrix, Serializable { /** Serializable version identifier */ private static final long serialVersionUID = 4237564493130426188L; /** Entries of the matrix */ private double data[][] = null; /** Entries of cached LU decomposition. * All updates to data (other than luDecompose()) *must* set this to null */ private double lu[][] = null; /** Permutation associated with LU decomposition */ 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 * @throws IllegalArgumentException if row or column dimension is not * positive */ public RealMatrixImpl(int rowDimension, int columnDimension) { if (rowDimension <= 0 || columnDimension <= 0) { throw new IllegalArgumentException( "row and column dimensions must be postive"); } data = new double[rowDimension][columnDimension]; lu = null; } /** * Create a new RealMatrix using the input array as the underlying * data array. * <p> * The input array is copied, not referenced.</p> * * @param d data for new matrix * @throws IllegalArgumentException if <code>data</code> is not rectangular * (not all rows have the same length) or empty * @throws NullPointerException if <code>data</code> is null */ 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.</p> * * @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]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col] + m.getEntry(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]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col] - m.getEntry(row, col); } } return new RealMatrixImpl(outData); } /** * Returns the result of adding d to each entry of this. * * @param d value to be added to each entry * @return d + this */ public RealMatrix scalarAdd(double d) { int rowCount = this.getRowDimension(); int columnCount = this.getColumnDimension(); double[][] outData = new double[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col] + d; } } return new RealMatrixImpl(outData); } /** * Returns the result multiplying each entry of this by <code>d</code> * @param d value to multiply all entries by * @return d * this */ public RealMatrix scalarMultiply(double d) { int rowCount = this.getRowDimension(); int columnCount = this.getColumnDimension(); double[][] outData = new double[rowCount][columnCount]; for (int row = 0; row < rowCount; row++) { for (int col = 0; col < columnCount; col++) { outData[row][col] = data[row][col] * d; } } return new RealMatrixImpl(outData); } /** * Returns the result of postmultiplying this by <code>m</code>. * @param m matrix to postmultiply by * @return this*m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public RealMatrix multiply(RealMatrix m) throws IllegalArgumentException { if (this.getColumnDimension() != m.getRowDimension()) { throw new IllegalArgumentException("Matrices are not multiplication compatible."); } int nRows = this.getRowDimension(); int nCols = m.getColumnDimension(); int nSum = this.getColumnDimension(); double[][] 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] * m.getEntry(i, col); } outData[row][col] = sum; } } return new RealMatrixImpl(outData); } /** * Returns the result premultiplying this by <code>m</code>. * @param m matrix to premultiply by * @return m * this * @throws IllegalArgumentException * if rowDimension(this) != columnDimension(m) */ public RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException { return m.multiply(this); } /** * Returns matrix entries as a two-dimensional array. * <p> * Makes a fresh copy of the underlying data.</p> * * @return 2-dimensional array of entries */ public double[][] getData() { return copyOut(); } /** * Returns a reference to the underlying data array. * <p> * Does not make a fresh copy of the underlying data.</p> * * @return 2-dimensional array of entries */ public double[][] getDataRef() { return data; } /** * * @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; } /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param startRow Initial row index * @param endRow Final row index * @param startColumn Initial column index * @param endColumn Final column index * @return The subMatrix containing the data of the * specified rows and columns * @exception MatrixIndexException if row or column selections are not valid */ public RealMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) throws MatrixIndexException { if (startRow < 0 || startRow > endRow || endRow > data.length || startColumn < 0 || startColumn > endColumn || endColumn > data[0].length ) { throw new MatrixIndexException( "invalid row or column index selection"); } RealMatrixImpl subMatrix = new RealMatrixImpl(endRow - startRow+1, endColumn - startColumn+1); double[][] subMatrixData = subMatrix.getDataRef(); for (int i = startRow; i <= endRow; i++) { for (int j = startColumn; j <= endColumn; j++) { subMatrixData[i - startRow][j - startColumn] = data[i][j]; } } return subMatrix; } /** * Gets a submatrix. Rows and columns are indicated * counting from 0 to n-1. * * @param selectedRows Array of row indices must be non-empty * @param selectedColumns Array of column indices must be non-empty * @return The subMatrix containing the data in the * specified rows and columns * @exception MatrixIndexException if supplied row or column index arrays * are not valid */ public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) throws MatrixIndexException { if (selectedRows.length * selectedColumns.length == 0) { throw new MatrixIndexException( "selected row and column index arrays must be non-empty"); } RealMatrixImpl subMatrix = new RealMatrixImpl(selectedRows.length, selectedColumns.length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -