added an abstract implementation of RealMatrix and used it for RealMatrixImpl
JIRA: MATH-231 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@724141 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
eec0bdccd6
commit
2dc7b2d460
|
@ -187,8 +187,22 @@ public class MessagesResources_fr
|
|||
{ "index {0} out of allowed range [{1}, {2}]",
|
||||
"index {0} hors de la plage autoris\u00e9e [{1}, {2}]" },
|
||||
|
||||
// org.apache.commons.math.linear.AbstractRealMatrix
|
||||
{ "invalid row dimension: {0} (must be positive)",
|
||||
"nombre de lignes invalide : {0} (doit \u00eatre positif)" },
|
||||
{ "invalid column dimension: {0} (must be positive)",
|
||||
"nombre de colonnes invalide : {0} (doit \u00eatre positif)" },
|
||||
{ "vector length mismatch: got {0} but expected {1}",
|
||||
"taille de vecteur invalide : {0} au lieu de {1} attendue" },
|
||||
|
||||
// org.apache.commons.math.linear.BigMatrixImpl
|
||||
// org.apache.commons.math.linear.RealMatrixImpl
|
||||
{ "matrix must have at least one row",
|
||||
"une matrice doit comporter au moins une ligne" },
|
||||
{ "matrix must have at least one column",
|
||||
"une matrice doit comporter au moins une colonne" },
|
||||
{ "some rows have length {0} while others have length {1}",
|
||||
"certaines ligne ont une longueur de {0} alors que d''autres ont une longueur de {1}" },
|
||||
{ "row index {0} out of allowed range [{1}, {2}]",
|
||||
"index de ligne {0} hors de la plage autoris\u00e9e [{1}, {2}]" },
|
||||
{ "column index {0} out of allowed range [{1}, {2}]",
|
||||
|
@ -277,13 +291,6 @@ public class MessagesResources_fr
|
|||
{ "first {0} columns are not initialized yet",
|
||||
"les {0} premi\u00e8res colonnes ne sont pas encore initialis\u00e9es" },
|
||||
|
||||
// org.apache.commons.math.linear.EigenDecompositionImpl
|
||||
// org.apache.commons.math.linear.LUDecompositionImpl
|
||||
// org.apache.commons.math.linear.QRDecompositionImpl
|
||||
// org.apache.commons.math.linear.SingularValueDecompositionImpl
|
||||
{ "no matrix have been decomposed yet",
|
||||
"aucune matrice n''a encore \u00e9t\u00e9 d\u00e9compos\u00e9e" },
|
||||
|
||||
// org.apache.commons.math.random.EmpiricalDistributionImpl
|
||||
{ "distribution not loaded",
|
||||
"aucune distribution n''a \u00e9t\u00e9 charg\u00e9e" },
|
||||
|
|
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
* 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.MathRuntimeException;
|
||||
import org.apache.commons.math.util.MathUtils;
|
||||
|
||||
/**
|
||||
* Basic implementation of RealMatrix methods regardless of the underlying storage.
|
||||
* <p>All the methods implemented here use {@link #getEntry(int, int)} to access
|
||||
* matrix elements. Derived class can provide faster implementations. </p>
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractRealMatrix implements RealMatrix, Serializable {
|
||||
|
||||
/** Serializable version identifier */
|
||||
private static final long serialVersionUID = -3665653040524315561L;
|
||||
|
||||
/** Cached LU solver.
|
||||
* @deprecated as of release 2.0, since all methods using this are deprecated
|
||||
*/
|
||||
private LUSolver lu;
|
||||
|
||||
/**
|
||||
* Creates a matrix with no data
|
||||
*/
|
||||
protected AbstractRealMatrix() {
|
||||
lu = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
protected AbstractRealMatrix(final int rowDimension, final int columnDimension)
|
||||
throws IllegalArgumentException {
|
||||
if (rowDimension <= 0 ) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("invalid row dimension {0}" +
|
||||
" (must be positive)",
|
||||
new Object[] { rowDimension });
|
||||
}
|
||||
if (columnDimension <= 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("invalid column dimension {0}" +
|
||||
" (must be positive)",
|
||||
new Object[] { columnDimension });
|
||||
}
|
||||
lu = null;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract RealMatrix createMatrix(final int rowDimension, final int columnDimension)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract RealMatrix copy();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix add(RealMatrix m) throws IllegalArgumentException {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" addition compatible",
|
||||
new Object[] {
|
||||
getRowDimension(),
|
||||
getColumnDimension(),
|
||||
m.getRowDimension(),
|
||||
m.getColumnDimension()
|
||||
});
|
||||
}
|
||||
|
||||
final RealMatrix out = createMatrix(rowCount, columnCount);
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
for (int col = 0; col < columnCount; ++col) {
|
||||
out.setEntry(row, col, getEntry(row, col) + m.getEntry(row, col));
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix subtract(final RealMatrix m) throws IllegalArgumentException {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" subtraction compatible",
|
||||
new Object[] {
|
||||
getRowDimension(),
|
||||
getColumnDimension(),
|
||||
m.getRowDimension(),
|
||||
m.getColumnDimension()
|
||||
});
|
||||
}
|
||||
|
||||
final RealMatrix out = createMatrix(rowCount, columnCount);
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
for (int col = 0; col < columnCount; ++col) {
|
||||
out.setEntry(row, col, getEntry(row, col) - m.getEntry(row, col));
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix scalarAdd(final double d) {
|
||||
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
final RealMatrix out = createMatrix(rowCount, columnCount);
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
for (int col = 0; col < columnCount; ++col) {
|
||||
out.setEntry(row, col, getEntry(row, col) + d);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix scalarMultiply(final double d) {
|
||||
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
final RealMatrix out = createMatrix(rowCount, columnCount);
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
for (int col = 0; col < columnCount; ++col) {
|
||||
out.setEntry(row, col, getEntry(row, col) * d);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix multiply(final RealMatrix m)
|
||||
throws IllegalArgumentException {
|
||||
if (getColumnDimension() != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" multiplication compatible",
|
||||
new Object[] {
|
||||
getRowDimension(),
|
||||
getColumnDimension(),
|
||||
m.getRowDimension(),
|
||||
m.getColumnDimension()
|
||||
});
|
||||
}
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = m.getColumnDimension();
|
||||
final int nSum = getColumnDimension();
|
||||
final RealMatrix out = createMatrix(nRows, nCols);
|
||||
for (int row = 0; row < nRows; ++row) {
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nSum; ++i) {
|
||||
sum += getEntry(row, i) * m.getEntry(i, col);
|
||||
}
|
||||
out.setEntry(row, col, sum);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix preMultiply(final RealMatrix m)
|
||||
throws IllegalArgumentException {
|
||||
return m.multiply(this);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract double[][] getData();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm() {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
double maxColSum = 0;
|
||||
for (int col = 0; col < columnCount; ++col) {
|
||||
double sum = 0;
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
sum += Math.abs(getEntry(row, col));
|
||||
}
|
||||
maxColSum = Math.max(maxColSum, sum);
|
||||
}
|
||||
return maxColSum;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getSubMatrix(final int startRow, final int endRow,
|
||||
final int startColumn, final int endColumn)
|
||||
throws MatrixIndexException {
|
||||
|
||||
checkRowIndex(startRow);
|
||||
checkRowIndex(endRow);
|
||||
if (startRow > endRow) {
|
||||
throw new MatrixIndexException("initial row {0} after final row {1}",
|
||||
new Object[] { startRow, endRow });
|
||||
}
|
||||
|
||||
checkColumnIndex(startColumn);
|
||||
checkColumnIndex(endColumn);
|
||||
if (startColumn > endColumn) {
|
||||
throw new MatrixIndexException("initial column {0} after final column {1}",
|
||||
new Object[] { startColumn, endColumn });
|
||||
}
|
||||
|
||||
final RealMatrix subMatrix =
|
||||
createMatrix(endRow - startRow + 1, endColumn - startColumn + 1);
|
||||
for (int i = startRow; i <= endRow; ++i) {
|
||||
for (int j = startColumn; j <= endColumn; ++j) {
|
||||
subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j));
|
||||
}
|
||||
}
|
||||
|
||||
return subMatrix;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
|
||||
throws MatrixIndexException {
|
||||
|
||||
if (selectedRows.length * selectedColumns.length == 0) {
|
||||
if (selectedRows.length == 0) {
|
||||
throw new MatrixIndexException("empty selected row index array", null);
|
||||
}
|
||||
throw new MatrixIndexException("empty selected column index array", null);
|
||||
}
|
||||
|
||||
final RealMatrix subMatrix =
|
||||
createMatrix(selectedRows.length, selectedColumns.length);
|
||||
try {
|
||||
for (int i = 0; i < selectedRows.length; i++) {
|
||||
for (int j = 0; j < selectedColumns.length; j++) {
|
||||
subMatrix.setEntry(i, j, getEntry(selectedRows[i], selectedColumns[j]));
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// we redo the loop with checks enabled
|
||||
// in order to generate an appropriate message
|
||||
for (final int row : selectedRows) {
|
||||
checkRowIndex(row);
|
||||
}
|
||||
for (final int column : selectedColumns) {
|
||||
checkColumnIndex(column);
|
||||
}
|
||||
}
|
||||
|
||||
return subMatrix;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
|
||||
throws MatrixIndexException {
|
||||
|
||||
final int nRows = subMatrix.length;
|
||||
if (nRows == 0) {
|
||||
throw new IllegalArgumentException("Matrix must have at least one row.");
|
||||
}
|
||||
|
||||
final int nCols = subMatrix[0].length;
|
||||
if (nCols == 0) {
|
||||
throw new IllegalArgumentException("Matrix must have at least one column.");
|
||||
}
|
||||
|
||||
for (int r = 1; r < nRows; ++r) {
|
||||
if (subMatrix[r].length != nCols) {
|
||||
throw new IllegalArgumentException("All input rows must have the same length.");
|
||||
}
|
||||
}
|
||||
|
||||
checkRowIndex(row);
|
||||
checkColumnIndex(column);
|
||||
checkRowIndex(nRows + row - 1);
|
||||
checkColumnIndex(nCols + column - 1);
|
||||
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
for (int j = 0; j < nCols; ++j) {
|
||||
setEntry(row + i, column + j, subMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
lu = null;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getRowMatrix(final int row)
|
||||
throws MatrixIndexException {
|
||||
|
||||
checkRowIndex(row);
|
||||
final int nCols = getColumnDimension();
|
||||
final RealMatrix out = createMatrix(1, nCols);
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
out.setEntry(0, i, getEntry(row, i));
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getColumnMatrix(final int column)
|
||||
throws MatrixIndexException {
|
||||
|
||||
checkColumnIndex(column);
|
||||
final int nRows = getRowDimension();
|
||||
final RealMatrix out = createMatrix(nRows, 1);
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
out.setEntry(i, 0, getEntry(i, column));
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector getColumnVector(final int column)
|
||||
throws MatrixIndexException {
|
||||
return new RealVectorImpl(getColumn(column), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector getRowVector(final int row)
|
||||
throws MatrixIndexException {
|
||||
return new RealVectorImpl(getRow(row), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] getRow(final int row)
|
||||
throws MatrixIndexException {
|
||||
|
||||
checkRowIndex(row);
|
||||
final int nCols = getColumnDimension();
|
||||
final double[] out = new double[nCols];
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
out[i] = getEntry(row, i);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] getColumn(final int column)
|
||||
throws MatrixIndexException {
|
||||
|
||||
checkColumnIndex(column);
|
||||
final int nRows = getRowDimension();
|
||||
final double[] out = new double[nRows];
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
out[i] = getEntry(i, column);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract double getEntry(int row, int column)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract void setEntry(int row, int column, double value)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix transpose() {
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
final RealMatrix out = createMatrix(nCols, nRows);
|
||||
for (int row = 0; row < nRows; ++row) {
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
out.setEntry(col, row, getEntry(row, col));
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public RealMatrix inverse()
|
||||
throws InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.getInverse();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public double getDeterminant()
|
||||
throws InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.getDeterminant();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isSquare() {
|
||||
return (getColumnDimension() == getRowDimension());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public boolean isSingular() {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return !lu.isNonSingular();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract int getRowDimension();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public abstract int getColumnDimension();
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getTrace()
|
||||
throws NonSquareMatrixException {
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (nRows != nCols) {
|
||||
throw new NonSquareMatrixException(nRows, nCols);
|
||||
}
|
||||
double trace = 0;
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
trace += getEntry(i, i);
|
||||
}
|
||||
return trace;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] operate(final double[] v)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (v.length != nCols) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("vector length mismatch:" +
|
||||
" got {0} but expected {1}",
|
||||
new Object[] {
|
||||
v.length, nCols
|
||||
});
|
||||
}
|
||||
|
||||
final double[] out = new double[nRows];
|
||||
for (int row = 0; row < nRows; ++row) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
sum += getEntry(row, i) * v[i];
|
||||
}
|
||||
out[row] = sum;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector operate(final RealVector v)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (v.getDimension() != nCols) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("vector length mismatch:" +
|
||||
" got {0} but expected {1}",
|
||||
new Object[] {
|
||||
v.getDimension(), nCols
|
||||
});
|
||||
}
|
||||
|
||||
final double[] out = new double[nRows];
|
||||
for (int row = 0; row < nRows; ++row) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nCols; ++i) {
|
||||
sum += getEntry(row, i) * v.getEntry(i);
|
||||
}
|
||||
out[row] = sum;
|
||||
}
|
||||
|
||||
return new RealVectorImpl(out, false);
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] preMultiply(final double[] v)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (v.length != nRows) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("vector length mismatch:" +
|
||||
" got {0} but expected {1}",
|
||||
new Object[] {
|
||||
v.length, nRows
|
||||
});
|
||||
}
|
||||
|
||||
final double[] out = new double[nCols];
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
sum += getEntry(i, col) * v[i];
|
||||
}
|
||||
out[col] = sum;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector preMultiply(final RealVector v)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (v.getDimension() != nRows) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("vector length mismatch:" +
|
||||
" got {0} but expected {1}",
|
||||
new Object[] {
|
||||
v.getDimension(), nRows
|
||||
});
|
||||
}
|
||||
|
||||
final double[] out = new double[nCols];
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
sum += getEntry(i, col) * v.getEntry(i);
|
||||
}
|
||||
out[col] = sum;
|
||||
}
|
||||
|
||||
return new RealVectorImpl(out);
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public double[] solve(final double[] b)
|
||||
throws IllegalArgumentException, InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.solve(b);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public RealMatrix solve(final RealMatrix b)
|
||||
throws IllegalArgumentException, InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.solve(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a new
|
||||
* <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
|
||||
* LU decomposition</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 algorithm</a>, with partial pivoting.</p>
|
||||
* <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.</p>
|
||||
*
|
||||
* @throws InvalidMatrixException if the matrix is non-square or singular.
|
||||
* @deprecated as of release 2.0, replaced by {@link LUDecomposition}
|
||||
*/
|
||||
@Deprecated
|
||||
public void luDecompose()
|
||||
throws InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string representation for this matrix.
|
||||
* @return a string representation for this matrix
|
||||
*/
|
||||
public String toString() {
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
final StringBuffer res = new StringBuffer();
|
||||
res.append("RealMatrixImpl{");
|
||||
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
if (i > 0) {
|
||||
res.append(",");
|
||||
}
|
||||
res.append("{");
|
||||
for (int j = 0; j < nCols; ++j) {
|
||||
if (j > 0) {
|
||||
res.append(",");
|
||||
}
|
||||
res.append(getEntry(i, j));
|
||||
}
|
||||
res.append("}");
|
||||
}
|
||||
|
||||
res.append("}");
|
||||
return res.toString();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff <code>object</code> is a
|
||||
* <code>RealMatrix</code> instance with the same dimensions as this
|
||||
* and all corresponding matrix entries are equal.
|
||||
*
|
||||
* @param object the object to test equality against.
|
||||
* @return true if object equals this
|
||||
*/
|
||||
public boolean equals(final Object object) {
|
||||
if (object == this ) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof RealMatrix == false) {
|
||||
return false;
|
||||
}
|
||||
RealMatrix m = (RealMatrix) object;
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
|
||||
return false;
|
||||
}
|
||||
for (int row = 0; row < nRows; ++row) {
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
if (getEntry(row, col) != m.getEntry(row, col)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hashcode for the matrix.
|
||||
*
|
||||
* @return hashcode for matrix
|
||||
*/
|
||||
public int hashCode() {
|
||||
int ret = 7;
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
ret = ret * 31 + nRows;
|
||||
ret = ret * 31 + nCols;
|
||||
for (int row = 0; row < nRows; ++row) {
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) *
|
||||
MathUtils.hash(getEntry(row, col));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a row index is valid.
|
||||
* @param row row index to check
|
||||
* @exception MatrixIndexException if index is not valid
|
||||
*/
|
||||
private void checkRowIndex(final int row) {
|
||||
if (row < 0 || row >= getRowDimension()) {
|
||||
throw new MatrixIndexException("row index {0} out of allowed range [{1}, {2}]",
|
||||
new Object[] { row, 0, getRowDimension() - 1});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column index is valid.
|
||||
* @param column column index to check
|
||||
* @exception MatrixIndexException if index is not valid
|
||||
*/
|
||||
private void checkColumnIndex(final int column)
|
||||
throws MatrixIndexException {
|
||||
if (column < 0 || column >= getColumnDimension()) {
|
||||
throw new MatrixIndexException("column index {0} out of allowed range [{1}, {2}]",
|
||||
new Object[] { column, 0, getColumnDimension() - 1});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,18 @@ package org.apache.commons.math.linear;
|
|||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public interface RealMatrix {
|
||||
|
||||
/**
|
||||
* Create a new RealMatrix of the same type as the instance 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
|
||||
* @since 2.0
|
||||
*/
|
||||
RealMatrix createMatrix(final int rowDimension, final int columnDimension);
|
||||
|
||||
/**
|
||||
* Returns a (deep) copy of this.
|
||||
*
|
||||
|
@ -128,7 +140,37 @@ public interface RealMatrix {
|
|||
*/
|
||||
RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
|
||||
throws MatrixIndexException;
|
||||
|
||||
|
||||
/**
|
||||
* Replace the submatrix starting at <code>row, column</code> using data in
|
||||
* the input <code>subMatrix</code> array. Indexes are 0-based.
|
||||
* <p>
|
||||
* Example:<br>
|
||||
* Starting with <pre>
|
||||
* 1 2 3 4
|
||||
* 5 6 7 8
|
||||
* 9 0 1 2
|
||||
* </pre>
|
||||
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
|
||||
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
|
||||
* 1 2 3 4
|
||||
* 5 3 4 8
|
||||
* 9 5 6 2
|
||||
* </pre></p>
|
||||
*
|
||||
* @param subMatrix array containing the submatrix replacement data
|
||||
* @param row row coordinate of the top, left element to be replaced
|
||||
* @param column column coordinate of the top, left element to be replaced
|
||||
* @throws MatrixIndexException if subMatrix does not fit into this
|
||||
* matrix from element in (row, column)
|
||||
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
|
||||
* (not all rows have the same length) or empty
|
||||
* @throws NullPointerException if <code>subMatrix</code> is null
|
||||
* @since 2.0
|
||||
*/
|
||||
void setSubMatrix(double[][] subMatrix, int row, int column)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Returns the entries in row number <code>row</code>
|
||||
* as a row matrix. Row indices start at 0.
|
||||
|
@ -187,11 +229,11 @@ public interface RealMatrix {
|
|||
* Column indices start at 0. A <code>MatrixIndexException</code> is thrown
|
||||
* unless <code>0 <= column < columnDimension.</code></p>
|
||||
*
|
||||
* @param col the column to be fetched
|
||||
* @param column the column to be fetched
|
||||
* @return array of entries in the column
|
||||
* @throws MatrixIndexException if the specified column index is not valid
|
||||
*/
|
||||
double[] getColumn(int col) throws MatrixIndexException;
|
||||
double[] getColumn(int column) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Returns the entry in the specified row and column.
|
||||
|
@ -210,6 +252,24 @@ public interface RealMatrix {
|
|||
*/
|
||||
double getEntry(int row, int column) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Set the entry in the specified row and column.
|
||||
* <p>
|
||||
* Row and column indices start at 0 and must satisfy
|
||||
* <ul>
|
||||
* <li><code>0 <= row < rowDimension</code></li>
|
||||
* <li><code> 0 <= column < columnDimension</code></li>
|
||||
* </ul>
|
||||
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
|
||||
*
|
||||
* @param row row location of entry to be set
|
||||
* @param column column location of entry to be set
|
||||
* @param value matrix entry to be set in row,column
|
||||
* @throws MatrixIndexException if the row or column index is not valid
|
||||
* @since 2.0
|
||||
*/
|
||||
void setEntry(int row, int column, double value) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Returns the transpose of this matrix.
|
||||
*
|
||||
|
@ -270,8 +330,9 @@ public interface RealMatrix {
|
|||
* trace</a> of the matrix (the sum of the elements on the main diagonal).
|
||||
*
|
||||
* @return trace
|
||||
* @throws NonSquareMatrixException if the matrix is not square
|
||||
*/
|
||||
double getTrace();
|
||||
double getTrace() throws NonSquareMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the result of multiplying this by the vector <code>v</code>.
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.apache.commons.math.linear;
|
|||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
import org.apache.commons.math.util.MathUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of RealMatrix using a double[][] array to store entries and
|
||||
|
@ -51,19 +49,14 @@ import org.apache.commons.math.util.MathUtils;
|
|||
*
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class RealMatrixImpl implements RealMatrix, Serializable {
|
||||
public class RealMatrixImpl extends AbstractRealMatrix implements Serializable {
|
||||
|
||||
/** Serializable version identifier */
|
||||
private static final long serialVersionUID = -391443069570048115L;
|
||||
private static final long serialVersionUID = -1067294169172445528L;
|
||||
|
||||
/** Entries of the matrix */
|
||||
protected double data[][];
|
||||
|
||||
/** Cached LU solver.
|
||||
* @deprecated as of release 2.0, since all methods using this are deprecated
|
||||
*/
|
||||
private LUSolver lu;
|
||||
|
||||
/**
|
||||
* Creates a matrix with no data
|
||||
*/
|
||||
|
@ -78,13 +71,10 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @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");
|
||||
}
|
||||
public RealMatrixImpl(final int rowDimension, final int columnDimension)
|
||||
throws IllegalArgumentException {
|
||||
super(rowDimension, columnDimension);
|
||||
data = new double[rowDimension][columnDimension];
|
||||
lu = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,9 +90,9 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @throws NullPointerException if <code>d</code> is null
|
||||
* @see #RealMatrixImpl(double[][], boolean)
|
||||
*/
|
||||
public RealMatrixImpl(double[][] d) {
|
||||
public RealMatrixImpl(final double[][] d)
|
||||
throws IllegalArgumentException, NullPointerException {
|
||||
copyIn(d);
|
||||
lu = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,7 +110,8 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @throws NullPointerException if <code>d</code> is null
|
||||
* @see #RealMatrixImpl(double[][])
|
||||
*/
|
||||
public RealMatrixImpl(double[][] d, boolean copyArray) {
|
||||
public RealMatrixImpl(final double[][] d, final boolean copyArray)
|
||||
throws IllegalArgumentException, NullPointerException {
|
||||
if (copyArray) {
|
||||
copyIn(d);
|
||||
} else {
|
||||
|
@ -129,20 +120,23 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
final int nRows = d.length;
|
||||
if (nRows == 0) {
|
||||
throw new IllegalArgumentException("Matrix must have at least one row.");
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row",
|
||||
null);
|
||||
}
|
||||
final int nCols = d[0].length;
|
||||
if (nCols == 0) {
|
||||
throw new IllegalArgumentException("Matrix must have at least one column.");
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column",
|
||||
null);
|
||||
}
|
||||
for (int r = 1; r < nRows; r++) {
|
||||
if (d[r].length != nCols) {
|
||||
throw new IllegalArgumentException("All input rows must have the same length.");
|
||||
throw MathRuntimeException.createIllegalArgumentException("some rows have length {0} while" +
|
||||
" others have length {1}",
|
||||
new Object[] { nCols, d[r].length });
|
||||
}
|
||||
}
|
||||
data = d;
|
||||
}
|
||||
lu = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,7 +147,7 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
*
|
||||
* @param v column vector holding data for new matrix
|
||||
*/
|
||||
public RealMatrixImpl(double[] v) {
|
||||
public RealMatrixImpl(final double[] v) {
|
||||
final int nRows = v.length;
|
||||
data = new double[nRows][1];
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
|
@ -161,35 +155,24 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix createMatrix(final int rowDimension, final int columnDimension)
|
||||
throws IllegalArgumentException {
|
||||
return new RealMatrixImpl(rowDimension, columnDimension);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix copy() {
|
||||
return new RealMatrixImpl(copyOut(), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix add(RealMatrix m) throws IllegalArgumentException {
|
||||
public RealMatrix add(final RealMatrix m)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return add((RealMatrixImpl) m);
|
||||
} catch (ClassCastException cce) {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" addition compatible",
|
||||
new Object[] {
|
||||
getRowDimension(), getColumnDimension(),
|
||||
m.getRowDimension(), m.getColumnDimension()
|
||||
});
|
||||
}
|
||||
final double[][] outData = new double[rowCount][columnCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
final double[] outDataRow = outData[row];
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
outDataRow[col] = dataRow[col] + m.getEntry(row, col);
|
||||
}
|
||||
}
|
||||
return new RealMatrixImpl(outData, false);
|
||||
return super.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +183,8 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @return this + m
|
||||
* @throws IllegalArgumentException if m is not the same size as this
|
||||
*/
|
||||
public RealMatrixImpl add(RealMatrixImpl m) throws IllegalArgumentException {
|
||||
public RealMatrixImpl add(final RealMatrixImpl m)
|
||||
throws IllegalArgumentException {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
|
||||
|
@ -224,29 +208,12 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix subtract(RealMatrix m) throws IllegalArgumentException {
|
||||
public RealMatrix subtract(final RealMatrix m)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return subtract((RealMatrixImpl) m);
|
||||
} catch (ClassCastException cce) {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" subtraction compatible",
|
||||
new Object[] {
|
||||
getRowDimension(), getColumnDimension(),
|
||||
m.getRowDimension(), m.getColumnDimension()
|
||||
});
|
||||
}
|
||||
final double[][] outData = new double[rowCount][columnCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
final double[] outDataRow = outData[row];
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
outDataRow[col] = dataRow[col] - m.getEntry(row, col);
|
||||
}
|
||||
}
|
||||
return new RealMatrixImpl(outData, false);
|
||||
return super.subtract(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +224,8 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @return this + m
|
||||
* @throws IllegalArgumentException if m is not the same size as this
|
||||
*/
|
||||
public RealMatrixImpl subtract(RealMatrixImpl m) throws IllegalArgumentException {
|
||||
public RealMatrixImpl subtract(final RealMatrixImpl m)
|
||||
throws IllegalArgumentException {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
|
||||
|
@ -281,64 +249,12 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix scalarAdd(double d) {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
final double[][] outData = new double[rowCount][columnCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
final double[] outDataRow = outData[row];
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
outDataRow[col] = dataRow[col] + d;
|
||||
}
|
||||
}
|
||||
return new RealMatrixImpl(outData, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix scalarMultiply(double d) {
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
final double[][] outData = new double[rowCount][columnCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
final double[] outDataRow = outData[row];
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
outDataRow[col] = dataRow[col] * d;
|
||||
}
|
||||
}
|
||||
return new RealMatrixImpl(outData, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix multiply(RealMatrix m) throws IllegalArgumentException {
|
||||
public RealMatrix multiply(final RealMatrix m)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return multiply((RealMatrixImpl) m);
|
||||
} catch (ClassCastException cce) {
|
||||
if (this.getColumnDimension() != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" multiplication compatible",
|
||||
new Object[] {
|
||||
getRowDimension(), getColumnDimension(),
|
||||
m.getRowDimension(), m.getColumnDimension()
|
||||
});
|
||||
}
|
||||
final int nRows = this.getRowDimension();
|
||||
final int nCols = m.getColumnDimension();
|
||||
final int nSum = this.getColumnDimension();
|
||||
final double[][] outData = new double[nRows][nCols];
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
final double[] outDataRow = outData[row];
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nSum; i++) {
|
||||
sum += dataRow[i] * m.getEntry(i, col);
|
||||
}
|
||||
outDataRow[col] = sum;
|
||||
}
|
||||
}
|
||||
return new RealMatrixImpl(outData, false);
|
||||
return super.multiply(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,7 +265,8 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @throws IllegalArgumentException
|
||||
* if columnDimension(this) != rowDimension(m)
|
||||
*/
|
||||
public RealMatrixImpl multiply(RealMatrixImpl m) throws IllegalArgumentException {
|
||||
public RealMatrixImpl multiply(final RealMatrixImpl m)
|
||||
throws IllegalArgumentException {
|
||||
if (this.getColumnDimension() != m.getRowDimension()) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("{0}x{1} and {2}x{3} matrices are not" +
|
||||
" multiplication compatible",
|
||||
|
@ -376,11 +293,6 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
return new RealMatrixImpl(outData, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException {
|
||||
return m.multiply(this);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[][] getData() {
|
||||
return copyOut();
|
||||
|
@ -398,127 +310,8 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
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;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getSubMatrix(int startRow, int endRow,
|
||||
int startColumn, int endColumn)
|
||||
throws MatrixIndexException {
|
||||
|
||||
checkRowIndex(startRow);
|
||||
checkRowIndex(endRow);
|
||||
if (startRow > endRow) {
|
||||
throw new MatrixIndexException("initial row {0} after final row {1}",
|
||||
new Object[] { startRow, endRow });
|
||||
}
|
||||
|
||||
checkColumnIndex(startColumn);
|
||||
checkColumnIndex(endColumn);
|
||||
if (startColumn > endColumn) {
|
||||
throw new MatrixIndexException("initial column {0} after final column {1}",
|
||||
new Object[] { startColumn, endColumn });
|
||||
}
|
||||
|
||||
final double[][] subMatrixData =
|
||||
new double[endRow - startRow + 1][endColumn - startColumn + 1];
|
||||
for (int i = startRow; i <= endRow; i++) {
|
||||
System.arraycopy(data[i], startColumn,
|
||||
subMatrixData[i - startRow], 0,
|
||||
endColumn - startColumn + 1);
|
||||
}
|
||||
return new RealMatrixImpl(subMatrixData, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
|
||||
throws MatrixIndexException {
|
||||
|
||||
if (selectedRows.length * selectedColumns.length == 0) {
|
||||
if (selectedRows.length == 0) {
|
||||
throw new MatrixIndexException("empty selected row index array", null);
|
||||
}
|
||||
throw new MatrixIndexException("empty selected column index array", null);
|
||||
}
|
||||
|
||||
final double[][] subMatrixData =
|
||||
new double[selectedRows.length][selectedColumns.length];
|
||||
try {
|
||||
for (int i = 0; i < selectedRows.length; i++) {
|
||||
final double[] subI = subMatrixData[i];
|
||||
final double[] dataSelectedI = data[selectedRows[i]];
|
||||
for (int j = 0; j < selectedColumns.length; j++) {
|
||||
subI[j] = dataSelectedI[selectedColumns[j]];
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// we redo the loop with checks enabled
|
||||
// in order to generate an appropriate message
|
||||
for (final int row : selectedRows) {
|
||||
checkRowIndex(row);
|
||||
}
|
||||
for (final int column : selectedColumns) {
|
||||
checkColumnIndex(column);
|
||||
}
|
||||
}
|
||||
return new RealMatrixImpl(subMatrixData, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the submatrix starting at <code>row, column</code> using data in
|
||||
* the input <code>subMatrix</code> array. Indexes are 0-based.
|
||||
* <p>
|
||||
* Example:<br>
|
||||
* Starting with <pre>
|
||||
* 1 2 3 4
|
||||
* 5 6 7 8
|
||||
* 9 0 1 2
|
||||
* </pre>
|
||||
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
|
||||
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
|
||||
* 1 2 3 4
|
||||
* 5 3 4 8
|
||||
* 9 5 6 2
|
||||
* </pre></p>
|
||||
*
|
||||
* @param subMatrix array containing the submatrix replacement data
|
||||
* @param row row coordinate of the top, left element to be replaced
|
||||
* @param column column coordinate of the top, left element to be replaced
|
||||
* @throws MatrixIndexException if subMatrix does not fit into this
|
||||
* matrix from element in (row, column)
|
||||
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
|
||||
* (not all rows have the same length) or empty
|
||||
* @throws NullPointerException if <code>subMatrix</code> is null
|
||||
* @since 1.1
|
||||
*/
|
||||
public void setSubMatrix(double[][] subMatrix, int row, int column)
|
||||
throws MatrixIndexException {
|
||||
|
||||
final int nRows = subMatrix.length;
|
||||
if (nRows == 0) {
|
||||
throw new IllegalArgumentException("Matrix must have at least one row.");
|
||||
}
|
||||
|
||||
final int nCols = subMatrix[0].length;
|
||||
if (nCols == 0) {
|
||||
throw new IllegalArgumentException("Matrix must have at least one column.");
|
||||
}
|
||||
|
||||
for (int r = 1; r < nRows; r++) {
|
||||
if (subMatrix[r].length != nCols) {
|
||||
throw new IllegalArgumentException("All input rows must have the same length.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
|
||||
throws MatrixIndexException {
|
||||
if (data == null) {
|
||||
if (row > 0) {
|
||||
throw MathRuntimeException.createIllegalStateException("first {0} rows are not initialized yet",
|
||||
|
@ -528,75 +321,18 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
throw MathRuntimeException.createIllegalStateException("first {0} columns are not initialized yet",
|
||||
new Object[] { column });
|
||||
}
|
||||
data = new double[nRows][nCols];
|
||||
System.arraycopy(subMatrix, 0, data, 0, subMatrix.length);
|
||||
data = new double[subMatrix.length][subMatrix[0].length];
|
||||
for (int i = 0; i < data.length; ++i) {
|
||||
System.arraycopy(subMatrix[i], 0, data[i], 0, subMatrix[i].length);
|
||||
}
|
||||
} else {
|
||||
checkRowIndex(row);
|
||||
checkColumnIndex(column);
|
||||
checkRowIndex(nRows + row - 1);
|
||||
checkColumnIndex(nCols + column - 1);
|
||||
super.setSubMatrix(subMatrix, row, column);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nRows; i++) {
|
||||
System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols);
|
||||
}
|
||||
|
||||
lu = null;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getRowMatrix(int row) throws MatrixIndexException {
|
||||
checkRowIndex(row);
|
||||
final int ncols = this.getColumnDimension();
|
||||
final double[][] out = new double[1][ncols];
|
||||
System.arraycopy(data[row], 0, out[0], 0, ncols);
|
||||
return new RealMatrixImpl(out, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix getColumnMatrix(int column) throws MatrixIndexException {
|
||||
checkColumnIndex(column);
|
||||
final int nRows = this.getRowDimension();
|
||||
final double[][] out = new double[nRows][1];
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
out[row][0] = data[row][column];
|
||||
}
|
||||
return new RealMatrixImpl(out, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector getColumnVector(int column) throws MatrixIndexException {
|
||||
return new RealVectorImpl(getColumn(column), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector getRowVector(int row) throws MatrixIndexException {
|
||||
return new RealVectorImpl(getRow(row), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] getRow(int row) throws MatrixIndexException {
|
||||
checkRowIndex(row);
|
||||
final int ncols = this.getColumnDimension();
|
||||
final double[] out = new double[ncols];
|
||||
System.arraycopy(data[row], 0, out, 0, ncols);
|
||||
return out;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] getColumn(int col) throws MatrixIndexException {
|
||||
checkColumnIndex(col);
|
||||
final int nRows = this.getRowDimension();
|
||||
final double[] out = new double[nRows];
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
out[row] = data[row][col];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getEntry(int row, int column)
|
||||
public double getEntry(final int row, final int column)
|
||||
throws MatrixIndexException {
|
||||
try {
|
||||
return data[row][column];
|
||||
|
@ -610,75 +346,32 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealMatrix transpose() {
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
final double[][] outData = new double[nCols][nRows];
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
outData[col][row] = dataRow[col];
|
||||
}
|
||||
public void setEntry(final int row, final int column, final double value)
|
||||
throws MatrixIndexException {
|
||||
try {
|
||||
data[row][column] = value;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new MatrixIndexException("no entry at indices ({0}, {1}) in a {2}x{3} matrix",
|
||||
new Object[] {
|
||||
row, column,
|
||||
getRowDimension(), getColumnDimension()
|
||||
});
|
||||
}
|
||||
return new RealMatrixImpl(outData, false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public RealMatrix inverse() throws InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.getInverse();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public double getDeterminant() throws InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.getDeterminant();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isSquare() {
|
||||
return (this.getColumnDimension() == this.getRowDimension());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public boolean isSingular() {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return !lu.isNonSingular();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getRowDimension() {
|
||||
return data.length;
|
||||
return (data == null) ? 0 : data.length;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getColumnDimension() {
|
||||
return data[0].length;
|
||||
return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
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;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] operate(double[] v) throws IllegalArgumentException {
|
||||
public double[] operate(final double[] v)
|
||||
throws IllegalArgumentException {
|
||||
final int nRows = this.getRowDimension();
|
||||
final int nCols = this.getColumnDimension();
|
||||
if (v.length != nCols) {
|
||||
|
@ -697,25 +390,12 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector operate(RealVector v) throws IllegalArgumentException {
|
||||
public RealVector operate(final RealVector v)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return operate((RealVectorImpl) v);
|
||||
} catch (ClassCastException cce) {
|
||||
final int nRows = this.getRowDimension();
|
||||
final int nCols = this.getColumnDimension();
|
||||
if (v.getDimension() != nCols) {
|
||||
throw new IllegalArgumentException("vector has wrong length");
|
||||
}
|
||||
final double[] out = new double[nRows];
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
double sum = 0;
|
||||
for (int i = 0; i < nCols; i++) {
|
||||
sum += dataRow[i] * v.getEntry(i);
|
||||
}
|
||||
out[row] = sum;
|
||||
}
|
||||
return new RealVectorImpl(out, false);
|
||||
return super.operate(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,186 +406,11 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* @return this*v
|
||||
* @throws IllegalArgumentException if columnDimension != v.size()
|
||||
*/
|
||||
public RealVectorImpl operate(RealVectorImpl v) throws IllegalArgumentException {
|
||||
public RealVectorImpl operate(final RealVectorImpl v)
|
||||
throws IllegalArgumentException {
|
||||
return new RealVectorImpl(operate(v.getDataRef()), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double[] preMultiply(double[] v) throws IllegalArgumentException {
|
||||
final int nRows = this.getRowDimension();
|
||||
if (v.length != nRows) {
|
||||
throw new IllegalArgumentException("vector has wrong length");
|
||||
}
|
||||
final int nCols = this.getColumnDimension();
|
||||
final 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;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public RealVector preMultiply(RealVector v) throws IllegalArgumentException {
|
||||
try {
|
||||
return preMultiply((RealVectorImpl) v);
|
||||
} catch (ClassCastException cce) {
|
||||
final int nRows = this.getRowDimension();
|
||||
if (v.getDimension() != nRows) {
|
||||
throw new IllegalArgumentException("vector has wrong length");
|
||||
}
|
||||
final int nCols = this.getColumnDimension();
|
||||
final 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.getEntry(i);
|
||||
}
|
||||
out[col] = sum;
|
||||
}
|
||||
return new RealVectorImpl(out, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
|
||||
*
|
||||
* @param v the row vector to premultiply by
|
||||
* @return v*this
|
||||
* @throws IllegalArgumentException if rowDimension != v.size()
|
||||
*/
|
||||
RealVectorImpl preMultiply(RealVectorImpl v) throws IllegalArgumentException {
|
||||
return new RealVectorImpl(preMultiply(v.getDataRef()), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.solve(b);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
return lu.solve(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a new
|
||||
* <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
|
||||
* LU decomposition</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 algorithm</a>, with partial pivoting.</p>
|
||||
* <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.</p>
|
||||
*
|
||||
* @throws InvalidMatrixException if the matrix is non-square or singular.
|
||||
* @deprecated as of release 2.0, replaced by {@link LUDecomposition}
|
||||
*/
|
||||
@Deprecated
|
||||
public void luDecompose() throws InvalidMatrixException {
|
||||
if (lu == null) {
|
||||
lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string representation for this matrix.
|
||||
* @return a string representation for this matrix
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer res = new StringBuffer();
|
||||
res.append("RealMatrixImpl{");
|
||||
if (data != null) {
|
||||
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]);
|
||||
}
|
||||
res.append("}");
|
||||
}
|
||||
}
|
||||
res.append("}");
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff <code>object</code> is a
|
||||
* <code>RealMatrixImpl</code> instance with the same dimensions as this
|
||||
* and all corresponding matrix entries are equal.
|
||||
*
|
||||
* @param object the object to test equality against.
|
||||
* @return true if object equals this
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
if (object == this ) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof RealMatrixImpl == false) {
|
||||
return false;
|
||||
}
|
||||
RealMatrix m = (RealMatrix) object;
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
|
||||
return false;
|
||||
}
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
if (dataRow[col] != m.getEntry(row, col)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hashcode for the matrix.
|
||||
*
|
||||
* @return hashcode for matrix
|
||||
*/
|
||||
public int hashCode() {
|
||||
int ret = 7;
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
ret = ret * 31 + nRows;
|
||||
ret = ret * 31 + nCols;
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final double[] dataRow = data[row];
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) *
|
||||
MathUtils.hash(dataRow[col]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------ Private methods
|
||||
|
||||
/**
|
||||
* Returns a fresh copy of the underlying data array.
|
||||
*
|
||||
|
@ -931,33 +436,8 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
|
|||
* rectangular
|
||||
* @throws NullPointerException if input array is null
|
||||
*/
|
||||
private void copyIn(double[][] in) {
|
||||
private void copyIn(final double[][] in) {
|
||||
setSubMatrix(in, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a row index is valid.
|
||||
* @param row row index to check
|
||||
* @exception MatrixIndexException if index is not valid
|
||||
*/
|
||||
private void checkRowIndex(final int row) {
|
||||
if (row < 0 || row >= getRowDimension()) {
|
||||
throw new MatrixIndexException("row index {0} out of allowed range [{1}, {2}]",
|
||||
new Object[] { row, 0, getRowDimension() - 1});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column index is valid.
|
||||
* @param column column index to check
|
||||
* @exception MatrixIndexException if index is not valid
|
||||
*/
|
||||
private void checkColumnIndex(final int column)
|
||||
throws MatrixIndexException {
|
||||
if (column < 0 || column >= getColumnDimension()) {
|
||||
throw new MatrixIndexException("column index {0} out of allowed range [{1}, {2}]",
|
||||
new Object[] { column, 0, getColumnDimension() - 1});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</properties>
|
||||
<body>
|
||||
<release version="2.0" date="TBD" description="TBD">
|
||||
<action dev="luc" type="add" issue="MATH-231" >
|
||||
Added an abstract matrix implementation simplifying extension by users.
|
||||
</action>
|
||||
<action dev="luc" type="add" issue="MATH-178" due-to="Paul Cowan">
|
||||
Added support for the Zipf distribution.
|
||||
</action>
|
||||
|
|
|
@ -217,8 +217,8 @@ public final class RealMatrixImplTest extends TestCase {
|
|||
m = new RealMatrixImpl(testData2);
|
||||
try {
|
||||
m.getTrace();
|
||||
fail("Expecting illegalArgumentException");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
fail("Expecting NonSquareMatrixException");
|
||||
} catch (NonSquareMatrixException ex) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue