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 2011/04/29 10:48:39 UTC

svn commit: r1097730 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/linear/ site/xdoc/ test/java/org/apache/commons/math/linear/

Author: luc
Date: Fri Apr 29 08:48:38 2011
New Revision: 1097730

URL: http://svn.apache.org/viewvc?rev=1097730&view=rev
Log:
Added solve methods using double[][] to linear algebra decomposition solvers.

JIRA: MATH-564

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/CholeskySolverTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenSolverTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/LUSolverTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/QRSolverTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SingularValueSolverTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java Fri Apr 29 08:48:38 2011
@@ -273,15 +273,34 @@ public class CholeskyDecompositionImpl i
             return new ArrayRealVector(solve(b.getDataRef()), false);
         }
 
-        /** {@inheritDoc} */
-        public RealMatrix solve(RealMatrix b) {
+        /** 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 &times; X = B
+         * @param reUseB if true, the b array will be reused and returned,
+         * instead of being copied
+         * @return a matrix X that minimizes the two norm of A &times; X - B
+         * @throws org.apache.commons.math.exception.DimensionMismatchException
+         * if the matrices dimensions do not match.
+         * @throws SingularMatrixException
+         * if the decomposed matrix is singular.
+         */
+        private double[][] solve(double[][] b, boolean reUseB) {
             final int m = lTData.length;
-            if (b.getRowDimension() != m) {
-                throw new DimensionMismatchException(b.getRowDimension(), m);
+            if (b.length != m) {
+                throw new DimensionMismatchException(b.length, m);
             }
 
-            final int nColB = b.getColumnDimension();
-            double[][] x = b.getData();
+            final int nColB = b[0].length;
+            final double[][] x;
+            if (reUseB) {
+                x = b;
+            } else {
+                x = new double[b.length][nColB];
+                for (int i = 0; i < b.length; ++i) {
+                    System.arraycopy(b[i], 0, x[i], 0, nColB);
+                }
+            }
 
             // Solve LY = b
             for (int j = 0; j < m; j++) {
@@ -316,8 +335,18 @@ public class CholeskyDecompositionImpl i
                 }
             }
 
-            return new Array2DRowRealMatrix(x, false);
+            return x;
+
+        }
 
+        /** {@inheritDoc} */
+        public double[][] solve(double[][] b) {
+            return solve(b, false);
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix solve(RealMatrix b) {
+            return new Array2DRowRealMatrix(solve(b.getData(), true), false);
         }
 
         /** {@inheritDoc} */

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java Fri Apr 29 08:48:38 2011
@@ -69,6 +69,18 @@ public interface DecompositionSolver {
      * @throws SingularMatrixException
      * if the decomposed matrix is singular.
      */
+    double[][] solve(final double[][] b);
+
+    /** 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
+     * @return a matrix X that minimizes the two norm of A &times; X - B
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if the matrices dimensions do not match.
+     * @throws SingularMatrixException
+     * if the decomposed matrix is singular.
+     */
     RealMatrix solve(final RealMatrix b);
 
     /**

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java Fri Apr 29 08:48:38 2011
@@ -338,37 +338,48 @@ public class EigenDecompositionImpl impl
             return new ArrayRealVector(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
-         * @throws DimensionMismatchException if the matrices dimensions do not match.
-         * @throws SingularMatrixException if the decomposed matrix is singular.
+        /** 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 reUseB if true, the b array will be reused and returned,
+         * instead of being copied
+         * @return a matrix X that minimizes the two norm of A &times; X - B
+         * @throws org.apache.commons.math.exception.DimensionMismatchException
+         * if the matrices dimensions do not match.
+         * @throws SingularMatrixException
+         * if the decomposed matrix is singular.
          */
-        public RealMatrix solve(final RealMatrix b) {
+        private double[][] solve(double[][] b, boolean reUseB) {
 
             if (!isNonSingular()) {
                 throw new SingularMatrixException();
             }
 
             final int m = realEigenvalues.length;
-            if (b.getRowDimension() != m) {
-                throw new DimensionMismatchException(b.getRowDimension(), m);
+            if (b.length != m) {
+                throw new DimensionMismatchException(b.length, m);
             }
 
-            final int nColB = b.getColumnDimension();
-            final double[][] bp = new double[m][nColB];
+            final int nColB = b[0].length;
+            final double[][] bp;
+            if (reUseB) {
+                bp = b;
+            } else {
+                bp = new double[m][nColB];
+            }
+            final double[] tmpCol = new double[m];
             for (int k = 0; k < nColB; ++k) {
                 for (int i = 0; i < m; ++i) {
+                    tmpCol[i] = b[i][k];
+                    bp[i][k]  = 0;
+                }
+                for (int i = 0; i < m; ++i) {
                     final ArrayRealVector v = eigenvectors[i];
                     final double[] vData = v.getDataRef();
                     double s = 0;
                     for (int j = 0; j < m; ++j) {
-                        s += v.getEntry(j) * b.getEntry(j, k);
+                        s += v.getEntry(j) * tmpCol[j];
                     }
                     s /= realEigenvalues[i];
                     for (int j = 0; j < m; ++j) {
@@ -377,8 +388,18 @@ public class EigenDecompositionImpl impl
                 }
             }
 
-            return MatrixUtils.createRealMatrix(bp);
+            return bp;
+
+        }
+
+        /** {@inheritDoc} */
+        public double[][] solve(double[][] b) {
+            return solve(b, false);
+        }
 
+        /** {@inheritDoc} */
+        public RealMatrix solve(RealMatrix b) {
+            return new Array2DRowRealMatrix(solve(b.getData(), true), false);
         }
 
         /**

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java Fri Apr 29 08:48:38 2011
@@ -337,17 +337,17 @@ public class LUDecompositionImpl impleme
         }
 
         /** {@inheritDoc} */
-        public RealMatrix solve(RealMatrix b) {
+        public double[][] solve(double[][] b) {
 
             final int m = pivot.length;
-            if (b.getRowDimension() != m) {
-                throw new DimensionMismatchException(b.getRowDimension(), m);
+            if (b.length != m) {
+                throw new DimensionMismatchException(b.length, m);
             }
             if (singular) {
                 throw new SingularMatrixException();
             }
 
-            final int nColB = b.getColumnDimension();
+            final int nColB = b[0].length;
 
             // Apply permutations to b
             final double[][] bp = new double[m][nColB];
@@ -355,7 +355,7 @@ public class LUDecompositionImpl impleme
                 final double[] bpRow = bp[row];
                 final int pRow = pivot[row];
                 for (int col = 0; col < nColB; col++) {
-                    bpRow[col] = b.getEntry(pRow, col);
+                    bpRow[col] = b[pRow][col];
                 }
             }
 
@@ -387,7 +387,13 @@ public class LUDecompositionImpl impleme
                 }
             }
 
-            return new Array2DRowRealMatrix(bp, false);
+            return bp;
+
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix solve(RealMatrix b) {
+            return new Array2DRowRealMatrix(solve(b.getData()), false);
         }
 
         /** {@inheritDoc} */

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java Fri Apr 29 08:48:38 2011
@@ -338,6 +338,11 @@ public class QRDecompositionImpl impleme
         }
 
         /** {@inheritDoc} */
+        public double[][] solve(double[][] b) {
+            return solve(new BlockRealMatrix(b)).getData();
+        }
+
+        /** {@inheritDoc} */
         public RealMatrix solve(RealMatrix b) {
             final int n = qrt.length;
             final int m = qrt[0].length;

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java Fri Apr 29 08:48:38 2011
@@ -313,6 +313,22 @@ public class SingularValueDecompositionI
          * @throws org.apache.commons.math.exception.DimensionMismatchException
          * if the matrices dimensions do not match.
          */
+        public double[][] solve(final double[][] b) {
+            return pseudoInverse.multiply(MatrixUtils.createRealMatrix(b)).getData();
+        }
+
+        /**
+         * 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
+         * @throws org.apache.commons.math.exception.DimensionMismatchException
+         * if the matrices dimensions do not match.
+         */
         public RealMatrix solve(final RealMatrix b) {
             return pseudoInverse.multiply(b);
         }

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Fri Apr 29 08:48:38 2011
@@ -52,6 +52,9 @@ The <action> type attribute can be add,u
     If the output is not quite correct, check for invisible trailing spaces!
      -->
     <release version="3.0" date="TBD" description="TBD">
+      <action dev="luc" type="add" issue="MATH-564">
+        Added solve methods using double[][] to linear algebra decomposition solvers.
+      </action>
       <action dev="erans" type="add" issue="MATH-562">
         Added an interpolator adapter for data with known period.
       </action>

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/CholeskySolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/CholeskySolverTest.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/CholeskySolverTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/CholeskySolverTest.java Fri Apr 29 08:48:38 2011
@@ -81,6 +81,9 @@ public class CholeskySolverTest {
         // using RealMatrix
         Assert.assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 1.0e-13);
 
+        // using double[][]
+        Assert.assertEquals(0, MatrixUtils.createRealMatrix(solver.solve(b.getData())).subtract(xRef).getNorm(), 1.0e-13);
+
         // using double[]
         for (int i = 0; i < b.getColumnDimension(); ++i) {
             Assert.assertEquals(0,

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenSolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenSolverTest.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenSolverTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/EigenSolverTest.java Fri Apr 29 08:48:38 2011
@@ -120,6 +120,10 @@ public class EigenSolverTest {
         RealMatrix solution=es.solve(b);
         Assert.assertEquals(0, solution.subtract(xRef).getNorm(), 2.5e-12);
 
+        // using double[][]
+        solution = MatrixUtils.createRealMatrix(es.solve(b.getData()));
+        Assert.assertEquals(0, solution.subtract(xRef).getNorm(), 2.5e-12);
+
         // using double[]
         for (int i = 0; i < b.getColumnDimension(); ++i) {
             Assert.assertEquals(0,

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/LUSolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/LUSolverTest.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/LUSolverTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/LUSolverTest.java Fri Apr 29 08:48:38 2011
@@ -143,6 +143,9 @@ public class LUSolverTest {
         // using RealMatrix
         Assert.assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 1.0e-13);
 
+        // using double[][]
+        Assert.assertEquals(0, MatrixUtils.createRealMatrix(solver.solve(b.getData())).subtract(xRef).getNorm(), 1.0e-13);
+
         // using double[]
         for (int i = 0; i < b.getColumnDimension(); ++i) {
             Assert.assertEquals(0,

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/QRSolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/QRSolverTest.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/QRSolverTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/QRSolverTest.java Fri Apr 29 08:48:38 2011
@@ -137,6 +137,9 @@ public class QRSolverTest {
         // using RealMatrix
         Assert.assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 2.0e-16 * xRef.getNorm());
 
+        // using double[][]
+        Assert.assertEquals(0, MatrixUtils.createRealMatrix(solver.solve(b.getData())).subtract(xRef).getNorm(), 2.0e-16 * xRef.getNorm());
+
         // using double[]
         for (int i = 0; i < b.getColumnDimension(); ++i) {
             final double[] x = solver.solve(b.getColumn(i));

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SingularValueSolverTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SingularValueSolverTest.java?rev=1097730&r1=1097729&r2=1097730&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SingularValueSolverTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/linear/SingularValueSolverTest.java Fri Apr 29 08:48:38 2011
@@ -101,6 +101,9 @@ public class SingularValueSolverTest {
         // using RealMatrix
         Assert.assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), normTolerance);
 
+        // using double[][]
+        Assert.assertEquals(0, MatrixUtils.createRealMatrix(solver.solve(b.getData())).subtract(xRef).getNorm(), normTolerance);
+
         // using double[]
         for (int i = 0; i < b.getColumnDimension(); ++i) {
             Assert.assertEquals(0,