summaryrefslogtreecommitdiff
path: root/numpy/linalg/tests
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/linalg/tests')
-rw-r--r--numpy/linalg/tests/test_gufuncs_linalg.py500
-rw-r--r--numpy/linalg/tests/test_linalg.py241
2 files changed, 705 insertions, 36 deletions
diff --git a/numpy/linalg/tests/test_gufuncs_linalg.py b/numpy/linalg/tests/test_gufuncs_linalg.py
new file mode 100644
index 000000000..d3299b7b5
--- /dev/null
+++ b/numpy/linalg/tests/test_gufuncs_linalg.py
@@ -0,0 +1,500 @@
+"""
+Test functions for gufuncs_linalg module
+Heavily inspired (ripped in part) test_linalg
+"""
+from __future__ import division, print_function
+
+################################################################################
+# The following functions are implemented in the module "gufuncs_linalg"
+#
+# category "linalg"
+# - inv (TestInv)
+# - poinv (TestPoinv)
+# - det (TestDet)
+# - slogdet (TestDet)
+# - eig (TestEig)
+# - eigh (TestEigh)
+# - eigvals (TestEigvals)
+# - eigvalsh (TestEigvalsh)
+# - cholesky
+# - solve (TestSolve)
+# - chosolve (TestChosolve)
+# - svd (TestSVD)
+
+# ** unimplemented **
+# - qr
+# - matrix_power
+# - matrix_rank
+# - pinv
+# - lstsq
+# - tensorinv
+# - tensorsolve
+# - norm
+# - cond
+#
+# category "inspired by pdl"
+# - quadratic_form
+# - matrix_multiply3
+# - add3 (TestAdd3)
+# - multiply3 (TestMultiply3)
+# - multiply3_add (TestMultiply3Add)
+# - multiply_add (TestMultiplyAdd)
+# - multiply_add2 (TestMultiplyAdd2)
+# - multiply4 (TestMultiply4)
+# - multiply4_add (TestMultiply4Add)
+#
+# category "others"
+# - convolve
+# - inner1d
+# - innerwt
+# - matrix_multiply
+
+from nose.plugins.skip import Skip, SkipTest
+import numpy as np
+
+from numpy.testing import (TestCase, assert_, assert_equal, assert_raises,
+ assert_array_equal, assert_almost_equal,
+ run_module_suite)
+
+from numpy import array, single, double, csingle, cdouble, dot, identity
+from numpy import multiply, inf
+import numpy.linalg._gufuncs_linalg as gula
+
+old_assert_almost_equal = assert_almost_equal
+
+def assert_almost_equal(a, b, **kw):
+ if a.dtype.type in (single, csingle):
+ decimal = 5
+ else:
+ decimal = 10
+ old_assert_almost_equal(a, b, decimal = decimal, **kw)
+
+
+def assert_valid_eigen_no_broadcast(M, w, v, **kw):
+ lhs = gula.matrix_multiply(M,v)
+ rhs = w*v
+ assert_almost_equal(lhs, rhs, **kw)
+
+
+def assert_valid_eigen_recurse(M, w, v, **kw):
+ """check that w and v are valid eigenvalues/eigenvectors for matrix M
+ broadcast"""
+ if len(M.shape) > 2:
+ for i in range(M.shape[0]):
+ assert_valid_eigen_recurse(M[i], w[i], v[i], **kw)
+ else:
+ if len(M.shape) == 2:
+ assert_valid_eigen_no_broadcast(M, w, v, **kw)
+ else:
+ raise AssertionError('Not enough dimensions')
+
+
+def assert_valid_eigen(M, w, v, **kw):
+ if np.any(np.isnan(M)):
+ raise AssertionError('nan found in matrix')
+ if np.any(np.isnan(w)):
+ raise AssertionError('nan found in eigenvalues')
+ if np.any(np.isnan(v)):
+ raise AssertionError('nan found in eigenvectors')
+
+ assert_valid_eigen_recurse(M, w, v, **kw)
+
+
+def assert_valid_eigenvals_no_broadcast(M, w, **kw):
+ ident = np.eye(M.shape[0], dtype=M.dtype)
+ for i in range(w.shape[0]):
+ assert_almost_equal(gula.det(M - w[i]*ident), 0.0, **kw)
+
+
+def assert_valid_eigenvals_recurse(M, w, **kw):
+ if len(M.shape) > 2:
+ for i in range(M.shape[0]):
+ assert_valid_eigenvals_recurse(M[i], w[i], **kw)
+ else:
+ if len(M.shape) == 2:
+ assert_valid_eigenvals_no_broadcast(M, w, **kw)
+ else:
+ raise AssertionError('Not enough dimensions')
+
+
+def assert_valid_eigenvals(M, w, **kw):
+ if np.any(np.isnan(M)):
+ raise AssertionError('nan found in matrix')
+ if np.any(np.isnan(w)):
+ raise AssertionError('nan found in eigenvalues')
+ assert_valid_eigenvals_recurse(M, w, **kw)
+
+
+class MatrixGenerator(object):
+ def real_matrices(self):
+ a = [[1,2],
+ [3,4]]
+
+ b = [[4,3],
+ [2,1]]
+
+ return a, b
+
+ def real_symmetric_matrices(self):
+ a = [[ 2 ,-1],
+ [-1 , 2]]
+
+ b = [[4,3],
+ [2,1]]
+
+ return a, b
+
+ def complex_matrices(self):
+ a = [[1+2j,2+3j],
+ [3+4j,4+5j]]
+
+ b = [[4+3j,3+2j],
+ [2+1j,1+0j]]
+
+ return a, b
+
+ def complex_hermitian_matrices(self):
+ a = [[2,-1],
+ [-1, 2]]
+
+ b = [[4+3j,3+2j],
+ [2-1j,1+0j]]
+
+ return a, b
+
+ def real_matrices_vector(self):
+ a, b = self.real_matrices()
+ return [a], [b]
+
+ def real_symmetric_matrices_vector(self):
+ a, b = self.real_symmetric_matrices()
+ return [a], [b]
+
+ def complex_matrices_vector(self):
+ a, b = self.complex_matrices()
+ return [a], [b]
+
+ def complex_hermitian_matrices_vector(self):
+ a, b = self.complex_hermitian_matrices()
+ return [a], [b]
+
+
+class GeneralTestCase(MatrixGenerator):
+ def test_single(self):
+ a,b = self.real_matrices()
+ self.do(array(a, dtype=single),
+ array(b, dtype=single))
+
+ def test_double(self):
+ a, b = self.real_matrices()
+ self.do(array(a, dtype=double),
+ array(b, dtype=double))
+
+ def test_csingle(self):
+ a, b = self.complex_matrices()
+ self.do(array(a, dtype=csingle),
+ array(b, dtype=csingle))
+
+ def test_cdouble(self):
+ a, b = self.complex_matrices()
+ self.do(array(a, dtype=cdouble),
+ array(b, dtype=cdouble))
+
+ def test_vector_single(self):
+ a,b = self.real_matrices_vector()
+ self.do(array(a, dtype=single),
+ array(b, dtype=single))
+
+ def test_vector_double(self):
+ a, b = self.real_matrices_vector()
+ self.do(array(a, dtype=double),
+ array(b, dtype=double))
+
+ def test_vector_csingle(self):
+ a, b = self.complex_matrices_vector()
+ self.do(array(a, dtype=csingle),
+ array(b, dtype=csingle))
+
+ def test_vector_cdouble(self):
+ a, b = self.complex_matrices_vector()
+ self.do(array(a, dtype=cdouble),
+ array(b, dtype=cdouble))
+
+
+class HermitianTestCase(MatrixGenerator):
+ def test_single(self):
+ a,b = self.real_symmetric_matrices()
+ self.do(array(a, dtype=single),
+ array(b, dtype=single))
+
+ def test_double(self):
+ a, b = self.real_symmetric_matrices()
+ self.do(array(a, dtype=double),
+ array(b, dtype=double))
+
+ def test_csingle(self):
+ a, b = self.complex_hermitian_matrices()
+ self.do(array(a, dtype=csingle),
+ array(b, dtype=csingle))
+
+ def test_cdouble(self):
+ a, b = self.complex_hermitian_matrices()
+ self.do(array(a, dtype=cdouble),
+ array(b, dtype=cdouble))
+
+ def test_vector_single(self):
+ a,b = self.real_symmetric_matrices_vector()
+ self.do(array(a, dtype=single),
+ array(b, dtype=single))
+
+ def test_vector_double(self):
+ a, b = self.real_symmetric_matrices_vector()
+ self.do(array(a, dtype=double),
+ array(b, dtype=double))
+
+ def test_vector_csingle(self):
+ a, b = self.complex_hermitian_matrices_vector()
+ self.do(array(a, dtype=csingle),
+ array(b, dtype=csingle))
+
+ def test_vector_cdouble(self):
+ a, b = self.complex_hermitian_matrices_vector()
+ self.do(array(a, dtype=cdouble),
+ array(b, dtype=cdouble))
+
+
+class TestMatrixMultiply(GeneralTestCase):
+ def do(self, a, b):
+ res = gula.matrix_multiply(a,b)
+ if a.ndim == 2:
+ assert_almost_equal(res, np.dot(a,b))
+ else:
+ assert_almost_equal(res[0], np.dot(a[0],b[0]))
+
+ def test_column_matrix(self):
+ A = np.arange(2*2).reshape((2,2))
+ B = np.arange(2*1).reshape((2,1))
+ res = gula.matrix_multiply(A,B)
+ assert_almost_equal(res, np.dot(A,B))
+
+class TestInv(GeneralTestCase, TestCase):
+ def do(self, a, b):
+ a_inv = gula.inv(a)
+ ident = identity(a.shape[-1])
+ if 3 == len(a.shape):
+ ident = ident.reshape((1, ident.shape[0], ident.shape[1]))
+ assert_almost_equal(gula.matrix_multiply(a, a_inv), ident)
+
+
+class TestPoinv(HermitianTestCase, TestCase):
+ def do(self, a, b):
+ a_inv = gula.poinv(a)
+ ident = identity(a.shape[-1])
+ if 3 == len(a.shape):
+ ident = ident.reshape((1,ident.shape[0], ident.shape[1]))
+
+ assert_almost_equal(a_inv, gula.inv(a))
+ assert_almost_equal(gula.matrix_multiply(a, a_inv), ident)
+
+
+class TestDet(GeneralTestCase, TestCase):
+ def do(self, a, b):
+ d = gula.det(a)
+ s, ld = gula.slogdet(a)
+ assert_almost_equal(s * np.exp(ld), d)
+
+ if np.csingle == a.dtype.type or np.single == a.dtype.type:
+ cmp_type=np.csingle
+ else:
+ cmp_type=np.cdouble
+
+ ev = gula.eigvals(a.astype(cmp_type))
+ assert_almost_equal(d.astype(cmp_type),
+ multiply.reduce(ev.astype(cmp_type),
+ axis=(ev.ndim-1)))
+ if s != 0:
+ assert_almost_equal(np.abs(s), 1)
+ else:
+ assert_equal(ld, -inf)
+
+ def test_zero(self):
+ assert_equal(gula.det(array([[0.0]], dtype=single)), 0.0)
+ assert_equal(gula.det(array([[0.0]], dtype=double)), 0.0)
+ assert_equal(gula.det(array([[0.0]], dtype=csingle)), 0.0)
+ assert_equal(gula.det(array([[0.0]], dtype=cdouble)), 0.0)
+
+ assert_equal(gula.slogdet(array([[0.0]], dtype=single)), (0.0, -inf))
+ assert_equal(gula.slogdet(array([[0.0]], dtype=double)), (0.0, -inf))
+ assert_equal(gula.slogdet(array([[0.0]], dtype=csingle)), (0.0, -inf))
+ assert_equal(gula.slogdet(array([[0.0]], dtype=cdouble)), (0.0, -inf))
+
+ def test_types(self):
+ for typ in [(single, single),
+ (double, double),
+ (csingle, single),
+ (cdouble, double)]:
+ for x in [ [0], [[0]], [[[0]]] ]:
+ assert_equal(gula.det(array(x, dtype=typ[0])).dtype, typ[0])
+ assert_equal(gula.slogdet(array(x, dtype=typ[0]))[0].dtype, typ[0])
+ assert_equal(gula.slogdet(array(x, dtype=typ[0]))[1].dtype, typ[1])
+
+
+class TestEig(GeneralTestCase, TestCase):
+ def do(self, a, b):
+ evalues, evectors = gula.eig(a)
+ assert_valid_eigenvals(a, evalues)
+ assert_valid_eigen(a, evalues, evectors)
+ ev = gula.eigvals(a)
+ assert_valid_eigenvals(a, evalues)
+ assert_almost_equal(ev, evalues)
+
+
+class TestEigh(HermitianTestCase, TestCase):
+ def do(self, a, b):
+ evalues_lo, evectors_lo = gula.eigh(a, UPLO='L')
+ evalues_up, evectors_up = gula.eigh(a, UPLO='U')
+
+ assert_valid_eigenvals(a, evalues_lo)
+ assert_valid_eigenvals(a, evalues_up)
+ assert_valid_eigen(a, evalues_lo, evectors_lo)
+ assert_valid_eigen(a, evalues_up, evectors_up)
+ assert_almost_equal(evalues_lo, evalues_up)
+ assert_almost_equal(evectors_lo, evectors_up)
+
+ ev_lo = gula.eigvalsh(a, UPLO='L')
+ ev_up = gula.eigvalsh(a, UPLO='U')
+ assert_valid_eigenvals(a, ev_lo)
+ assert_valid_eigenvals(a, ev_up)
+ assert_almost_equal(ev_lo, evalues_lo)
+ assert_almost_equal(ev_up, evalues_up)
+
+
+class TestSolve(GeneralTestCase,TestCase):
+ def do(self, a, b):
+ x = gula.solve(a,b)
+ assert_almost_equal(b, gula.matrix_multiply(a,x))
+
+
+class TestChosolve(HermitianTestCase, TestCase):
+ def do(self, a, b):
+ """
+ inner1d not defined for complex types.
+ todo: implement alternative test
+ """
+ if csingle == a.dtype or cdouble == a.dtype:
+ raise SkipTest
+
+ x_lo = gula.chosolve(a, b, UPLO='L')
+ x_up = gula.chosolve(a, b, UPLO='U')
+ assert_almost_equal(x_lo, x_up)
+ # inner1d not defined for complex types
+ # todo: implement alternative test
+ assert_almost_equal(b, gula.matrix_multiply(a,x_lo))
+ assert_almost_equal(b, gula.matrix_multiply(a,x_up))
+
+
+class TestSVD(GeneralTestCase, TestCase):
+ def do(self, a, b):
+ """ still work in progress """
+ raise SkipTest
+ u, s, vt = gula.svd(a, 0)
+ assert_almost_equal(a, dot(multiply(u, s), vt))
+
+"""
+class TestCholesky(HermitianTestCase, TestCase):
+ def do(self, a, b):
+ pass
+"""
+
+################################################################################
+# ufuncs inspired by pdl
+# - add3
+# - multiply3
+# - multiply3_add
+# - multiply_add
+# - multiply_add2
+# - multiply4
+# - multiply4_add
+
+class UfuncTestCase(object):
+ parameter = range(0,10)
+
+ def _check_for_type(self, typ):
+ a = np.array(self.__class__.parameter, dtype=typ)
+ self.do(a)
+
+ def _check_for_type_vector(self, typ):
+ parameter = self.__class__.parameter
+ a = np.array([parameter, parameter], dtype=typ)
+ self.do(a)
+
+ def test_single(self):
+ self._check_for_type(single)
+
+ def test_double(self):
+ self._check_for_type(double)
+
+ def test_csingle(self):
+ self._check_for_type(csingle)
+
+ def test_cdouble(self):
+ self._check_for_type(cdouble)
+
+ def test_single_vector(self):
+ self._check_for_type_vector(single)
+
+ def test_double_vector(self):
+ self._check_for_type_vector(double)
+
+ def test_csingle_vector(self):
+ self._check_for_type_vector(csingle)
+
+ def test_cdouble_vector(self):
+ self._check_for_type_vector(cdouble)
+
+
+class TestAdd3(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.add3(a,a,a)
+ assert_almost_equal(r, a+a+a)
+
+
+class TestMultiply3(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.multiply3(a,a,a)
+ assert_almost_equal(r, a*a*a)
+
+
+class TestMultiply3Add(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.multiply3_add(a,a,a,a)
+ assert_almost_equal(r, a*a*a+a)
+
+
+class TestMultiplyAdd(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.multiply_add(a,a,a)
+ assert_almost_equal(r, a*a+a)
+
+
+class TestMultiplyAdd2(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.multiply_add2(a,a,a,a)
+ assert_almost_equal(r, a*a+a+a)
+
+
+class TestMultiply4(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.multiply4(a,a,a,a)
+ assert_almost_equal(r, a*a*a*a)
+
+
+class TestMultiply4_add(UfuncTestCase, TestCase):
+ def do(self, a):
+ r = gula.multiply4_add(a,a,a,a,a)
+ assert_almost_equal(r, a*a*a*a+a)
+
+
+if __name__ == "__main__":
+ print('testing gufuncs_linalg; gufuncs version: %s' % gula._impl.__version__)
+ run_module_suite()
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index d31da3220..c64253d21 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -7,7 +7,7 @@ import sys
import numpy as np
from numpy.testing import (TestCase, assert_, assert_equal, assert_raises,
assert_array_equal, assert_almost_equal,
- run_module_suite)
+ run_module_suite, dec)
from numpy import array, single, double, csingle, cdouble, dot, identity
from numpy import multiply, atleast_2d, inf, asarray, matrix
from numpy import linalg
@@ -27,6 +27,14 @@ def assert_almost_equal(a, b, **kw):
decimal = 12
old_assert_almost_equal(a, b, decimal=decimal, **kw)
+def get_real_dtype(dtype):
+ return {single: single, double: double,
+ csingle: single, cdouble: double}[dtype]
+
+def get_complex_dtype(dtype):
+ return {single: csingle, double: cdouble,
+ csingle: csingle, cdouble: cdouble}[dtype]
+
class LinalgTestCase(object):
def test_single(self):
@@ -138,43 +146,145 @@ class LinalgNonsquareTestCase(object):
self.do(a, b)
-class TestSolve(LinalgTestCase, TestCase):
+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)
+
+
+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)
+
+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])
+
+
+class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
x = linalg.solve(a, b)
- assert_almost_equal(b, dot(a, x))
+ assert_almost_equal(b, dot_generalized(a, x))
assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
+ def test_types(self):
+ def check(dtype):
+ x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+ assert_equal(linalg.solve(x, x).dtype, dtype)
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
-class TestInv(LinalgTestCase, TestCase):
+
+class TestInv(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
a_inv = linalg.inv(a)
- assert_almost_equal(dot(a, a_inv), identity(asarray(a).shape[0]))
+ assert_almost_equal(dot_generalized(a, a_inv),
+ identity_like_generalized(a))
assert_(imply(isinstance(a, matrix), isinstance(a_inv, matrix)))
+ def test_types(self):
+ def check(dtype):
+ x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+ assert_equal(linalg.inv(x).dtype, dtype)
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
+
-class TestEigvals(LinalgTestCase, TestCase):
+class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
ev = linalg.eigvals(a)
evalues, evectors = linalg.eig(a)
assert_almost_equal(ev, evalues)
+ def test_types(self):
+ def check(dtype):
+ x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+ assert_equal(linalg.eigvals(x).dtype, dtype)
+ x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
+ assert_equal(linalg.eigvals(x).dtype, get_complex_dtype(dtype))
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
-class TestEig(LinalgTestCase, TestCase):
+
+class TestEig(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
evalues, evectors = linalg.eig(a)
- assert_almost_equal(dot(a, evectors), multiply(evectors, evalues))
+ 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_(imply(isinstance(a, matrix), isinstance(evectors, matrix)))
+ 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.dtype, dtype)
+ assert_equal(v.dtype, dtype)
+
+ x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
+ w, v = np.linalg.eig(x)
+ assert_equal(w.dtype, get_complex_dtype(dtype))
+ assert_equal(v.dtype, get_complex_dtype(dtype))
-class TestSVD(LinalgTestCase, TestCase):
+ for dtype in [single, double, csingle, cdouble]:
+ yield dtype
+
+
+class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
u, s, vt = linalg.svd(a, 0)
- assert_almost_equal(a, dot(multiply(u, s), vt))
+ 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_(imply(isinstance(a, matrix), isinstance(u, matrix)))
assert_(imply(isinstance(a, matrix), isinstance(vt, matrix)))
+ def test_types(self):
+ def check(dtype):
+ x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
+ u, s, vh = linalg.svd(x)
+ assert_equal(u.dtype, dtype)
+ assert_equal(s.dtype, get_real_dtype(dtype))
+ assert_equal(vh.dtype, dtype)
+ s = linalg.svd(x, compute_uv=False)
+ assert_equal(s.dtype, get_real_dtype(dtype))
+
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
-class TestCondSVD(LinalgTestCase, TestCase):
+
+class TestCondSVD(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
c = asarray(a) # a might be a matrix
s = linalg.svd(c, compute_uv=False)
@@ -201,7 +311,7 @@ class TestPinv(LinalgTestCase, TestCase):
assert_(imply(isinstance(a, matrix), isinstance(a_ginv, matrix)))
-class TestDet(LinalgTestCase, TestCase):
+class TestDet(LinalgTestCase, LinalgGeneralizedTestCase, TestCase):
def do(self, a, b):
d = linalg.det(a)
(s, ld) = linalg.slogdet(a)
@@ -210,12 +320,14 @@ class TestDet(LinalgTestCase, TestCase):
else:
ad = asarray(a).astype(cdouble)
ev = linalg.eigvals(ad)
- assert_almost_equal(d, multiply.reduce(ev))
- assert_almost_equal(s * np.exp(ld), multiply.reduce(ev))
- if s != 0:
- assert_almost_equal(np.abs(s), 1)
- else:
- assert_equal(ld, -inf)
+ assert_almost_equal(d, multiply.reduce(ev, axis=-1))
+ assert_almost_equal(s * np.exp(ld), multiply.reduce(ev, axis=-1))
+
+ s = np.atleast_1d(s)
+ ld = np.atleast_1d(ld)
+ m = (s != 0)
+ assert_almost_equal(np.abs(s[m]), 1)
+ assert_equal(ld[~m], -inf)
def test_zero(self):
assert_equal(linalg.det([[0.0]]), 0.0)
@@ -230,6 +342,13 @@ class TestDet(LinalgTestCase, TestCase):
assert_equal(type(linalg.slogdet([[0.0j]])[0]), cdouble)
assert_equal(type(linalg.slogdet([[0.0j]])[1]), double)
+ 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))
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
+
class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase, TestCase):
def do(self, a, b):
@@ -269,10 +388,10 @@ class TestMatrixPower(object):
large[0,:] = t
def test_large_power(self):
- assert_equal(matrix_power(self.R90,2L**100+2**10+2**5+1),self.R90)
+ assert_equal(matrix_power(self.R90,2**100+2**10+2**5+1),self.R90)
def test_large_power_trailing_zero(self):
- assert_equal(matrix_power(self.R90,2L**100+2**10+2**5),identity(2))
+ assert_equal(matrix_power(self.R90,2**100+2**10+2**5),identity(2))
def testip_zero(self):
def tz(M):
@@ -320,60 +439,79 @@ class TestBoolPower(TestCase):
class HermitianTestCase(object):
def test_single(self):
a = array([[1.,2.], [2.,1.]], dtype=single)
- self.do(a)
+ self.do(a, None)
def test_double(self):
a = array([[1.,2.], [2.,1.]], dtype=double)
- self.do(a)
+ self.do(a, None)
def test_csingle(self):
a = array([[1.,2+3j], [2-3j,1]], dtype=csingle)
- self.do(a)
+ self.do(a, None)
def test_cdouble(self):
a = array([[1.,2+3j], [2-3j,1]], dtype=cdouble)
- self.do(a)
+ self.do(a, None)
def test_empty(self):
a = atleast_2d(array([], dtype = double))
- assert_raises(linalg.LinAlgError, self.do, a)
+ assert_raises(linalg.LinAlgError, self.do, a, None)
def test_nonarray(self):
a = [[1,2], [2,1]]
- self.do(a)
+ 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)
+ 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)
+ self.do(a, None)
+
+HermitianGeneralizedTestCase = _generalized_testcase(
+ 'HermitianGeneralizedTestCase', HermitianTestCase)
-class TestEigvalsh(HermitianTestCase, TestCase):
- def do(self, a):
+class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase, TestCase):
+ def do(self, a, b):
# note that eigenvalue arrays must be sorted since
# their order isn't guaranteed.
ev = linalg.eigvalsh(a)
evalues, evectors = linalg.eig(a)
- ev.sort()
- evalues.sort()
+ ev.sort(axis=-1)
+ evalues.sort(axis=-1)
assert_almost_equal(ev, evalues)
+ 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))
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
+
-class TestEigh(HermitianTestCase, TestCase):
- def do(self, a):
+class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase, TestCase):
+ def do(self, a, b):
# note that eigenvalue arrays must be sorted since
# their order isn't guaranteed.
ev, evc = linalg.eigh(a)
evalues, evectors = linalg.eig(a)
- ev.sort()
- evalues.sort()
+ ev.sort(axis=-1)
+ evalues.sort(axis=-1)
assert_almost_equal(ev, evalues)
+ 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)
+ for dtype in [single, double, csingle, cdouble]:
+ yield check, dtype
+
class _TestNorm(TestCase):
dt = None
@@ -599,5 +737,36 @@ def test_byteorder_check():
assert_array_equal(res, routine(sw_arr))
+def test_generalized_raise_multiloop():
+ # It should raise an error even if the error doesn't occur in the
+ # last iteration of the ufunc inner loop
+
+ invertible = np.array([[1, 2], [3, 4]])
+ non_invertible = np.array([[1, 1], [1, 1]])
+
+ x = np.zeros([4, 4, 2, 2])[1::2]
+ x[...] = invertible
+ x[0,0] = non_invertible
+
+ assert_raises(np.linalg.LinAlgError, np.linalg.inv, x)
+
+
+@dec.skipif(sys.platform == "win32", "python_xerbla not enabled on Win32")
+def test_xerbla():
+ # Test that xerbla works (with GIL)
+ a = np.array([[1]])
+ try:
+ np.linalg.lapack_lite.dgetrf(
+ 1, 1, a.astype(np.double),
+ 0, # <- invalid value
+ a.astype(np.intc), 0)
+ except ValueError as e:
+ assert_("DGETRF parameter number 4" in str(e))
+ else:
+ assert_(False)
+
+ # Test that xerbla works (without GIL)
+ assert_raises(ValueError, np.linalg.lapack_lite.xerbla)
+
if __name__ == "__main__":
run_module_suite()