pulled some solve-related methods higher in the classes hierarchy

(isNonSinglular(), getInverse())

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_0@699844 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2008-09-28 15:51:47 +00:00
parent 44e04f2a0a
commit d3f7151590
6 changed files with 52 additions and 34 deletions

View File

@ -45,7 +45,7 @@ public interface DecompositionSolver extends Serializable {
* for {@link LUDecomposition})
*/
void decompose(RealMatrix matrix)
throws InvalidMatrixException;
throws InvalidMatrixException;
/** Solve the linear equation A × X = B.
* <p>The A matrix is implicit here. It <strong>must</strong> have
@ -58,7 +58,7 @@ public interface DecompositionSolver extends Serializable {
* @exception InvalidMatrixException if decomposed matrix is singular
*/
double[] solve(double[] b)
throws IllegalStateException, IllegalArgumentException, InvalidMatrixException;
throws IllegalStateException, IllegalArgumentException, InvalidMatrixException;
/** Solve the linear equation A &times; X = B.
* <p>The A matrix is implicit here. It <strong>must</strong> have
@ -71,7 +71,7 @@ public interface DecompositionSolver extends Serializable {
* @exception InvalidMatrixException if decomposed matrix is singular
*/
RealVector solve(RealVector b)
throws IllegalStateException, IllegalArgumentException, InvalidMatrixException;
throws IllegalStateException, IllegalArgumentException, InvalidMatrixException;
/** Solve the linear equation A &times; X = B.
* <p>The A matrix is implicit here. It <strong>must</strong> have
@ -84,6 +84,23 @@ public interface DecompositionSolver extends Serializable {
* @exception InvalidMatrixException if decomposed matrix is singular
*/
RealMatrix solve(RealMatrix b)
throws IllegalStateException, IllegalArgumentException, InvalidMatrixException;
throws IllegalStateException, IllegalArgumentException, InvalidMatrixException;
/**
* Check if the decomposed matrix is non-singular.
* @return true if the decomposed matrix is non-singular
* @exception IllegalStateException if {@link
* DecompositionSolver#decompose(RealMatrix) decompose} has not been called
*/
boolean isNonSingular() throws IllegalStateException;
/** Get the inverse of the decomposed matrix.
* @return inverse matrix
* @exception IllegalStateException if {@link #decompose(RealMatrix) decompose}
* has not been called
* @throws InvalidMatrixException if decomposed matrix is singular
*/
RealMatrix getInverse()
throws IllegalStateException, InvalidMatrixException;
}

View File

