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 &times; 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 &times; X = B in least squares sense: they find X
+ * Interface handling decomposition algorithms that can solve A &times; X = B.
+ * <p>Decomposition algorithms decompose an A matrix has a product of several specific
+ * matrices from which they can solve A &times; X = B in least squares sense: they find X
  * such that ||A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a matrix X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a matrix X that minimizes the two norm of A &times; 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 &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
      * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
      * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
      * @return a matrix X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a vector X that minimizes the two norm of A &times; 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 &times; 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 &times; X = B
-     * @param decomposition decomposition of the matrix A
-     * @return a matrix X that minimizes the two norm of A &times; 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 &times; X = B for symmetric matrices A.
+ * <p>This class finds only exact linear solution, i.e. when
+ * ||A &times; 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 &times; X = B for symmetric matrices A.
+     * <p>This method only find exact linear solutions, i.e. solutions for
+     * which ||A &times; X - B|| is exactly 0.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B for symmetric matrices A.
+     * <p>This method only find exact linear solutions, i.e. solutions for
+     * which ||A &times; X - B|| is exactly 0.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B for symmetric matrices A.
+     * <p>This method only find exact linear solutions, i.e. solutions for
+     * which ||A &times; X - B|| is exactly 0.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a matrix X that minimizes the two norm of A &times; 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 &times; X = B for square matrices A.
+ * <p>This class finds only exact linear solution, i.e. when
+ * ||A &times; 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 &times; X = B for square matrices A.
+     * <p>This method only find exact linear solutions, i.e. solutions for
+     * which ||A &times; X - B|| is exactly 0.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B for square matrices A.
+     * <p>This method only find exact linear solutions, i.e. solutions for
+     * which ||A &times; X - B|| is exactly 0.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B for square matrices A.
+     * <p>This method only find exact linear solutions, i.e. solutions for
+     * which ||A &times; X - B|| is exactly 0.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a matrix X that minimizes the two norm of A &times; 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 &times; X = B in least square sense
+ * for any matrices A.
+ * <p>This class solve A &times; X = B in least squares sense: it finds X
+ * such that ||A &times; 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 &times; X = B in least square sense.
+     * <p>The m&times;n matrix A may not be square, the solution X is
+     * such that ||A &times; X - B|| is minimal.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B in least square sense.
+     * <p>The m&times;n matrix A may not be square, the solution X is
+     * such that ||A &times; X - B|| is minimal.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B in least square sense.
+     * <p>The m&times;n matrix A may not be square, the solution X is
+     * such that ||A &times; X - B|| is minimal.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a matrix X that minimizes the two norm of A &times; 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 &times;
+ * X = B in least square sense for any matrices A.
+ * <p>This class solve A &times; X = B in least squares sense: it finds X
+ * such that ||A &times; 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 &times; X = B in least square sense.
+     * <p>The m&times;n matrix A may not be square, the solution X is
+     * such that ||A &times; X - B|| is minimal.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B in least square sense.
+     * <p>The m&times;n matrix A may not be square, the solution X is
+     * such that ||A &times; X - B|| is minimal.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; 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 &times; X = B in least square sense.
+     * <p>The m&times;n matrix A may not be square, the solution X is
+     * such that ||A &times; X - B|| is minimal.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a matrix X that minimizes the two norm of A &times; 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