[Numpy-svn] r4989 - in trunk/numpy/linalg: . tests

numpy-svn at scipy.org numpy-svn at scipy.org
Tue Apr 8 14:49:23 EDT 2008


Author: peridot
Date: 2008-04-08 13:49:18 -0500 (Tue, 08 Apr 2008)
New Revision: 4989

Modified:
   trunk/numpy/linalg/linalg.py
   trunk/numpy/linalg/tests/test_linalg.py
Log:
Added function for computing condition number, with tests and docs; closes #622.


Modified: trunk/numpy/linalg/linalg.py
===================================================================
--- trunk/numpy/linalg/linalg.py	2008-04-08 18:04:33 UTC (rev 4988)
+++ trunk/numpy/linalg/linalg.py	2008-04-08 18:49:18 UTC (rev 4989)
@@ -16,6 +16,7 @@
            'det', 'svd',
            'eig', 'eigh','lstsq', 'norm',
            'qr',
+           'cond',
            'LinAlgError'
            ]
 
@@ -968,6 +969,43 @@
     else:
         return s
 
+def cond(x,p=None):
+    """Compute the condition number of a matrix.
+
+    The condition number of x is the norm of x times the norm 
+    of the inverse of x.  The norm can be the usual L2 
+    (root-of-sum-of-squares) norm or a number of other matrix norms.
+
+    Parameters
+    ----------
+    x : array, shape (M, N)
+        The matrix whose condition number is sought.
+    p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}
+        Order of the norm:
+
+        p      norm for matrices           
+        =====  ============================
+        None   2-norm, computed directly using the SVD
+        'fro'  Frobenius norm             
+        inf    max(sum(abs(x), axis=1))   
+        -inf   min(sum(abs(x), axis=1))    
+        1      max(sum(abs(x), axis=0))     
+        -1     min(sum(abs(x), axis=0))     
+        2      2-norm (largest sing. value) 
+        -2     smallest singular value      
+        =====  ============================
+
+    Returns
+    -------
+    c : float
+        The condition number of the matrix. May be infinite.
+    """
+    if p is None:
+        s = svd(x,compute_uv=False)
+        return s[0]/s[-1]
+    else:
+        return norm(x,p)*norm(inv(x),p)
+
 # Generalized inverse
 
 def pinv(a, rcond=1e-15 ):

Modified: trunk/numpy/linalg/tests/test_linalg.py
===================================================================
--- trunk/numpy/linalg/tests/test_linalg.py	2008-04-08 18:04:33 UTC (rev 4988)
+++ trunk/numpy/linalg/tests/test_linalg.py	2008-04-08 18:49:18 UTC (rev 4989)
@@ -4,7 +4,7 @@
 from numpy.testing import *
 set_package_path()
 from numpy import array, single, double, csingle, cdouble, dot, identity, \
-        multiply, atleast_2d
+        multiply, atleast_2d, inf
 from numpy import linalg
 from linalg import matrix_power
 restore_path()
@@ -73,6 +73,21 @@
         u, s, vt = linalg.svd(a, 0)
         assert_almost_equal(a, dot(u*s, vt))
 
+class TestCondSVD(LinalgTestCase):
+    def do(self, a, b):
+        s = linalg.svd(a, compute_uv=False)
+        old_assert_almost_equal(s[0]/s[-1], linalg.cond(a), decimal=5)
+
+class TestCond2(LinalgTestCase):
+    def do(self, a, b):
+        s = linalg.svd(a, compute_uv=False)
+        old_assert_almost_equal(s[0]/s[-1], linalg.cond(a,2), decimal=5)
+
+class TestCondInf(NumpyTestCase):
+    def test(self):
+        A = array([[1.,0,0],[0,-2.,0],[0,0,3.]])
+        assert_almost_equal(linalg.cond(A,inf),3.)
+
 class TestPinv(LinalgTestCase):
     def do(self, a, b):
         a_ginv = linalg.pinv(a)




More information about the Numpy-svn mailing list