summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/linalg/tests/test_linalg.py555
1 files changed, 332 insertions, 223 deletions
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index 2c003a072..aeeedadf9 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -5,6 +5,8 @@ from __future__ import division, absolute_import, print_function
import os
import sys
+import itertools
+import traceback
import numpy as np
from numpy import array, single, double, csingle, cdouble, dot, identity
@@ -12,8 +14,9 @@ from numpy import multiply, atleast_2d, inf, asarray, matrix
from numpy import linalg
from numpy.linalg import matrix_power, norm, matrix_rank
from numpy.testing import (
- TestCase, assert_, assert_equal, assert_raises, assert_array_equal,
- assert_almost_equal, run_module_suite, dec
+ assert_, assert_equal, assert_raises, assert_array_equal,
+ assert_almost_equal, assert_allclose, run_module_suite,
+ dec
)
@@ -45,162 +48,287 @@ def get_complex_dtype(dtype):
return {single: csingle, double: cdouble,
csingle: csingle, cdouble: cdouble}[dtype]
+def get_rtol(dtype):
+ return 0.1 * np.sqrt(np.finfo(dtype).eps)
-class LinalgTestCase(object):
- def test_single(self):
- a = array([[1., 2.], [3., 4.]], dtype=single)
- b = array([2., 1.], dtype=single)
- self.do(a, b)
-
- def test_double(self):
- a = array([[1., 2.], [3., 4.]], dtype=double)
- b = array([2., 1.], dtype=double)
- self.do(a, b)
-
- def test_double_2(self):
- a = array([[1., 2.], [3., 4.]], dtype=double)
- b = array([[2., 1., 4.], [3., 4., 6.]], dtype=double)
- self.do(a, b)
-
- def test_csingle(self):
- a = array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=csingle)
- b = array([2.+1j, 1.+2j], dtype=csingle)
- self.do(a, b)
-
- def test_cdouble(self):
- a = array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=cdouble)
- b = array([2.+1j, 1.+2j], dtype=cdouble)
- self.do(a, b)
-
- def test_cdouble_2(self):
- a = array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=cdouble)
- b = array([[2.+1j, 1.+2j, 1+3j], [1-2j, 1-3j, 1-6j]], dtype=cdouble)
- self.do(a, b)
+class LinalgCase(object):
+ def __init__(self, name, a, b, exception_cls=None):
+ assert isinstance(name, str)
+ self.name = name
+ self.a = a
+ self.b = b
+ self.exception_cls = exception_cls
- def test_empty(self):
- a = atleast_2d(array([], dtype = double))
- b = atleast_2d(array([], dtype = double))
+ def check(self, do):
+ if self.exception_cls is None:
+ do(self.a, self.b)
+ else:
+ assert_raises(self.exception_cls, do, self.a, self.b)
+
+ def __repr__(self):
+ return "<LinalgCase: %s>" % (self.name,)
+
+
+#
+# Base test cases
+#
+
+SQUARE_CASES = [
+ LinalgCase("single",
+ array([[1., 2.], [3., 4.]], dtype=single),
+ array([2., 1.], dtype=single)),
+ LinalgCase("double",
+ array([[1., 2.], [3., 4.]], dtype=double),
+ array([2., 1.], dtype=double)),
+ LinalgCase("double_2",
+ array([[1., 2.], [3., 4.]], dtype=double),
+ array([[2., 1., 4.], [3., 4., 6.]], dtype=double)),
+ LinalgCase("csingle",
+ array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=csingle),
+ array([2.+1j, 1.+2j], dtype=csingle)),
+ LinalgCase("cdouble",
+ array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=cdouble),
+ array([2.+1j, 1.+2j], dtype=cdouble)),
+ LinalgCase("cdouble_2",
+ array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=cdouble),
+ array([[2.+1j, 1.+2j, 1+3j], [1-2j, 1-3j, 1-6j]], dtype=cdouble)),
+ LinalgCase("empty",
+ atleast_2d(array([], dtype = double)),
+ atleast_2d(array([], dtype = double)),
+ linalg.LinAlgError),
+ LinalgCase("nonarray",
+ [[1, 2], [3, 4]],
+ [2, 1]),
+ LinalgCase("matrix_b_only",
+ array([[1., 2.], [3., 4.]]),
+ matrix([2., 1.]).T),
+ LinalgCase("matrix_a_and_b",
+ matrix([[1., 2.], [3., 4.]]),
+ matrix([2., 1.]).T),
+]
+
+NONSQUARE_CASES = [
+ LinalgCase("single_nsq_1",
+ array([[1., 2., 3.], [3., 4., 6.]], dtype=single),
+ array([2., 1.], dtype=single)),
+ LinalgCase("single_nsq_2",
+ array([[1., 2.], [3., 4.], [5., 6.]], dtype=single),
+ array([2., 1., 3.], dtype=single)),
+ LinalgCase("double_nsq_1",
+ array([[1., 2., 3.], [3., 4., 6.]], dtype=double),
+ array([2., 1.], dtype=double)),
+ LinalgCase("double_nsq_2",
+ array([[1., 2.], [3., 4.], [5., 6.]], dtype=double),
+ array([2., 1., 3.], dtype=double)),
+ LinalgCase("csingle_nsq_1",
+ array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=csingle),
+ array([2.+1j, 1.+2j], dtype=csingle)),
+ LinalgCase("csingle_nsq_2",
+ array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=csingle),
+ array([2.+1j, 1.+2j, 3.-3j], dtype=csingle)),
+ LinalgCase("cdouble_nsq_1",
+ array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=cdouble),
+ array([2.+1j, 1.+2j], dtype=cdouble)),
+ LinalgCase("cdouble_nsq_2",
+ array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=cdouble),
+ array([2.+1j, 1.+2j, 3.-3j], dtype=cdouble)),
+ LinalgCase("cdouble_nsq_1_2",
+ array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=cdouble),
+ array([[2.+1j, 1.+2j], [1-1j, 2-2j]], dtype=cdouble)),
+ LinalgCase("cdouble_nsq_2_2",
+ array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=cdouble),
+ array([[2.+1j, 1.+2j], [1-1j, 2-2j], [1-1j, 2-2j]], dtype=cdouble)),
+]
+
+HERMITIAN_CASES = [
+ LinalgCase("hsingle",
+ array([[1., 2.], [2., 1.]], dtype=single),
+ None),
+ LinalgCase("hdouble",
+ array([[1., 2.], [2., 1.]], dtype=double),
+ None),
+ LinalgCase("hcsingle",
+ array([[1., 2+3j], [2-3j, 1]], dtype=csingle),
+ None),
+ LinalgCase("hcdouble",
+ array([[1., 2+3j], [2-3j, 1]], dtype=cdouble),
+ None),
+ LinalgCase("hempty",
+ atleast_2d(array([], dtype = double)),
+ None,
+ linalg.LinAlgError),
+ LinalgCase("hnonarray",
+ [[1, 2], [2, 1]],
+ None),
+ LinalgCase("matrix_b_only",
+ array([[1., 2.], [2., 1.]]),
+ None),
+ LinalgCase("hmatrix_a_and_b",
+ matrix([[1., 2.], [2., 1.]]),
+ None)
+]
+
+
+#
+# Gufunc test cases
+#
+
+GENERALIZED_SQUARE_CASES = []
+GENERALIZED_NONSQUARE_CASES = []
+GENERALIZED_HERMITIAN_CASES = []
+
+for tgt, src in ((GENERALIZED_SQUARE_CASES, SQUARE_CASES),
+ (GENERALIZED_NONSQUARE_CASES, NONSQUARE_CASES),
+ (GENERALIZED_HERMITIAN_CASES, HERMITIAN_CASES)):
+ for case in src:
+ if not isinstance(case.a, np.ndarray):
+ continue
+
+ a = np.array([case.a, 2*case.a, 3*case.a])
+ if case.b is None:
+ b = None
+ else:
+ b = np.array([case.b, 7*case.b, 6*case.b])
+ new_case = LinalgCase(case.name + "_tile3", a, b,
+ case.exception_cls)
+ tgt.append(new_case)
+
+ a = np.array([case.a]*2*3).reshape((3, 2) + case.a.shape)
+ if case.b is None:
+ b = None
+ else:
+ b = np.array([case.b]*2*3).reshape((3, 2) + case.b.shape)
+ new_case = LinalgCase(case.name + "_tile213", a, b,
+ case.exception_cls)
+ tgt.append(new_case)
+
+#
+# Generate stride combination variations of the above
+#
+
+def _stride_comb_iter(x):
+ """
+ Generate cartesian product of strides for all axes
+ """
+
+ if not isinstance(x, np.ndarray):
+ yield x, "nop"
+ return
+
+ stride_set = [(1,)]*x.ndim
+ stride_set[-1] = (1, 3, -4)
+ if x.ndim > 1:
+ stride_set[-2] = (1, 3, -4)
+ if x.ndim > 2:
+ stride_set[-3] = (1, -4)
+
+ for repeats in itertools.product(*tuple(stride_set)):
+ new_shape = [abs(a*b) for a, b in zip(x.shape, repeats)]
+ slices = tuple([slice(None, None, repeat) for repeat in repeats])
+
+ # new array with different strides, but same data
+ xi = np.empty(new_shape, dtype=x.dtype)
+ xi.view(np.uint32).fill(0xdeadbeef)
+ xi = xi[slices]
+ xi[...] = x
+ xi = xi.view(x.__class__)
+ assert np.all(xi == x)
+ yield xi, "stride_" + "_".join(["%+d" % j for j in repeats])
+
+for src in (SQUARE_CASES,
+ NONSQUARE_CASES,
+ HERMITIAN_CASES,
+ GENERALIZED_SQUARE_CASES,
+ GENERALIZED_NONSQUARE_CASES,
+ GENERALIZED_HERMITIAN_CASES):
+
+ new_cases = []
+ for case in src:
+ for a, a_tag in _stride_comb_iter(case.a):
+ for b, b_tag in _stride_comb_iter(case.b):
+ new_case = LinalgCase(case.name + "_" + a_tag + "_" + b_tag, a, b,
+ exception_cls=case.exception_cls)
+ new_cases.append(new_case)
+ src.extend(new_cases)
+
+
+#
+# Test different routines against the above cases
+#
+
+def _check_cases(func, cases):
+ for case in cases:
try:
- self.do(a, b)
- raise AssertionError("%s should fail with empty matrices", self.__name__[5:])
- except linalg.LinAlgError as e:
- pass
+ case.check(func)
+ except:
+ msg = "In test case: %r\n\n" % case
+ msg += traceback.format_exc()
+ raise AssertionError(msg)
- def test_nonarray(self):
- a = [[1, 2], [3, 4]]
- b = [2, 1]
- self.do(a, b)
+class LinalgTestCase(object):
+ def test_sq_cases(self):
+ _check_cases(self.do, SQUARE_CASES)
- def test_matrix_b_only(self):
- """Check that matrix type is preserved."""
- a = array([[1., 2.], [3., 4.]])
- b = matrix([2., 1.]).T
- self.do(a, b)
- def test_matrix_a_and_b(self):
- """Check that matrix type is preserved."""
- a = matrix([[1., 2.], [3., 4.]])
- b = matrix([2., 1.]).T
- self.do(a, b)
+class LinalgNonsquareTestCase(object):
+ def test_sq_cases(self):
+ _check_cases(self.do, NONSQUARE_CASES)
-class LinalgNonsquareTestCase(object):
- def test_single_nsq_1(self):
- a = array([[1., 2., 3.], [3., 4., 6.]], dtype=single)
- b = array([2., 1.], dtype=single)
- self.do(a, b)
-
- def test_single_nsq_2(self):
- a = array([[1., 2.], [3., 4.], [5., 6.]], dtype=single)
- b = array([2., 1., 3.], dtype=single)
- self.do(a, b)
-
- def test_double_nsq_1(self):
- a = array([[1., 2., 3.], [3., 4., 6.]], dtype=double)
- b = array([2., 1.], dtype=double)
- self.do(a, b)
-
- def test_double_nsq_2(self):
- a = array([[1., 2.], [3., 4.], [5., 6.]], dtype=double)
- b = array([2., 1., 3.], dtype=double)
- self.do(a, b)
-
- def test_csingle_nsq_1(self):
- a = array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=csingle)
- b = array([2.+1j, 1.+2j], dtype=csingle)
- self.do(a, b)
-
- def test_csingle_nsq_2(self):
- a = array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=csingle)
- b = array([2.+1j, 1.+2j, 3.-3j], dtype=csingle)
- self.do(a, b)
-
- def test_cdouble_nsq_1(self):
- a = array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=cdouble)
- b = array([2.+1j, 1.+2j], dtype=cdouble)
- self.do(a, b)
-
- def test_cdouble_nsq_2(self):
- a = array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=cdouble)
- b = array([2.+1j, 1.+2j, 3.-3j], dtype=cdouble)
- self.do(a, b)
-
- def test_cdouble_nsq_1_2(self):
- a = array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=cdouble)
- b = array([[2.+1j, 1.+2j], [1-1j, 2-2j]], dtype=cdouble)
- self.do(a, b)
-
- def test_cdouble_nsq_2_2(self):
- a = array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=cdouble)
- b = array([[2.+1j, 1.+2j], [1-1j, 2-2j], [1-1j, 2-2j]], dtype=cdouble)
- self.do(a, b)
-
-
-def _generalized_testcase(new_cls_name, old_cls):
- def get_method(old_name, new_name):
- def method(self):
- base = old_cls()
- def do(a, b):
- a = np.array([a, a, a])
- b = np.array([b, b, b])
- self.do(a, b)
- base.do = do
- getattr(base, old_name)()
- method.__name__ = new_name
- return method
-
- dct = dict()
- for old_name in dir(old_cls):
- if old_name.startswith('test_'):
- new_name = old_name + '_generalized'
- dct[new_name] = get_method(old_name, new_name)
-
- return type(new_cls_name, (object,), dct)
-
-LinalgGeneralizedTestCase = _generalized_testcase(
- 'LinalgGeneralizedTestCase', LinalgTestCase)
-LinalgGeneralizedNonsquareTestCase = _generalized_testcase(
- 'LinalgGeneralizedNonsquareTestCase', LinalgNonsquareTestCase)
+class LinalgGeneralizedTestCase(object):
+ @dec.slow
+ def test_generalized_sq_cases(self):
+ _check_cases(self.do, GENERALIZED_SQUARE_CASES)
+
+
+class LinalgGeneralizedNonsquareTestCase(object):
+ @dec.slow
+ def test_generalized_nonsq_cases(self):
+ _check_cases(self.do, GENERALIZED_NONSQUARE_CASES)
+
+
+class HermitianTestCase(object):
+ def test_herm_cases(self):
+ _check_cases(self.do, HERMITIAN_CASES)
+
+
+class HermitianGeneralizedTestCase(object):
+ @dec.slow
+ def test_generalized_herm_cases(self):
+ _check_cases(self.do, GENERALIZED_HERMITIAN_CASES)
def dot_generalized(a, b):
a = asarray(a)
- if a.ndim == 3:
- return np.array([dot(ax, bx) for ax, bx in zip(a, b)])
- elif a.ndim > 3:
- raise ValueError("Not implemented...")
- return dot(a, b)
+ if a.ndim >= 3:
+ if a.ndim == b.ndim:
+ # matrix x matrix
+ new_shape = a.shape[:-1] + b.shape[-1:]
+ elif a.ndim == b.ndim + 1:
+ # matrix x vector
+ new_shape = a.shape[:-1]
+ else:
+ raise ValueError("Not implemented...")
+ r = np.empty(new_shape, dtype=np.common_type(a, b))
+ for c in itertools.product(*map(range, a.shape[:-2])):
+ r[c] = dot(a[c], b[c])
+ return r
+ else:
+ return dot(a, b)
+
def identity_like_generalized(a):
a = asarray(a)
- if a.ndim == 3:
- return np.array([identity(a.shape[-2]) for ax in a])
- elif a.ndim > 3:
- raise ValueError("Not implemented...")
- return identity(a.shape[0])
+ if a.ndim >= 3:
+ r = np.empty(a.shape, dtype=a.dtype)
+ for c in itertools.product(*map(range, a.shape[:-2])):
+ r[c] = identity(a.shape[-2])
+ return r
+ else:
+ return identity(a.shape[0])
-class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
x = linalg.solve(a, b)
assert_almost_equal(b, dot_generalized(a, x))
@@ -265,7 +393,7 @@ class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
assert_(isinstance(result, ArraySubclass))
-class TestInv(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestInv(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
a_inv = linalg.inv(a)
assert_almost_equal(dot_generalized(a, a_inv),
@@ -295,7 +423,7 @@ class TestInv(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
assert_equal(a.shape, res.shape)
-class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
ev = linalg.eigvals(a)
evalues, evectors = linalg.eig(a)
@@ -311,13 +439,12 @@ class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
yield check, dtype
-class TestEig(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestEig(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
evalues, evectors = linalg.eig(a)
- if evectors.ndim == 3:
- assert_almost_equal(dot_generalized(a, evectors), evectors * evalues[:, None,:])
- else:
- assert_almost_equal(dot(a, evectors), multiply(evectors, evalues))
+ assert_allclose(dot_generalized(a, evectors),
+ np.asarray(evectors) * np.asarray(evalues)[...,None,:],
+ rtol=get_rtol(evalues.dtype))
assert_(imply(isinstance(a, matrix), isinstance(evectors, matrix)))
def test_types(self):
@@ -333,16 +460,15 @@ class TestEig(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
assert_equal(v.dtype, get_complex_dtype(dtype))
for dtype in [single, double, csingle, cdouble]:
- yield dtype
+ yield check, dtype
-class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
u, s, vt = linalg.svd(a, 0)
- if u.ndim == 3:
- assert_almost_equal(a, dot_generalized(u * s[:, None,:], vt))
- else:
- assert_almost_equal(a, dot(multiply(u, s), vt))
+ assert_allclose(a, dot_generalized(np.asarray(u) * np.asarray(s)[...,None,:],
+ np.asarray(vt)),
+ rtol=get_rtol(u.dtype))
assert_(imply(isinstance(a, matrix), isinstance(u, matrix)))
assert_(imply(isinstance(a, matrix), isinstance(vt, matrix)))
@@ -360,34 +486,34 @@ class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
yield check, dtype
-class TestCondSVD(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestCondSVD(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
c = asarray(a) # a might be a matrix
s = linalg.svd(c, compute_uv=False)
old_assert_almost_equal(s[0]/s[-1], linalg.cond(a), decimal=5)
-class TestCond2(LinalgTestCase, TestCase):
+class TestCond2(LinalgTestCase):
def do(self, a, b):
c = asarray(a) # a might be a matrix
s = linalg.svd(c, compute_uv=False)
old_assert_almost_equal(s[0]/s[-1], linalg.cond(a, 2), decimal=5)
-class TestCondInf(TestCase):
+class TestCondInf(object):
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, TestCase):
+class TestPinv(LinalgTestCase):
def do(self, a, b):
a_ginv = linalg.pinv(a)
assert_almost_equal(dot(a, a_ginv), identity(asarray(a).shape[0]))
assert_(imply(isinstance(a, matrix), isinstance(a_ginv, matrix)))
-class TestDet(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
+class TestDet(LinalgTestCase, LinalgGeneralizedTestCase):
def do(self, a, b):
d = linalg.det(a)
(s, ld) = linalg.slogdet(a)
@@ -421,12 +547,15 @@ class TestDet(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def test_types(self):
def check(dtype):
x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
- assert_equal(np.linalg.det(x), get_real_dtype(dtype))
+ assert_equal(np.linalg.det(x).dtype, dtype)
+ ph, s = np.linalg.slogdet(x)
+ assert_equal(s.dtype, get_real_dtype(dtype))
+ assert_equal(ph.dtype, dtype)
for dtype in [single, double, csingle, cdouble]:
yield check, dtype
-class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase, TestCase):
+class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase):
def do(self, a, b):
arr = np.asarray(a)
m, n = arr.shape
@@ -506,70 +635,38 @@ class TestMatrixPower(object):
lambda: matrix_power(self.noninv, -1))
-class TestBoolPower(TestCase):
+class TestBoolPower(object):
def test_square(self):
A = array([[True, False], [True, True]])
assert_equal(matrix_power(A, 2), A)
-class HermitianTestCase(object):
- def test_single(self):
- a = array([[1., 2.], [2., 1.]], dtype=single)
- self.do(a, None)
-
- def test_double(self):
- a = array([[1., 2.], [2., 1.]], dtype=double)
- self.do(a, None)
-
- def test_csingle(self):
- a = array([[1., 2+3j], [2-3j, 1]], dtype=csingle)
- self.do(a, None)
-
- def test_cdouble(self):
- a = array([[1., 2+3j], [2-3j, 1]], dtype=cdouble)
- self.do(a, None)
-
- def test_empty(self):
- a = atleast_2d(array([], dtype = double))
- assert_raises(linalg.LinAlgError, self.do, a, None)
-
- def test_nonarray(self):
- a = [[1, 2], [2, 1]]
- self.do(a, None)
-
- def test_matrix_b_only(self):
- """Check that matrix type is preserved."""
- a = array([[1., 2.], [2., 1.]])
- self.do(a, None)
-
- def test_matrix_a_and_b(self):
- """Check that matrix type is preserved."""
- a = matrix([[1., 2.], [2., 1.]])
- self.do(a, None)
-
-
-HermitianGeneralizedTestCase = _generalized_testcase(
- 'HermitianGeneralizedTestCase', HermitianTestCase)
-
-class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase, TestCase):
+class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase):
def do(self, a, b):
# note that eigenvalue arrays must be sorted since
# their order isn't guaranteed.
- ev = linalg.eigvalsh(a)
+ ev = linalg.eigvalsh(a, 'L')
evalues, evectors = linalg.eig(a)
ev.sort(axis=-1)
evalues.sort(axis=-1)
- assert_almost_equal(ev, evalues)
+ assert_allclose(ev, evalues,
+ rtol=get_rtol(ev.dtype))
+
+ ev2 = linalg.eigvalsh(a, 'U')
+ ev2.sort(axis=-1)
+ assert_allclose(ev2, evalues,
+ rtol=get_rtol(ev.dtype))
def test_types(self):
def check(dtype):
x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
- assert_equal(np.linalg.eigvalsh(x), get_real_dtype(dtype))
+ w = np.linalg.eigvalsh(x)
+ assert_equal(w.dtype, get_real_dtype(dtype))
for dtype in [single, double, csingle, cdouble]:
yield check, dtype
-class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase, TestCase):
+class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
def do(self, a, b):
# note that eigenvalue arrays must be sorted since
# their order isn't guaranteed.
@@ -579,17 +676,29 @@ class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase, TestCase):
evalues.sort(axis=-1)
assert_almost_equal(ev, evalues)
+ assert_allclose(dot_generalized(a, evc),
+ np.asarray(ev)[...,None,:] * np.asarray(evc),
+ rtol=get_rtol(ev.dtype))
+
+ ev2, evc2 = linalg.eigh(a, 'U')
+ ev2.sort(axis=-1)
+ assert_almost_equal(ev2, evalues)
+
+ assert_allclose(dot_generalized(a, evc2),
+ np.asarray(ev2)[...,None,:] * np.asarray(evc2),
+ rtol=get_rtol(ev.dtype))
+
def test_types(self):
def check(dtype):
x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
- w, v = np.linalg.eig(x)
- assert_equal(w, get_real_dtype(dtype))
- assert_equal(v, dtype)
+ w, v = np.linalg.eigh(x)
+ assert_equal(w.dtype, get_real_dtype(dtype))
+ assert_equal(v.dtype, dtype)
for dtype in [single, double, csingle, cdouble]:
yield check, dtype
-class _TestNorm(TestCase):
+class _TestNorm(object):
dt = None
dec = None
@@ -640,9 +749,9 @@ class _TestNorm(TestCase):
assert_almost_equal(norm(A, 2), 9.1231056256176615)
assert_almost_equal(norm(A, -2), 0.87689437438234041)
- self.assertRaises(ValueError, norm, A, 'nofro')
- self.assertRaises(ValueError, norm, A, -3)
- self.assertRaises(ValueError, norm, A, 0)
+ assert_raises(ValueError, norm, A, 'nofro')
+ assert_raises(ValueError, norm, A, -3)
+ assert_raises(ValueError, norm, A, 0)
def test_axis(self):
# Vector norms.
@@ -687,20 +796,20 @@ class _TestNorm(TestCase):
# Using `axis=<integer>` or passing in a 1-D array implies vector
# norms are being computed, so also using `ord='fro'` raises a
# ValueError.
- self.assertRaises(ValueError, norm, A, 'fro', 0)
- self.assertRaises(ValueError, norm, [3, 4], 'fro', None)
+ assert_raises(ValueError, norm, A, 'fro', 0)
+ assert_raises(ValueError, norm, [3, 4], 'fro', None)
# Similarly, norm should raise an exception when ord is any finite
# number other than 1, 2, -1 or -2 when computing matrix norms.
for order in [0, 3]:
- self.assertRaises(ValueError, norm, A, order, None)
- self.assertRaises(ValueError, norm, A, order, (0, 1))
- self.assertRaises(ValueError, norm, B, order, (1, 2))
+ assert_raises(ValueError, norm, A, order, None)
+ assert_raises(ValueError, norm, A, order, (0, 1))
+ assert_raises(ValueError, norm, B, order, (1, 2))
# Invalid axis
- self.assertRaises(ValueError, norm, B, None, 3)
- self.assertRaises(ValueError, norm, B, None, (2, 3))
- self.assertRaises(ValueError, norm, B, None, (0, 1, 2))
+ assert_raises(ValueError, norm, B, None, 3)
+ assert_raises(ValueError, norm, B, None, (2, 3))
+ assert_raises(ValueError, norm, B, None, (0, 1, 2))
class TestNormDouble(_TestNorm):
@@ -751,7 +860,7 @@ def test_reduced_rank():
assert_equal(matrix_rank(X), 8)
-class TestQR(TestCase):
+class TestQR(object):
def check_qr(self, a):
# This test expects the argument `a` to be an ndarray or
@@ -793,7 +902,7 @@ class TestQR(TestCase):
def test_qr_empty(self):
a = np.zeros((0, 2))
- self.assertRaises(linalg.LinAlgError, linalg.qr, a)
+ assert_raises(linalg.LinAlgError, linalg.qr, a)
def test_mode_raw(self):
# The factorization is not unique and varies between libraries,