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 2009/06/26 20:27:58 UTC

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

Author: luc
Date: Fri Jun 26 18:27:57 2009
New Revision: 788805

URL: http://svn.apache.org/viewvc?rev=788805&view=rev
Log:
Added a getCovariance method to singular value decomposition

Modified:
    commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
    commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java
    commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java?rev=788805&r1=788804&r2=788805&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java Fri Jun 26 18:27:57 2009
@@ -383,6 +383,10 @@
     { "matrix is singular",
       "matrice singuli\u00e8re" },
 
+    // org.apache.commons.math.linear.decomposition.SingularValueDecompositionImpl
+    { "cutoff singular value is {0}, should be at most {1}",
+      "la valeur singuli\u00e8re de coupure vaut {0}, elle ne devrait pas d\u00e9passer {1}" },
+
     // org.apache.commons.math.linear.decomposition.CholeskyDecompositionImpl
     // org.apache.commons.math.linear.decomposition.EigenDecompositionImpl
     // org.apache.commons.math.linear.decomposition.LUDecompositionImpl

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java?rev=788805&r1=788804&r2=788805&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java Fri Jun 26 18:27:57 2009
@@ -39,7 +39,8 @@
  *   getRank},</li>
  *   <li>a {@link #getUT() getUT} method has been added,</li>
  *   <li>a {@link #getVT() getVT} method has been added,</li>
- *   <li>a {@link #getSolver() getSolver} method has been added.</li>
+ *   <li>a {@link #getSolver() getSolver} method has been added,</li>
+ *   <li>a {@link #getCovariance(double) getCovariance} method has been added.</li>
  * </ul>
  * @see <a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">MathWorld</a>
  * @see <a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">Wikipedia</a>
@@ -97,6 +98,19 @@
     RealMatrix getVT();
 
     /**
+     * Returns the n &times; n covariance matrix.
+     * <p>The covariance matrix is V &times; J &times; V<sup>T</sup>
+     * where J is the diagonal matrix of the inverse of the squares of
+     * the singular values.</p>
+     * @param minSingularValue value below which singular values are ignored
+     * (a 0 or negative value implies all singular value will be used)
+     * @return covariance matrix
+     * @exception IllegalArgumentException if minSingularValue is larger than
+     * the largest singular value, meaning all singular values are ignored
+     */
+    RealMatrix getCovariance(double minSingularValue) throws IllegalArgumentException;
+
+    /**
      * Returns the L<sub>2</sub> norm of the matrix.
      * <p>The L<sub>2</sub> norm is max(|A &times; u|<sub>2</sub> /
      * |u|<sub>2</sub>), where |.|<sub>2</sub> denotes the vectorial 2-norm

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java?rev=788805&r1=788804&r2=788805&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java Fri Jun 26 18:27:57 2009
@@ -257,6 +257,35 @@
     }
 
     /** {@inheritDoc} */
+    public RealMatrix getCovariance(final double minSingularValue) {
+
+        // get the number of singular values to consider
+        int dimension = 0;
+        while ((dimension < n) && (singularValues[dimension] >= minSingularValue)) {
+            ++dimension;
+        }
+
+        if (dimension == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  "cutoff singular value is {0}, should be at most {1}",
+                  minSingularValue, singularValues[0]);
+        }
+
+        final double[][] data = new double[dimension][n];
+        getVT().walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
+            /** {@inheritDoc} */
+            @Override
+            public void visit(final int row, final int column, final double value) {
+                data[row][column] = value / singularValues[row];
+            }
+        }, 0, dimension - 1, 0, n - 1);
+
+        RealMatrix jv = new Array2DRowRealMatrix(data, false);
+        return jv.transpose().multiply(jv);
+
+    }
+
+    /** {@inheritDoc} */
     public double getNorm()
         throws InvalidMatrixException {
         return singularValues[0];

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=788805&r1=788804&r2=788805&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Fri Jun 26 18:27:57 2009
@@ -39,6 +39,9 @@
   </properties>
   <body>
     <release version="2.0" date="TBD" description="TBD">
+      <action dev="luc" type="add" due-to="Dimitri Pourbaix">
+        Added a getCovariance method to singular value decomposition
+      </action>
       <action dev="luc" type="add" issue="MATH-278" due-to="Eugene Kirpichov">
         Added robust locally weighted regression (Loess).
       </action>

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java?rev=788805&r1=788804&r2=788805&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/linear/SingularValueDecompositionImplTest.java Fri Jun 26 18:27:57 2009
@@ -97,6 +97,42 @@
 
     }
 
+    /** Test based on a dimension 4 Hadamard matrix. */
+    public void testHadamard() {
+        RealMatrix matrix = new Array2DRowRealMatrix(new double[][] {
+                {15.0 / 2.0,  5.0 / 2.0,  9.0 / 2.0,  3.0 / 2.0 },
+                { 5.0 / 2.0, 15.0 / 2.0,  3.0 / 2.0,  9.0 / 2.0 },
+                { 9.0 / 2.0,  3.0 / 2.0, 15.0 / 2.0,  5.0 / 2.0 },
+                { 3.0 / 2.0,  9.0 / 2.0,  5.0 / 2.0, 15.0 / 2.0 }
+        }, false);
+        SingularValueDecomposition svd = new SingularValueDecompositionImpl(matrix);
+        assertEquals(16.0, svd.getSingularValues()[0], 1.0e-14);
+        assertEquals( 8.0, svd.getSingularValues()[1], 1.0e-14);
+        assertEquals( 4.0, svd.getSingularValues()[2], 1.0e-14);
+        assertEquals( 2.0, svd.getSingularValues()[3], 1.0e-14);
+
+        RealMatrix fullCovariance = new Array2DRowRealMatrix(new double[][] {
+                {  85.0 / 1024, -51.0 / 1024, -75.0 / 1024,  45.0 / 1024 },
+                { -51.0 / 1024,  85.0 / 1024,  45.0 / 1024, -75.0 / 1024 },
+                { -75.0 / 1024,  45.0 / 1024,  85.0 / 1024, -51.0 / 1024 },
+                {  45.0 / 1024, -75.0 / 1024, -51.0 / 1024,  85.0 / 1024 }
+        }, false);
+        assertEquals(0.0,
+                     fullCovariance.subtract(svd.getCovariance(0.0)).getNorm(),
+                     1.0e-14);
+
+        RealMatrix halfCovariance = new Array2DRowRealMatrix(new double[][] {
+                {   5.0 / 1024,  -3.0 / 1024,   5.0 / 1024,  -3.0 / 1024 },
+                {  -3.0 / 1024,   5.0 / 1024,  -3.0 / 1024,   5.0 / 1024 },
+                {   5.0 / 1024,  -3.0 / 1024,   5.0 / 1024,  -3.0 / 1024 },
+                {  -3.0 / 1024,   5.0 / 1024,  -3.0 / 1024,   5.0 / 1024 }
+        }, false);
+        assertEquals(0.0,
+                     halfCovariance.subtract(svd.getCovariance(6.0)).getNorm(),
+                     1.0e-14);
+
+    }
+
     /** test A = USVt */
     public void testAEqualUSVt() {
         checkAEqualUSVt(MatrixUtils.createRealMatrix(testSquare));