@ -95,15 +95,6 @@ public interface LUDecomposition extends DecompositionSolver {
*/
int[] getPivot() throws IllegalStateException;
/**
* Check if the decomposed matrix is non-singular.
* @return true if the decomposed matrix is non-singular
* @exception IllegalStateException if {@link
* DecompositionSolver#decompose(RealMatrix) decompose} has not been called
* @see #getDeterminant()
*/
boolean isNonSingular() throws IllegalStateException;
/**
* Return the determinant of the matrix
* @return determinant of the matrix

View File

@ -32,7 +32,7 @@ package org.apache.commons.math.linear;
public class LUDecompositionImpl implements LUDecomposition {
/** Serializable version identifier. */
private static final long serialVersionUID = -9052751605297201067L;
private static final long serialVersionUID = 3446121671437672843L;
/** Entries of LU decomposition. */
private double lu[][];
@ -108,7 +108,7 @@ public class LUDecompositionImpl implements LUDecomposition {
public void decompose(RealMatrix matrix, double singularityThreshold)
throws InvalidMatrixException {
if (!matrix.isSquare()) {
throw new InvalidMatrixException("LU decomposition requires that the matrix be square.");
throw new InvalidMatrixException("LU decomposition requires that the matrix be square");
}
final int m = matrix.getColumnDimension();
lu = matrix.getData();
@ -413,6 +413,13 @@ public class LUDecompositionImpl implements LUDecomposition {
}
/** {@inheritDoc} */
public RealMatrix getInverse()
throws IllegalStateException, InvalidMatrixException {
checkDecomposed();
return solve(MatrixUtils.createRealIdentityMatrix(pivot.length));
}
/**
* Check if either {@link #decompose(RealMatrix)} or {@link
* #decompose(RealMatrix, double) has been called.

View File

@ -24,8 +24,12 @@ package org.apache.commons.math.linear;
* <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the
* following changes:</p>
* <ul>
* <li>several signatures have been added for the <code>solve</code> methods (in the superinterface),</code>
* <li>a <code>decompose</code> method has been added (in the superinterface),</code>
* <li>several signatures have been added for the <code>solve</code> methods
* (in the superinterface),</li>
* <li>a {@link DecompositionSolver#decompose(RealMatrix) decompose} method
* has been added (in the superinterface),</li>
* <li>the <code>isFullRank</code> method has been replaced by the {@link
* DecompositionSolver#isNonSingular() isNonSingular} method in the superinterface.</li>
* </ul>
*
* @see <a href="http://mathworld.wolfram.com/QRDecomposition.html">MathWorld</a>
@ -64,12 +68,4 @@ public interface QRDecomposition extends DecompositionSolver {
*/
RealMatrix getH() throws IllegalStateException;
/**
* Check if the decomposed matrix is full rank.
* @return true if the decomposed matrix is full rank
* @exception IllegalStateException if {@link
* DecompositionSolver#decompose(RealMatrix) decompose} has not been called
*/
boolean isFullRank() throws IllegalStateException;
}

View File

@ -36,7 +36,7 @@ package org.apache.commons.math.linear;
public class QRDecompositionImpl implements QRDecomposition {
/** Serializable version identifier. */
private static final long serialVersionUID = 7560093145655650408L;
private static final long serialVersionUID = -5179446891802932307L;
/**
* A packed TRANSPOSED representation of the QR decomposition.
@ -267,7 +267,7 @@ public class QRDecompositionImpl implements QRDecomposition {
}
/** {@inheritDoc} */
public boolean isFullRank()
public boolean isNonSingular()
throws IllegalStateException {
checkDecomposed();
@ -292,7 +292,7 @@ public class QRDecompositionImpl implements QRDecomposition {
if (b.length != m) {
throw new IllegalArgumentException("Incorrect row dimension");
}
if (!isFullRank()) {
if (!isNonSingular()) {
throw new InvalidMatrixException("Matrix is rank-deficient");
}
@ -366,7 +366,7 @@ public class QRDecompositionImpl implements QRDecomposition {
if (b.getRowDimension() != m) {
throw new IllegalArgumentException("Incorrect row dimension");
}
if (!isFullRank()) {
if (!isNonSingular()) {
throw new InvalidMatrixException("Matrix is rank-deficient");
}
@ -414,6 +414,13 @@ public class QRDecompositionImpl implements QRDecomposition {
}
/** {@inheritDoc} */
public RealMatrix getInverse()
throws IllegalStateException, InvalidMatrixException {
checkDecomposed();
return solve(MatrixUtils.createRealIdentityMatrix(rDiag.length));
}
/**
* Check if {@link #decompose(RealMatrix)} has been called.
* @exception IllegalStateException if {@link #decompose(RealMatrix) decompose}

View File

@ -200,16 +200,16 @@ public class QRDecompositionImplTest extends TestCase {
public void testRank() {
QRDecomposition qr =
new QRDecompositionImpl(new RealMatrixImpl(testData3x3NonSingular, false));
assertTrue(qr.isFullRank());
assertTrue(qr.isNonSingular());
qr = new QRDecompositionImpl(new RealMatrixImpl(testData3x3Singular, false));
assertFalse(qr.isFullRank());
assertFalse(qr.isNonSingular());
qr = new QRDecompositionImpl(new RealMatrixImpl(testData3x4, false));
assertFalse(qr.isFullRank());
assertFalse(qr.isNonSingular());
qr = new QRDecompositionImpl(new RealMatrixImpl(testData4x3, false));
assertTrue(qr.isFullRank());
assertTrue(qr.isNonSingular());
}
@ -352,7 +352,7 @@ public class QRDecompositionImplTest extends TestCase {
/** test no call to decompose */
public void testNoDecompose() {
try {
new QRDecompositionImpl().isFullRank();
new QRDecompositionImpl().isNonSingular();
fail("an exception should have been caught");
} catch (IllegalStateException ise) {
// expected behavior