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

numpy-svn@scip... numpy-svn@scip...
Tue Apr 8 13:49:23 CDT 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)

```