summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/linalg/linalg.py38
-rw-r--r--numpy/linalg/tests/test_linalg.py17
2 files changed, 54 insertions, 1 deletions
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index c4575e377..1706ff4a9 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -16,6 +16,7 @@ __all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv',
'det', 'svd',
'eig', 'eigh','lstsq', 'norm',
'qr',
+ 'cond',
'LinAlgError'
]
@@ -968,6 +969,43 @@ def svd(a, full_matrices=1, compute_uv=1):
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 ):
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index 5321ae7c5..7d2390980 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -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 @@ class TestSVD(LinalgTestCase):
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)