You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2008/12/05 15:05:51 UTC
svn commit: r723736 [1/2] - in /commons/proper/math/trunk/src:
java/org/apache/commons/math/estimation/ java/org/apache/commons/math/linear/
java/org/apache/commons/math/stat/regression/ site/xdoc/userguide/
test/org/apache/commons/math/linear/
Author: luc
Date: Fri Dec 5 06:05:50 2008
New Revision: 723736
URL: http://svn.apache.org/viewvc?rev=723736&view=rev
Log:
improved matrix decomposition API.
solving a linear system AX = B is now done by a call like:
RealVector x = new XyzSolver(new XyzDecomposition(a)).solve(b);
Added:
commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java (with props)
commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java (with props)
commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java (with props)
commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueSolver.java (with props)
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/EigenSolverTest.java (with props)
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/LUSolverTest.java (with props)
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/QRSolverTest.java (with props)
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueSolverTest.java (with props)
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/AbstractEstimator.java
commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java
commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DecompositionSolver.java
commons/proper/math/trunk/src/java/org/apache/commons/math/linear/RealMatrixImpl.java
commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/EigenDecompositionImplTest.java
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/LUDecompositionImplTest.java
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/QRDecompositionImplTest.java
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java
commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/AbstractEstimator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/AbstractEstimator.java?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/AbstractEstimator.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/AbstractEstimator.java Fri Dec 5 06:05:50 2008
@@ -19,8 +19,9 @@
import java.util.Arrays;
-import org.apache.commons.math.linear.DecompositionSolver;
import org.apache.commons.math.linear.InvalidMatrixException;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.LUSolver;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealMatrixImpl;
@@ -181,8 +182,8 @@
try {
// compute the covariances matrix
- DecompositionSolver solver = new DecompositionSolver(new RealMatrixImpl(jTj, false));
- RealMatrix inverse = solver.getInverse(solver.luDecompose());
+ RealMatrix inverse =
+ new LUSolver(new LUDecompositionImpl(new RealMatrixImpl(jTj, false))).getInverse();
return ((RealMatrixImpl) inverse).getDataRef();
} catch (InvalidMatrixException ime) {
throw new EstimationException("unable to compute covariances: singular problem",
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java Fri Dec 5 06:05:50 2008
@@ -19,8 +19,9 @@
import java.io.Serializable;
-import org.apache.commons.math.linear.DecompositionSolver;
import org.apache.commons.math.linear.InvalidMatrixException;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.LUSolver;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealMatrixImpl;
import org.apache.commons.math.linear.RealVector;
@@ -153,8 +154,7 @@
try {
// solve the linearized least squares problem
- DecompositionSolver solver = new DecompositionSolver(a);
- RealVector dX = solver.solve(b, solver.luDecompose());
+ RealVector dX = new LUSolver(new LUDecompositionImpl(a)).solve(b);
// update the estimated parameters
for (int i = 0; i < parameters.length; ++i) {
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DecompositionSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DecompositionSolver.java?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DecompositionSolver.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DecompositionSolver.java Fri Dec 5 06:05:50 2008
@@ -19,15 +19,11 @@
import java.io.Serializable;
-import org.apache.commons.math.util.MathUtils;
/**
- * Class handling decomposition algorithms that can solve A × X = B.
- * <p>This class is the entry point for decomposition algorithms like
- * {@link QRDecomposition}, {@link LUDecomposition}, {@link
- * SingularValueDecomposition} or {@link EigenDecomposition}. All these
- * algorithms decompose an A matrix has a product of several specific matrices
- * from which they can solve A × X = B in least squares sense: they find X
+ * Interface handling decomposition algorithms that can solve A × X = B.
+ * <p>Decomposition algorithms decompose an A matrix has a product of several specific
+ * matrices from which they can solve A × X = B in least squares sense: they find X
* such that ||A × X - B|| is minimal.</p>
* <p>Some solvers like {@link LUDecomposition} can only find the solution for
* square matrices and when the solution is an exact linear solution, i.e. when
@@ -38,708 +34,53 @@
* @version $Revision$ $Date$
* @since 2.0
*/
-public class DecompositionSolver implements Serializable {
+public interface DecompositionSolver extends Serializable {
- /** Serializable version identifier. */
- private static final long serialVersionUID = 182675257956465253L;
-
- /** Matrix to decompose. */
- private final RealMatrix matrix;
-
- /**
- * Build a decomposition solver for a matrix.
- * @param matrix matrix to decompose
- */
- public DecompositionSolver(final RealMatrix matrix) {
- this.matrix = matrix;
- }
-
- /**
- * Decompose a matrix using eigendecomposition.
- * <p>The split tolerance is set by default to {@link MathUtils#SAFE_MIN}.</p>
- * @exception InvalidMatrixException if matrix does not fulfill
- * the decomposition requirements (for example non-square matrix
- * for {@link LUDecomposition})
- */
- public EigenDecomposition eigenDecompose()
- throws InvalidMatrixException {
- return new EigenDecompositionImpl(matrix, MathUtils.SAFE_MIN);
- }
-
- /**
- * Decompose a matrix using eigendecomposition.
- * @param splitTolerance tolerance on the off-diagonal elements relative to the
- * geometric mean to split the tridiagonal matrix (a suggested value is
- * {@link MathUtils#SAFE_MIN})
- * @exception InvalidMatrixException if matrix does not fulfill
- * the decomposition requirements (for example non-square matrix
- * for {@link LUDecomposition})
- */
- public EigenDecomposition eigenDecompose(final double splitTolerance)
- throws InvalidMatrixException {
- return new EigenDecompositionImpl(matrix, splitTolerance);
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a vector X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public double[] solve(final double[] b, final EigenDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- final double[] eigenvalues = decomposition.getEigenvalues();
- final int m = eigenvalues.length;
- if (b.length != m) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
-
- final double[] bp = new double[m];
- for (int i = 0; i < m; ++i) {
- final RealVector v = decomposition.getEigenvector(i);
- final double s = v.dotProduct(b) / eigenvalues[i];
- for (int j = 0; j < m; ++j) {
- bp[j] += s * v.getEntry(j);
- }
- }
-
- return bp;
-
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a vector X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public RealVector solve(final RealVector b, final EigenDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- final double[] eigenvalues = decomposition.getEigenvalues();
- final int m = eigenvalues.length;
- if (b.getDimension() != m) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
-
- final double[] bp = new double[m];
- for (int i = 0; i < m; ++i) {
- final RealVector v = decomposition.getEigenvector(i);
- final double s = v.dotProduct(b) / eigenvalues[i];
- for (int j = 0; j < m; ++j) {
- bp[j] += s * v.getEntry(j);
- }
- }
-
- return new RealVectorImpl(bp, false);
-
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a matrix X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public RealMatrix solve(final RealMatrix b, final EigenDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- final double[] eigenvalues = decomposition.getEigenvalues();
- final int m = eigenvalues.length;
- if (b.getRowDimension() != m) {
- throw new IllegalArgumentException("Incorrect row dimension");
- }
-
- final int nColB = b.getColumnDimension();
- final double[][] bp = new double[m][nColB];
- for (int k = 0; k < nColB; ++k) {
- for (int i = 0; i < m; ++i) {
- final RealVector v = decomposition.getEigenvector(i);
- double s = 0;
- for (int j = 0; j < m; ++j) {
- s += v.getEntry(j) * b.getEntry(j, k);
- }
- s /= eigenvalues[i];
- for (int j = 0; j < m; ++j) {
- bp[j][k] += s * v.getEntry(j);
- }
- }
- }
-
- return new RealMatrixImpl(bp, false);
-
- }
-
- /**
- * Return the determinant of the matrix
- * @param decomposition decomposition of the matrix A
- * @return determinant of the matrix
- * @see #isNonSingular()
- */
- public double getDeterminant(final EigenDecomposition decomposition) {
- double determinant = 1;
- for (double lambda : decomposition.getEigenvalues()) {
- determinant *= lambda;
- }
- return determinant;
- }
-
- /**
- * Check if the decomposed matrix is non-singular.
- * @param decomposition decomposition of the matrix A
- * @return true if the decomposed matrix is non-singular
- */
- public boolean isNonSingular(final EigenDecomposition decomposition) {
- for (double lambda : decomposition.getEigenvalues()) {
- if (lambda == 0) {
- return false;
- }
- }
- return true;
- }
-
- /** Get the inverse of the decomposed matrix.
- * @param decomposition decomposition of the matrix A
- * @return inverse matrix
- * @throws InvalidMatrixException if decomposed matrix is singular
- */
- public RealMatrix getInverse(final EigenDecomposition decomposition)
- throws InvalidMatrixException {
-
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- final double[] eigenvalues = decomposition.getEigenvalues();
- final int m = eigenvalues.length;
- final double[][] invData = new double[m][m];
-
- for (int i = 0; i < m; ++i) {
- final double[] invI = invData[i];
- for (int j = 0; j < m; ++j) {
- double invIJ = 0;
- for (int k = 0; k < m; ++k) {
- final RealVector vK = decomposition.getEigenvector(k);
- invIJ += vK.getEntry(i) * vK.getEntry(j) / eigenvalues[k];
- }
- invI[j] = invIJ;
- }
- }
- return new RealMatrixImpl(invData, false);
-
- }
-
- /**
- * Decompose a matrix using singular value composition.
- * @exception InvalidMatrixException if matrix does not fulfill
- * the decomposition requirements (for example non-square matrix
- * for {@link LUDecomposition})
- */
- public SingularValueDecomposition singularDecompose()
- throws InvalidMatrixException {
- return new SingularValueDecompositionImpl(matrix);
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a vector X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public double[] solve(final double[] b, final SingularValueDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- final double[] singularValues = decomposition.getSingularValues();
- if (b.length != singularValues.length) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
-
- final double[] w = decomposition.getUT().operate(b);
- for (int i = 0; i < singularValues.length; ++i) {
- final double si = singularValues[i];
- if (si == 0) {
- throw new SingularMatrixException();
- }
- w[i] /= si;
- }
- return decomposition.getV().operate(w);
-
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a vector X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public RealVector solve(final RealVector b, final SingularValueDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- final double[] singularValues = decomposition.getSingularValues();
- if (b.getDimension() != singularValues.length) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
-
- final RealVector w = decomposition.getUT().operate(b);
- for (int i = 0; i < singularValues.length; ++i) {
- final double si = singularValues[i];
- if (si == 0) {
- throw new SingularMatrixException();
- }
- w.set(i, w.getEntry(i) / si);
- }
- return decomposition.getV().operate(w);
-
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a matrix X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public RealMatrix solve(final RealMatrix b, final SingularValueDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- final double[] singularValues = decomposition.getSingularValues();
- if (b.getRowDimension() != singularValues.length) {
- throw new IllegalArgumentException("Incorrect row dimension");
- }
-
- final RealMatrixImpl w = (RealMatrixImpl) decomposition.getUT().multiply(b);
- final double[][] wData = w.getDataRef();
- for (int i = 0; i < singularValues.length; ++i) {
- final double si = singularValues[i];
- if (si == 0) {
- throw new SingularMatrixException();
- }
- final double inv = 1.0 / si;
- final double[] wi = wData[i];
- for (int j = 0; j < b.getColumnDimension(); ++j) {
- wi[j] *= inv;
- }
- }
- return decomposition.getV().multiply(w);
-
- }
-
- /**
- * Check if the decomposed matrix is non-singular.
- * @param decomposition decomposition of the matrix A
- * @return true if the decomposed matrix is non-singular
- */
- public boolean isNonSingular(final SingularValueDecomposition decomposition) {
- return decomposition.getRank() == decomposition.getSingularValues().length;
- }
-
- /** Get the inverse of the decomposed matrix.
- * @param decomposition decomposition of the matrix A
- * @return inverse matrix
- * @throws InvalidMatrixException if decomposed matrix is singular
- */
- public RealMatrix getInverse(final SingularValueDecomposition decomposition)
- throws InvalidMatrixException {
-
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- return solve(MatrixUtils.createRealIdentityMatrix(decomposition.getSingularValues().length),
- decomposition);
-
- }
-
- /**
- * Decompose a matrix using QR decomposition.
- */
- public QRDecomposition qrDecompose() {
- return new QRDecompositionImpl(matrix);
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
+ /** Solve the linear equation A × X = B for matrices A.
+ * <p>The A matrix is implicit, it is provided by the underlying
+ * decomposition algorithm.</p>
* @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
* @return a vector X that minimizes the two norm of A × X - B
* @exception IllegalArgumentException if matrices dimensions don't match
* @exception InvalidMatrixException if decomposed matrix is singular
*/
- public double[] solve(final double[] b, final QRDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- if (decomposition.getR().getRowDimension() != b.length) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- // solve Q.y = b, using the fact Q is orthogonal
- final double[] y = decomposition.getQT().operate(b);
-
- // solve triangular system R.x = y
- final RealMatrix r = decomposition.getR();
- final double[] x = new double[r.getColumnDimension()];
- System.arraycopy(y, 0, x, 0, r.getRowDimension());
- for (int i = r.getRowDimension() - 1; i >= 0; --i) {
- x[i] /= r.getEntry(i, i);
- final double lastX = x[i];
- for (int j = i - 1; j >= 0; --j) {
- x[j] -= lastX * r.getEntry(j, i);
- }
- }
-
- return x;
-
- }
+ double[] solve(final double[] b)
+ throws IllegalArgumentException, InvalidMatrixException;
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
+ /** Solve the linear equation A × X = B for matrices A.
+ * <p>The A matrix is implicit, it is provided by the underlying
+ * decomposition algorithm.</p>
* @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
* @return a vector X that minimizes the two norm of A × X - B
* @exception IllegalArgumentException if matrices dimensions don't match
* @exception InvalidMatrixException if decomposed matrix is singular
*/
- public RealVector solve(final RealVector b, final QRDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
- return new RealVectorImpl(solve(b.getData(), decomposition), false);
- }
+ RealVector solve(final RealVector b)
+ throws IllegalArgumentException, InvalidMatrixException;
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
+ /** Solve the linear equation A × X = B for matrices A.
+ * <p>The A matrix is implicit, it is provided by the underlying
+ * decomposition algorithm.</p>
* @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
* @return a matrix X that minimizes the two norm of A × X - B
* @exception IllegalArgumentException if matrices dimensions don't match
* @exception InvalidMatrixException if decomposed matrix is singular
*/
- public RealMatrix solve(final RealMatrix b, final QRDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- if (decomposition.getR().getRowDimension() != b.getRowDimension()) {
- throw new IllegalArgumentException("Incorrect row dimension");
- }
- if (!isNonSingular(decomposition)) {
- throw new SingularMatrixException();
- }
-
- // solve Q.y = b, using the fact Q is orthogonal
- final RealMatrix y = decomposition.getQT().multiply(b);
-
- // solve triangular system R.x = y
- final RealMatrix r = decomposition.getR();
- final double[][] xData =
- new double[r.getColumnDimension()][b.getColumnDimension()];
- for (int i = 0; i < r.getRowDimension(); ++i) {
- final double[] xi = xData[i];
- for (int k = 0; k < xi.length; ++k) {
- xi[k] = y.getEntry(i, k);
- }
- }
- for (int i = r.getRowDimension() - 1; i >= 0; --i) {
- final double rii = r.getEntry(i, i);
- final double[] xi = xData[i];
- for (int k = 0; k < xi.length; ++k) {
- xi[k] /= rii;
- final double lastX = xi[k];
- for (int j = i - 1; j >= 0; --j) {
- xData[j][k] -= lastX * r.getEntry(j, i);
- }
- }
- }
-
- return new RealMatrixImpl(xData, false);
-
- }
+ RealMatrix solve(final RealMatrix b)
+ throws IllegalArgumentException, InvalidMatrixException;
/**
* Check if the decomposed matrix is non-singular.
- * @param decomposition decomposition of the matrix A
- * @return true if the decomposed matrix is non-singular
- */
- public boolean isNonSingular(final QRDecomposition decomposition) {
- final RealMatrix r = decomposition.getR();
- final int p = Math.min(r.getRowDimension(), r.getColumnDimension());
- for (int i = 0; i < p; ++i) {
- if (r.getEntry(i, i) == 0) {
- return false;
- }
- }
- return true;
- }
-
- /** Get the inverse of the decomposed matrix.
- * @param decomposition decomposition of the matrix A
- * @return inverse matrix
- * @throws InvalidMatrixException if decomposed matrix is singular
- */
- public RealMatrix getInverse(final QRDecomposition decomposition)
- throws InvalidMatrixException {
- final RealMatrix r = decomposition.getR();
- final int p = Math.min(r.getRowDimension(), r.getColumnDimension());
- return solve(MatrixUtils.createRealIdentityMatrix(p), decomposition);
- }
-
- /**
- * Decompose a matrix using LU decomposition.
- * @exception InvalidMatrixException if matrix is non-square)
- */
- public LUDecomposition luDecompose()
- throws InvalidMatrixException {
- return new LUDecompositionImpl(matrix);
- }
-
- /**
- * Decompose a matrix using LU decomposition.
- * @param singularityThreshold threshold (based on partial row norm)
- * under which a matrix is considered singular
- * @exception InvalidMatrixException if matrix is non-square)
- */
- public LUDecomposition luDecompose(final double singularityThreshold)
- throws InvalidMatrixException {
- return new LUDecompositionImpl(matrix, singularityThreshold);
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a vector X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public double[] solve(final double[] b, final LUDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- final int[] pivot = decomposition.getPivot();
- final int m = pivot.length;
- if (b.length != m) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
- if (decomposition.isSingular()) {
- throw new SingularMatrixException();
- }
-
- final double[] bp = new double[m];
-
- // Apply permutations to b
- for (int row = 0; row < m; row++) {
- bp[row] = b[pivot[row]];
- }
-
- // Solve LY = b
- final RealMatrix l = decomposition.getL();
- for (int col = 0; col < m; col++) {
- for (int i = col + 1; i < m; i++) {
- bp[i] -= bp[col] * l.getEntry(i, col);
- }
- }
-
- // Solve UX = Y
- final RealMatrix u = decomposition.getU();
- for (int col = m - 1; col >= 0; col--) {
- bp[col] /= u.getEntry(col, col);
- for (int i = 0; i < col; i++) {
- bp[i] -= bp[col] * u.getEntry(i, col);
- }
- }
-
- return bp;
-
- }
-
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a vector X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public RealVector solve(final RealVector b, final LUDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- final int[] pivot = decomposition.getPivot();
- final int m = pivot.length;
- if (b.getDimension() != m) {
- throw new IllegalArgumentException("constant vector has wrong length");
- }
- if (decomposition.isSingular()) {
- throw new SingularMatrixException();
- }
-
- final double[] bp = new double[m];
-
- // Apply permutations to b
- for (int row = 0; row < m; row++) {
- bp[row] = b.getEntry(pivot[row]);
- }
-
- // Solve LY = b
- final RealMatrix l = decomposition.getL();
- for (int col = 0; col < m; col++) {
- for (int i = col + 1; i < m; i++) {
- bp[i] -= bp[col] * l.getEntry(i, col);
- }
- }
-
- // Solve UX = Y
- final RealMatrix u = decomposition.getU();
- for (int col = m - 1; col >= 0; col--) {
- bp[col] /= u.getEntry(col, col);
- for (int i = 0; i < col; i++) {
- bp[i] -= bp[col] * u.getEntry(i, col);
- }
- }
-
- return new RealVectorImpl(bp, false);
-
- }
-
- /** Solve the linear equation A × X = B.
- * <p>The A matrix is implicit here. It <strong>must</strong> have
- * already been provided by a previous call to {@link #decompose(RealMatrix)}.</p>
- * @param b right-hand side of the equation A × X = B
- * @param decomposition decomposition of the matrix A
- * @return a matrix X that minimizes the two norm of A × X - B
- * @exception IllegalArgumentException if matrices dimensions don't match
- * @exception InvalidMatrixException if decomposed matrix is singular
- */
- public RealMatrix solve(final RealMatrix b, final LUDecomposition decomposition)
- throws IllegalArgumentException, InvalidMatrixException {
-
- final int[] pivot = decomposition.getPivot();
- final int m = pivot.length;
- if (b.getRowDimension() != m) {
- throw new IllegalArgumentException("Incorrect row dimension");
- }
- if (decomposition.isSingular()) {
- throw new SingularMatrixException();
- }
-
- final int nColB = b.getColumnDimension();
-
- // Apply permutations to b
- final double[][] bp = new double[m][nColB];
- for (int row = 0; row < m; row++) {
- final double[] bpRow = bp[row];
- final int pRow = pivot[row];
- for (int col = 0; col < nColB; col++) {
- bpRow[col] = b.getEntry(pRow, col);
- }
- }
-
- // Solve LY = b
- final RealMatrix l = decomposition.getL();
- for (int col = 0; col < m; col++) {
- final double[] bpCol = bp[col];
- for (int i = col + 1; i < m; i++) {
- final double[] bpI = bp[i];
- final double luICol = l.getEntry(i, col);
- for (int j = 0; j < nColB; j++) {
- bpI[j] -= bpCol[j] * luICol;
- }
- }
- }
-
- // Solve UX = Y
- final RealMatrix u = decomposition.getU();
- for (int col = m - 1; col >= 0; col--) {
- final double[] bpCol = bp[col];
- final double luDiag = u.getEntry(col, col);
- for (int j = 0; j < nColB; j++) {
- bpCol[j] /= luDiag;
- }
- for (int i = 0; i < col; i++) {
- final double[] bpI = bp[i];
- final double luICol = u.getEntry(i, col);
- for (int j = 0; j < nColB; j++) {
- bpI[j] -= bpCol[j] * luICol;
- }
- }
- }
-
- return new RealMatrixImpl(bp, false);
-
- }
-
-
- /**
- * Return the determinant of the matrix
- * @param decomposition decomposition of the matrix A
- * @return determinant of the matrix
- * @see #isNonSingular()
- */
- public double getDeterminant(final LUDecomposition decomposition) {
- if (decomposition.isSingular()) {
- return 0;
- } else {
- final int m = decomposition.getPivot().length;
- final RealMatrix u = decomposition.getU();
- double determinant = decomposition.evenPermutation() ? 1 : -1;
- for (int i = 0; i < m; i++) {
- determinant *= u.getEntry(i, i);
- }
- return determinant;
- }
- }
-
- /**
- * Check if the decomposed matrix is non-singular.
- * @param decomposition decomposition of the matrix A
* @return true if the decomposed matrix is non-singular
*/
- public boolean isNonSingular(final LUDecomposition decomposition) {
- return !decomposition.isSingular();
- }
+ boolean isNonSingular();
- /** Get the inverse of the decomposed matrix.
+ /** Get the inverse (or pseudo-inverse) of the decomposed matrix.
* @param decomposition decomposition of the matrix A
* @return inverse matrix
* @throws InvalidMatrixException if decomposed matrix is singular
*/
- public RealMatrix getInverse(final LUDecomposition decomposition)
- throws InvalidMatrixException {
- final int m = decomposition.getPivot().length;
- return solve(MatrixUtils.createRealIdentityMatrix(m), decomposition);
- }
+ RealMatrix getInverse()
+ throws InvalidMatrixException;
}
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java?rev=723736&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java Fri Dec 5 06:05:50 2008
@@ -0,0 +1,210 @@
+/*
+ * 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;
+
+
+/**
+ * Solver using eigen decomposition to solve A × X = B for symmetric matrices A.
+ * <p>This class finds only exact linear solution, i.e. when
+ * ||A × X - B|| is exactly 0.</p>
+ *
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public class EigenSolver implements DecompositionSolver {
+
+ /** Serializable version identifier. */
+ private static final long serialVersionUID = 4339008311386325953L;
+
+ /** Underlying decomposition. */
+ private final EigenDecomposition decomposition;
+
+ /**
+ * Simple constructor.
+ * @param decomposition decomposition to use
+ */
+ public EigenSolver(final EigenDecomposition decomposition) {
+ this.decomposition = decomposition;
+ }
+
+ /** Solve the linear equation A × X = B for symmetric matrices A.
+ * <p>This method only find exact linear solutions, i.e. solutions for
+ * which ||A × X - B|| is exactly 0.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public double[] solve(final double[] b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final double[] eigenvalues = decomposition.getEigenvalues();
+ final int m = eigenvalues.length;
+ if (b.length != m) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+
+ final double[] bp = new double[m];
+ for (int i = 0; i < m; ++i) {
+ final RealVector v = decomposition.getEigenvector(i);
+ final double s = v.dotProduct(b) / eigenvalues[i];
+ for (int j = 0; j < m; ++j) {
+ bp[j] += s * v.getEntry(j);
+ }
+ }
+
+ return bp;
+
+ }
+
+ /** Solve the linear equation A × X = B for symmetric matrices A.
+ * <p>This method only find exact linear solutions, i.e. solutions for
+ * which ||A × X - B|| is exactly 0.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealVector solve(final RealVector b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final double[] eigenvalues = decomposition.getEigenvalues();
+ final int m = eigenvalues.length;
+ if (b.getDimension() != m) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+
+ final double[] bp = new double[m];
+ for (int i = 0; i < m; ++i) {
+ final RealVector v = decomposition.getEigenvector(i);
+ final double s = v.dotProduct(b) / eigenvalues[i];
+ for (int j = 0; j < m; ++j) {
+ bp[j] += s * v.getEntry(j);
+ }
+ }
+
+ return new RealVectorImpl(bp, false);
+
+ }
+
+ /** Solve the linear equation A × X = B for symmetric matrices A.
+ * <p>This method only find exact linear solutions, i.e. solutions for
+ * which ||A × X - B|| is exactly 0.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a matrix X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix solve(final RealMatrix b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final double[] eigenvalues = decomposition.getEigenvalues();
+ final int m = eigenvalues.length;
+ if (b.getRowDimension() != m) {
+ throw new IllegalArgumentException("Incorrect row dimension");
+ }
+
+ final int nColB = b.getColumnDimension();
+ final double[][] bp = new double[m][nColB];
+ for (int k = 0; k < nColB; ++k) {
+ for (int i = 0; i < m; ++i) {
+ final RealVector v = decomposition.getEigenvector(i);
+ double s = 0;
+ for (int j = 0; j < m; ++j) {
+ s += v.getEntry(j) * b.getEntry(j, k);
+ }
+ s /= eigenvalues[i];
+ for (int j = 0; j < m; ++j) {
+ bp[j][k] += s * v.getEntry(j);
+ }
+ }
+ }
+
+ return new RealMatrixImpl(bp, false);
+
+ }
+
+ /**
+ * Return the determinant of the matrix
+ * @return determinant of the matrix
+ * @see #isNonSingular()
+ */
+ public double getDeterminant() {
+ double determinant = 1;
+ for (double lambda : decomposition.getEigenvalues()) {
+ determinant *= lambda;
+ }
+ return determinant;
+ }
+
+ /**
+ * Check if the decomposed matrix is non-singular.
+ * @return true if the decomposed matrix is non-singular
+ */
+ public boolean isNonSingular() {
+ for (double lambda : decomposition.getEigenvalues()) {
+ if (lambda == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Get the inverse of the decomposed matrix.
+ * @return inverse matrix
+ * @throws InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix getInverse()
+ throws InvalidMatrixException {
+
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final double[] eigenvalues = decomposition.getEigenvalues();
+ final int m = eigenvalues.length;
+ final double[][] invData = new double[m][m];
+
+ for (int i = 0; i < m; ++i) {
+ final double[] invI = invData[i];
+ for (int j = 0; j < m; ++j) {
+ double invIJ = 0;
+ for (int k = 0; k < m; ++k) {
+ final RealVector vK = decomposition.getEigenvector(k);
+ invIJ += vK.getEntry(i) * vK.getEntry(j) / eigenvalues[k];
+ }
+ invI[j] = invIJ;
+ }
+ }
+ return new RealMatrixImpl(invData, false);
+
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/EigenSolver.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java?rev=723736&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java Fri Dec 5 06:05:50 2008
@@ -0,0 +1,245 @@
+/*
+ * 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;
+
+
+/**
+ * Solver using LU decomposition to solve A × X = B for square matrices A.
+ * <p>This class finds only exact linear solution, i.e. when
+ * ||A × X - B|| is exactly 0.</p>
+ *
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public class LUSolver implements DecompositionSolver {
+
+ /** Serializable version identifier. */
+ private static final long serialVersionUID = -8775006035077527661L;
+
+ /** Underlying decomposition. */
+ private final LUDecomposition decomposition;
+
+ /**
+ * Simple constructor.
+ * @param decomposition decomposition to use
+ */
+ public LUSolver(final LUDecomposition decomposition) {
+ this.decomposition = decomposition;
+ }
+
+ /** Solve the linear equation A × X = B for square matrices A.
+ * <p>This method only find exact linear solutions, i.e. solutions for
+ * which ||A × X - B|| is exactly 0.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public double[] solve(final double[] b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ final int[] pivot = decomposition.getPivot();
+ final int m = pivot.length;
+ if (b.length != m) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+ if (decomposition.isSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final double[] bp = new double[m];
+
+ // Apply permutations to b
+ for (int row = 0; row < m; row++) {
+ bp[row] = b[pivot[row]];
+ }
+
+ // Solve LY = b
+ final RealMatrix l = decomposition.getL();
+ for (int col = 0; col < m; col++) {
+ for (int i = col + 1; i < m; i++) {
+ bp[i] -= bp[col] * l.getEntry(i, col);
+ }
+ }
+
+ // Solve UX = Y
+ final RealMatrix u = decomposition.getU();
+ for (int col = m - 1; col >= 0; col--) {
+ bp[col] /= u.getEntry(col, col);
+ for (int i = 0; i < col; i++) {
+ bp[i] -= bp[col] * u.getEntry(i, col);
+ }
+ }
+
+ return bp;
+
+ }
+
+
+ /** Solve the linear equation A × X = B for square matrices A.
+ * <p>This method only find exact linear solutions, i.e. solutions for
+ * which ||A × X - B|| is exactly 0.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealVector solve(final RealVector b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ final int[] pivot = decomposition.getPivot();
+ final int m = pivot.length;
+ if (b.getDimension() != m) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+ if (decomposition.isSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final double[] bp = new double[m];
+
+ // Apply permutations to b
+ for (int row = 0; row < m; row++) {
+ bp[row] = b.getEntry(pivot[row]);
+ }
+
+ // Solve LY = b
+ final RealMatrix l = decomposition.getL();
+ for (int col = 0; col < m; col++) {
+ for (int i = col + 1; i < m; i++) {
+ bp[i] -= bp[col] * l.getEntry(i, col);
+ }
+ }
+
+ // Solve UX = Y
+ final RealMatrix u = decomposition.getU();
+ for (int col = m - 1; col >= 0; col--) {
+ bp[col] /= u.getEntry(col, col);
+ for (int i = 0; i < col; i++) {
+ bp[i] -= bp[col] * u.getEntry(i, col);
+ }
+ }
+
+ return new RealVectorImpl(bp, false);
+
+ }
+
+ /** Solve the linear equation A × X = B for square matrices A.
+ * <p>This method only find exact linear solutions, i.e. solutions for
+ * which ||A × X - B|| is exactly 0.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a matrix X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix solve(final RealMatrix b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ final int[] pivot = decomposition.getPivot();
+ final int m = pivot.length;
+ if (b.getRowDimension() != m) {
+ throw new IllegalArgumentException("Incorrect row dimension");
+ }
+ if (decomposition.isSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ final int nColB = b.getColumnDimension();
+
+ // Apply permutations to b
+ final double[][] bp = new double[m][nColB];
+ for (int row = 0; row < m; row++) {
+ final double[] bpRow = bp[row];
+ final int pRow = pivot[row];
+ for (int col = 0; col < nColB; col++) {
+ bpRow[col] = b.getEntry(pRow, col);
+ }
+ }
+
+ // Solve LY = b
+ final RealMatrix l = decomposition.getL();
+ for (int col = 0; col < m; col++) {
+ final double[] bpCol = bp[col];
+ for (int i = col + 1; i < m; i++) {
+ final double[] bpI = bp[i];
+ final double luICol = l.getEntry(i, col);
+ for (int j = 0; j < nColB; j++) {
+ bpI[j] -= bpCol[j] * luICol;
+ }
+ }
+ }
+
+ // Solve UX = Y
+ final RealMatrix u = decomposition.getU();
+ for (int col = m - 1; col >= 0; col--) {
+ final double[] bpCol = bp[col];
+ final double luDiag = u.getEntry(col, col);
+ for (int j = 0; j < nColB; j++) {
+ bpCol[j] /= luDiag;
+ }
+ for (int i = 0; i < col; i++) {
+ final double[] bpI = bp[i];
+ final double luICol = u.getEntry(i, col);
+ for (int j = 0; j < nColB; j++) {
+ bpI[j] -= bpCol[j] * luICol;
+ }
+ }
+ }
+
+ return new RealMatrixImpl(bp, false);
+
+ }
+
+ /**
+ * Return the determinant of the matrix
+ * @return determinant of the matrix
+ * @see #isNonSingular()
+ */
+ public double getDeterminant() {
+ if (decomposition.isSingular()) {
+ return 0;
+ } else {
+ final int m = decomposition.getPivot().length;
+ final RealMatrix u = decomposition.getU();
+ double determinant = decomposition.evenPermutation() ? 1 : -1;
+ for (int i = 0; i < m; i++) {
+ determinant *= u.getEntry(i, i);
+ }
+ return determinant;
+ }
+ }
+
+ /**
+ * Check if the decomposed matrix is non-singular.
+ * @return true if the decomposed matrix is non-singular
+ */
+ public boolean isNonSingular() {
+ return !decomposition.isSingular();
+ }
+
+ /** Get the inverse of the decomposed matrix.
+ * @return inverse matrix
+ * @throws InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix getInverse()
+ throws InvalidMatrixException {
+ final int m = decomposition.getPivot().length;
+ return solve(MatrixUtils.createRealIdentityMatrix(m));
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/LUSolver.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java?rev=723736&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java Fri Dec 5 06:05:50 2008
@@ -0,0 +1,169 @@
+/*
+ * 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;
+
+
+/**
+ * Class using QR decomposition to solve A × X = B in least square sense
+ * for any matrices A.
+ * <p>This class solve A × X = B in least squares sense: it finds X
+ * such that ||A × X - B|| is minimal.</p>
+ *
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public class QRSolver implements DecompositionSolver {
+
+ /** Serializable version identifier. */
+ private static final long serialVersionUID = -579465076068393818L;
+
+ /** Underlying decomposition. */
+ private final QRDecomposition decomposition;
+
+ /**
+ * Simple constructor.
+ * @param decomposition decomposition to use
+ */
+ public QRSolver(final QRDecomposition decomposition) {
+ this.decomposition = decomposition;
+ }
+
+ /** Solve the linear equation A × X = B in least square sense.
+ * <p>The m×n matrix A may not be square, the solution X is
+ * such that ||A × X - B|| is minimal.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public double[] solve(final double[] b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ if (decomposition.getR().getRowDimension() != b.length) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ // solve Q.y = b, using the fact Q is orthogonal
+ final double[] y = decomposition.getQT().operate(b);
+
+ // solve triangular system R.x = y
+ final RealMatrix r = decomposition.getR();
+ final double[] x = new double[r.getColumnDimension()];
+ System.arraycopy(y, 0, x, 0, r.getRowDimension());
+ for (int i = r.getRowDimension() - 1; i >= 0; --i) {
+ x[i] /= r.getEntry(i, i);
+ final double lastX = x[i];
+ for (int j = i - 1; j >= 0; --j) {
+ x[j] -= lastX * r.getEntry(j, i);
+ }
+ }
+
+ return x;
+
+ }
+
+ /** Solve the linear equation A × X = B in least square sense.
+ * <p>The m×n matrix A may not be square, the solution X is
+ * such that ||A × X - B|| is minimal.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealVector solve(final RealVector b)
+ throws IllegalArgumentException, InvalidMatrixException {
+ return new RealVectorImpl(solve(b.getData()), false);
+ }
+
+ /** Solve the linear equation A × X = B in least square sense.
+ * <p>The m×n matrix A may not be square, the solution X is
+ * such that ||A × X - B|| is minimal.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a matrix X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix solve(final RealMatrix b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ if (decomposition.getR().getRowDimension() != b.getRowDimension()) {
+ throw new IllegalArgumentException("Incorrect row dimension");
+ }
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ // solve Q.y = b, using the fact Q is orthogonal
+ final RealMatrix y = decomposition.getQT().multiply(b);
+
+ // solve triangular system R.x = y
+ final RealMatrix r = decomposition.getR();
+ final double[][] xData =
+ new double[r.getColumnDimension()][b.getColumnDimension()];
+ for (int i = 0; i < r.getRowDimension(); ++i) {
+ final double[] xi = xData[i];
+ for (int k = 0; k < xi.length; ++k) {
+ xi[k] = y.getEntry(i, k);
+ }
+ }
+ for (int i = r.getRowDimension() - 1; i >= 0; --i) {
+ final double rii = r.getEntry(i, i);
+ final double[] xi = xData[i];
+ for (int k = 0; k < xi.length; ++k) {
+ xi[k] /= rii;
+ final double lastX = xi[k];
+ for (int j = i - 1; j >= 0; --j) {
+ xData[j][k] -= lastX * r.getEntry(j, i);
+ }
+ }
+ }
+
+ return new RealMatrixImpl(xData, false);
+
+ }
+
+ /**
+ * Check if the decomposed matrix is non-singular.
+ * @return true if the decomposed matrix is non-singular
+ */
+ public boolean isNonSingular() {
+ final RealMatrix r = decomposition.getR();
+ final int p = Math.min(r.getRowDimension(), r.getColumnDimension());
+ for (int i = 0; i < p; ++i) {
+ if (r.getEntry(i, i) == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Get the pseudo-inverse of the decomposed matrix.
+ * @return inverse matrix
+ * @throws InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix getInverse()
+ throws InvalidMatrixException {
+ final RealMatrix r = decomposition.getR();
+ final int p = Math.min(r.getRowDimension(), r.getColumnDimension());
+ return solve(MatrixUtils.createRealIdentityMatrix(p));
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/QRSolver.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/RealMatrixImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/RealMatrixImpl.java?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/RealMatrixImpl.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/RealMatrixImpl.java Fri Dec 5 06:05:50 2008
@@ -54,20 +54,15 @@
public class RealMatrixImpl implements RealMatrix, Serializable {
/** Serializable version identifier */
- private static final long serialVersionUID = 4970229902484487012L;
+ private static final long serialVersionUID = -391443069570048115L;
/** Entries of the matrix */
protected double data[][];
- /** Cached decomposition solver.
+ /** Cached LU solver.
* @deprecated as of release 2.0, since all methods using this are deprecated
*/
- private DecompositionSolver ds;
-
- /** Cached LU decomposition.
- * @deprecated as of release 2.0, since all methods using this are deprecated
- */
- private LUDecomposition lu;
+ private LUSolver lu;
/**
* Creates a matrix with no data
@@ -89,7 +84,7 @@
"row and column dimensions must be postive");
}
data = new double[rowDimension][columnDimension];
- ds = null;
+ lu = null;
}
/**
@@ -107,7 +102,7 @@
*/
public RealMatrixImpl(double[][] d) {
copyIn(d);
- ds = null;
+ lu = null;
}
/**
@@ -147,7 +142,7 @@
}
data = d;
}
- ds = null;
+ lu = null;
}
/**
@@ -546,7 +541,7 @@
System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols);
}
- ds = null;
+ lu = null;
}
@@ -631,21 +626,19 @@
/** {@inheritDoc} */
@Deprecated
public RealMatrix inverse() throws InvalidMatrixException {
- if (ds == null) {
- ds = new DecompositionSolver(this);
- lu = ds.luDecompose(MathUtils.SAFE_MIN);
+ if (lu == null) {
+ lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
}
- return ds.getInverse(lu);
+ return lu.getInverse();
}
/** {@inheritDoc} */
@Deprecated
public double getDeterminant() throws InvalidMatrixException {
- if (ds == null) {
- ds = new DecompositionSolver(this);
- lu = ds.luDecompose(MathUtils.SAFE_MIN);
+ if (lu == null) {
+ lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
}
- return ds.getDeterminant(lu);
+ return lu.getDeterminant();
}
/** {@inheritDoc} */
@@ -656,11 +649,10 @@
/** {@inheritDoc} */
@Deprecated
public boolean isSingular() {
- if (ds == null) {
- ds = new DecompositionSolver(this);
- lu = ds.luDecompose(MathUtils.SAFE_MIN);
- }
- return !ds.isNonSingular(lu);
+ if (lu == null) {
+ lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
+ }
+ return !lu.isNonSingular();
}
/** {@inheritDoc} */
@@ -792,21 +784,19 @@
/** {@inheritDoc} */
@Deprecated
public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException {
- if (ds == null) {
- ds = new DecompositionSolver(this);
- lu = ds.luDecompose(MathUtils.SAFE_MIN);
+ if (lu == null) {
+ lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
}
- return ds.solve(b, lu);
+ return lu.solve(b);
}
/** {@inheritDoc} */
@Deprecated
public RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException {
- if (ds == null) {
- ds = new DecompositionSolver(this);
- lu = ds.luDecompose(MathUtils.SAFE_MIN);
+ if (lu == null) {
+ lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
}
- return ds.solve(b, lu);
+ return lu.solve(b);
}
/**
@@ -830,9 +820,8 @@
*/
@Deprecated
public void luDecompose() throws InvalidMatrixException {
- if (ds == null) {
- ds = new DecompositionSolver(this);
- lu = ds.luDecompose(MathUtils.SAFE_MIN);
+ if (lu == null) {
+ lu = new LUSolver(new LUDecompositionImpl(this, MathUtils.SAFE_MIN));
}
}
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueSolver.java?rev=723736&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueSolver.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueSolver.java Fri Dec 5 06:05:50 2008
@@ -0,0 +1,158 @@
+/*
+ * 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;
+
+
+/**
+ * Class using singular value decomposition decomposition to solve A ×
+ * X = B in least square sense for any matrices A.
+ * <p>This class solve A × X = B in least squares sense: it finds X
+ * such that ||A × X - B|| is minimal.</p>
+ *
+ * @version $Revision: 723496 $ $Date: 2008-12-05 00:48:18 +0100 (ven., 05 déc. 2008) $
+ * @since 2.0
+ */
+public class SingularValueSolver implements DecompositionSolver {
+
+ /** Serializable version identifier. */
+ private static final long serialVersionUID = -33167987924870528L;
+
+ /** Underlying decomposition. */
+ private final SingularValueDecomposition decomposition;
+
+ /**
+ * Simple constructor.
+ * @param decomposition decomposition to use
+ */
+ public SingularValueSolver(final SingularValueDecomposition decomposition) {
+ this.decomposition = decomposition;
+ }
+
+ /** Solve the linear equation A × X = B in least square sense.
+ * <p>The m×n matrix A may not be square, the solution X is
+ * such that ||A × X - B|| is minimal.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public double[] solve(final double[] b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ final double[] singularValues = decomposition.getSingularValues();
+ if (b.length != singularValues.length) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+
+ final double[] w = decomposition.getUT().operate(b);
+ for (int i = 0; i < singularValues.length; ++i) {
+ final double si = singularValues[i];
+ if (si == 0) {
+ throw new SingularMatrixException();
+ }
+ w[i] /= si;
+ }
+ return decomposition.getV().operate(w);
+
+ }
+
+ /** Solve the linear equation A × X = B in least square sense.
+ * <p>The m×n matrix A may not be square, the solution X is
+ * such that ||A × X - B|| is minimal.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a vector X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealVector solve(final RealVector b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ final double[] singularValues = decomposition.getSingularValues();
+ if (b.getDimension() != singularValues.length) {
+ throw new IllegalArgumentException("constant vector has wrong length");
+ }
+
+ final RealVector w = decomposition.getUT().operate(b);
+ for (int i = 0; i < singularValues.length; ++i) {
+ final double si = singularValues[i];
+ if (si == 0) {
+ throw new SingularMatrixException();
+ }
+ w.set(i, w.getEntry(i) / si);
+ }
+ return decomposition.getV().operate(w);
+
+ }
+
+ /** Solve the linear equation A × X = B in least square sense.
+ * <p>The m×n matrix A may not be square, the solution X is
+ * such that ||A × X - B|| is minimal.</p>
+ * @param b right-hand side of the equation A × X = B
+ * @return a matrix X that minimizes the two norm of A × X - B
+ * @exception IllegalArgumentException if matrices dimensions don't match
+ * @exception InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix solve(final RealMatrix b)
+ throws IllegalArgumentException, InvalidMatrixException {
+
+ final double[] singularValues = decomposition.getSingularValues();
+ if (b.getRowDimension() != singularValues.length) {
+ throw new IllegalArgumentException("Incorrect row dimension");
+ }
+
+ final RealMatrixImpl w = (RealMatrixImpl) decomposition.getUT().multiply(b);
+ final double[][] wData = w.getDataRef();
+ for (int i = 0; i < singularValues.length; ++i) {
+ final double si = singularValues[i];
+ if (si == 0) {
+ throw new SingularMatrixException();
+ }
+ final double inv = 1.0 / si;
+ final double[] wi = wData[i];
+ for (int j = 0; j < b.getColumnDimension(); ++j) {
+ wi[j] *= inv;
+ }
+ }
+ return decomposition.getV().multiply(w);
+
+ }
+
+ /**
+ * Check if the decomposed matrix is non-singular.
+ * @return true if the decomposed matrix is non-singular
+ */
+ public boolean isNonSingular() {
+ return decomposition.getRank() == decomposition.getSingularValues().length;
+ }
+
+ /** Get the pseudo-inverse of the decomposed matrix.
+ * @return inverse matrix
+ * @throws InvalidMatrixException if decomposed matrix is singular
+ */
+ public RealMatrix getInverse()
+ throws InvalidMatrixException {
+
+ if (!isNonSingular()) {
+ throw new SingularMatrixException();
+ }
+
+ return solve(MatrixUtils.createRealIdentityMatrix(decomposition.getSingularValues().length));
+
+ }
+
+}
Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueSolver.java
------------------------------------------------------------------------------
svn:mergeinfo =
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java Fri Dec 5 06:05:50 2008
@@ -16,7 +16,8 @@
*/
package org.apache.commons.math.stat.regression;
-import org.apache.commons.math.linear.DecompositionSolver;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.LUSolver;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealMatrixImpl;
@@ -78,8 +79,7 @@
*/
protected RealMatrix getOmegaInverse() {
if (OmegaInverse == null) {
- DecompositionSolver solver = new DecompositionSolver(Omega);
- OmegaInverse = solver.getInverse(solver.luDecompose());
+ OmegaInverse = new LUSolver(new LUDecompositionImpl(Omega)).getInverse();
}
return OmegaInverse;
}
@@ -95,8 +95,8 @@
RealMatrix OI = getOmegaInverse();
RealMatrix XT = X.transpose();
RealMatrix XTOIX = XT.multiply(OI).multiply(X);
- DecompositionSolver solver = new DecompositionSolver(XTOIX);
- return solver.getInverse(solver.luDecompose()).multiply(XT).multiply(OI).multiply(Y);
+ RealMatrix inverse = new LUSolver(new LUDecompositionImpl(XTOIX)).getInverse();
+ return inverse.multiply(XT).multiply(OI).multiply(Y);
}
/**
@@ -109,8 +109,7 @@
protected RealMatrix calculateBetaVariance() {
RealMatrix OI = getOmegaInverse();
RealMatrix XTOIX = X.transpose().multiply(OI).multiply(X);
- DecompositionSolver solver = new DecompositionSolver(XTOIX);
- return solver.getInverse(solver.luDecompose());
+ return new LUSolver(new LUDecompositionImpl(XTOIX)).getInverse();
}
/**
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java Fri Dec 5 06:05:50 2008
@@ -16,8 +16,8 @@
*/
package org.apache.commons.math.stat.regression;
-import org.apache.commons.math.linear.DecompositionSolver;
import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.LUSolver;
import org.apache.commons.math.linear.QRDecomposition;
import org.apache.commons.math.linear.QRDecompositionImpl;
import org.apache.commons.math.linear.RealMatrix;
@@ -109,8 +109,7 @@
*/
protected RealMatrix calculateBetaVariance() {
RealMatrix XTX = X.transpose().multiply(X);
- DecompositionSolver solver = new DecompositionSolver(XTX);
- return solver.getInverse(solver.luDecompose());
+ return new LUSolver(new LUDecompositionImpl(XTX)).getInverse();
}
Modified: commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml?rev=723736&r1=723735&r2=723736&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml Fri Dec 5 06:05:50 2008
@@ -66,8 +66,7 @@
System.out.println(p.getColumnDimension()); // 2
// Invert p, using LU decomposition
-DecompositionSolver solver = new DecompositionSolver(p);
-RealMatrix pInverse = solver.inverse(solver.luDecompose());
+RealMatrix pInverse = new LUSolver(new LUDecompositionImpl(p))).getInverse();
</source>
</p>
</subsection>
@@ -93,7 +92,7 @@
</subsection>
<subsection name="3.4 Solving linear systems" href="solve">
<p>
- The <code>solve()</code> methods of the <code>DecompositionSolver</code> class
+ The <code>solve()</code> methods of the <code>DecompositionSolver</code> interface
support solving linear systems of equations of the form AX=B, either in linear sense
or in least square sense. In each case, the <code>RealMatrix</code> represents the
coefficient matrix of the system. For example, to solve the linear system
@@ -108,14 +107,13 @@
RealMatrix coefficients =
new RealMatrixImpl(new double[][] { { 2, 3, -2 }, { -1, 7, 6 }, { 4, -3, -5 } },
false);
-DecompositionSolver solver = new DecompositionSolver(coefficients);
+LUSolver solver = new LUSolver(new LUDecompositionImpl(coefficients));
</source>
Next create a <code>RealVector</code> array to represent the constant
- vector B, select one of the decomposition algorithms (LU, QR ...) and use
- <code>solve(vector, decomposition)</code> to solve the system
+ vector B and use <code>solve(RealVector)</code> to solve the system
<source>
RealVector constants = new RealVectorImpl(new double[] { 1, -2, 1 }, false);
-RealVector solution = solver.solve(constants, solver.luDecomposition());
+RealVector solution = solver.solve(constants);
</source>
The <code>solution</code> vector will contain values for x
(<code>solution.getEntry(0)</code>), y (<code>solution.getEntry(1)</code>),
@@ -126,11 +124,10 @@
for X is such that the residual AX-B has minimal norm. If an exact solution
exist (i.e. if for some X the residual AX-B is exactly 0), then this exact
solution is also the solution in least square sense. Some solvers like
- <code>LUDecomposition</code> can only find the solution for
- square matrices and when the solution is an exact linear solution. Other solvers
- like <code>QRDecomposition</code> are more versatile and can also find solutions
- with non-square matrix A or when no exact solution exist (i.e. when the minimal
- value for AX-B norm is non-null).
+ <code>LUSolver</code> can only find the solution for square matrices and when
+ the solution is an exact linear solution. Other solvers like <code>QRDecomposition</code>
+ are more versatile and can also find solutions with non-square matrix A or when
+ no exact solution exist (i.e. when the minimal value for AX-B norm is non-null).
</p>
<p>
If the coefficient matrix is singular or doesn't fulfill the requirements of
@@ -145,13 +142,16 @@
<p>
It is possible to solve multiple systems with the same coefficient matrix
in one method call. To do this, create a matrix whose column vectors correspond
- to the constant vectors for the systems to be solved and use
- <code>solve(matrix, decomposition),</code> which returns a matrix with column
- vectors representing the solutions.
+ to the constant vectors for the systems to be solved and use <code>solve(RealMatrix),</code>
+ which returns a matrix with column vectors representing the solutions.
</p>
</subsection>
<subsection name="3.5 Eigenvalues/eigenvectors and singular values/singular vectors" href="eigen">
<p>
+ Decomposition algorithms may be used for themselves and not only for linear system solving.
+ This is of prime interest with eigen decomposition and singular value decomposition.
+ </p>
+ <p>
The <code>getEigenvalue()</code>, <code>getEigenvalues()</code>, <code>getEigenVector()</code>,
<code>getV()</code>, <code>getD()</code> and <code>getVT()</code> methods of the
<code>EigenDecomposition</code> interface support solving eigenproblems of the form