annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/linalg/tests/test_linalg.py @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2a2c65a20a8b
children
rev   line source
Chris@87 1 """ Test functions for linalg module
Chris@87 2
Chris@87 3 """
Chris@87 4 from __future__ import division, absolute_import, print_function
Chris@87 5
Chris@87 6 import os
Chris@87 7 import sys
Chris@87 8 import itertools
Chris@87 9 import traceback
Chris@87 10
Chris@87 11 import numpy as np
Chris@87 12 from numpy import array, single, double, csingle, cdouble, dot, identity
Chris@87 13 from numpy import multiply, atleast_2d, inf, asarray, matrix
Chris@87 14 from numpy import linalg
Chris@87 15 from numpy.linalg import matrix_power, norm, matrix_rank
Chris@87 16 from numpy.testing import (
Chris@87 17 assert_, assert_equal, assert_raises, assert_array_equal,
Chris@87 18 assert_almost_equal, assert_allclose, run_module_suite,
Chris@87 19 dec
Chris@87 20 )
Chris@87 21
Chris@87 22
Chris@87 23 def ifthen(a, b):
Chris@87 24 return not a or b
Chris@87 25
Chris@87 26
Chris@87 27 def imply(a, b):
Chris@87 28 return not a or b
Chris@87 29
Chris@87 30
Chris@87 31 old_assert_almost_equal = assert_almost_equal
Chris@87 32
Chris@87 33
Chris@87 34 def assert_almost_equal(a, b, **kw):
Chris@87 35 if asarray(a).dtype.type in (single, csingle):
Chris@87 36 decimal = 6
Chris@87 37 else:
Chris@87 38 decimal = 12
Chris@87 39 old_assert_almost_equal(a, b, decimal=decimal, **kw)
Chris@87 40
Chris@87 41
Chris@87 42 def get_real_dtype(dtype):
Chris@87 43 return {single: single, double: double,
Chris@87 44 csingle: single, cdouble: double}[dtype]
Chris@87 45
Chris@87 46
Chris@87 47 def get_complex_dtype(dtype):
Chris@87 48 return {single: csingle, double: cdouble,
Chris@87 49 csingle: csingle, cdouble: cdouble}[dtype]
Chris@87 50
Chris@87 51 def get_rtol(dtype):
Chris@87 52 # Choose a safe rtol
Chris@87 53 if dtype in (single, csingle):
Chris@87 54 return 1e-5
Chris@87 55 else:
Chris@87 56 return 1e-11
Chris@87 57
Chris@87 58 class LinalgCase(object):
Chris@87 59 def __init__(self, name, a, b, exception_cls=None):
Chris@87 60 assert isinstance(name, str)
Chris@87 61 self.name = name
Chris@87 62 self.a = a
Chris@87 63 self.b = b
Chris@87 64 self.exception_cls = exception_cls
Chris@87 65
Chris@87 66 def check(self, do):
Chris@87 67 if self.exception_cls is None:
Chris@87 68 do(self.a, self.b)
Chris@87 69 else:
Chris@87 70 assert_raises(self.exception_cls, do, self.a, self.b)
Chris@87 71
Chris@87 72 def __repr__(self):
Chris@87 73 return "<LinalgCase: %s>" % (self.name,)
Chris@87 74
Chris@87 75
Chris@87 76 #
Chris@87 77 # Base test cases
Chris@87 78 #
Chris@87 79
Chris@87 80 np.random.seed(1234)
Chris@87 81
Chris@87 82 SQUARE_CASES = [
Chris@87 83 LinalgCase("single",
Chris@87 84 array([[1., 2.], [3., 4.]], dtype=single),
Chris@87 85 array([2., 1.], dtype=single)),
Chris@87 86 LinalgCase("double",
Chris@87 87 array([[1., 2.], [3., 4.]], dtype=double),
Chris@87 88 array([2., 1.], dtype=double)),
Chris@87 89 LinalgCase("double_2",
Chris@87 90 array([[1., 2.], [3., 4.]], dtype=double),
Chris@87 91 array([[2., 1., 4.], [3., 4., 6.]], dtype=double)),
Chris@87 92 LinalgCase("csingle",
Chris@87 93 array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=csingle),
Chris@87 94 array([2.+1j, 1.+2j], dtype=csingle)),
Chris@87 95 LinalgCase("cdouble",
Chris@87 96 array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=cdouble),
Chris@87 97 array([2.+1j, 1.+2j], dtype=cdouble)),
Chris@87 98 LinalgCase("cdouble_2",
Chris@87 99 array([[1.+2j, 2+3j], [3+4j, 4+5j]], dtype=cdouble),
Chris@87 100 array([[2.+1j, 1.+2j, 1+3j], [1-2j, 1-3j, 1-6j]], dtype=cdouble)),
Chris@87 101 LinalgCase("empty",
Chris@87 102 atleast_2d(array([], dtype = double)),
Chris@87 103 atleast_2d(array([], dtype = double)),
Chris@87 104 linalg.LinAlgError),
Chris@87 105 LinalgCase("8x8",
Chris@87 106 np.random.rand(8, 8),
Chris@87 107 np.random.rand(8)),
Chris@87 108 LinalgCase("1x1",
Chris@87 109 np.random.rand(1, 1),
Chris@87 110 np.random.rand(1)),
Chris@87 111 LinalgCase("nonarray",
Chris@87 112 [[1, 2], [3, 4]],
Chris@87 113 [2, 1]),
Chris@87 114 LinalgCase("matrix_b_only",
Chris@87 115 array([[1., 2.], [3., 4.]]),
Chris@87 116 matrix([2., 1.]).T),
Chris@87 117 LinalgCase("matrix_a_and_b",
Chris@87 118 matrix([[1., 2.], [3., 4.]]),
Chris@87 119 matrix([2., 1.]).T),
Chris@87 120 ]
Chris@87 121
Chris@87 122 NONSQUARE_CASES = [
Chris@87 123 LinalgCase("single_nsq_1",
Chris@87 124 array([[1., 2., 3.], [3., 4., 6.]], dtype=single),
Chris@87 125 array([2., 1.], dtype=single)),
Chris@87 126 LinalgCase("single_nsq_2",
Chris@87 127 array([[1., 2.], [3., 4.], [5., 6.]], dtype=single),
Chris@87 128 array([2., 1., 3.], dtype=single)),
Chris@87 129 LinalgCase("double_nsq_1",
Chris@87 130 array([[1., 2., 3.], [3., 4., 6.]], dtype=double),
Chris@87 131 array([2., 1.], dtype=double)),
Chris@87 132 LinalgCase("double_nsq_2",
Chris@87 133 array([[1., 2.], [3., 4.], [5., 6.]], dtype=double),
Chris@87 134 array([2., 1., 3.], dtype=double)),
Chris@87 135 LinalgCase("csingle_nsq_1",
Chris@87 136 array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=csingle),
Chris@87 137 array([2.+1j, 1.+2j], dtype=csingle)),
Chris@87 138 LinalgCase("csingle_nsq_2",
Chris@87 139 array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=csingle),
Chris@87 140 array([2.+1j, 1.+2j, 3.-3j], dtype=csingle)),
Chris@87 141 LinalgCase("cdouble_nsq_1",
Chris@87 142 array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=cdouble),
Chris@87 143 array([2.+1j, 1.+2j], dtype=cdouble)),
Chris@87 144 LinalgCase("cdouble_nsq_2",
Chris@87 145 array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=cdouble),
Chris@87 146 array([2.+1j, 1.+2j, 3.-3j], dtype=cdouble)),
Chris@87 147 LinalgCase("cdouble_nsq_1_2",
Chris@87 148 array([[1.+1j, 2.+2j, 3.-3j], [3.-5j, 4.+9j, 6.+2j]], dtype=cdouble),
Chris@87 149 array([[2.+1j, 1.+2j], [1-1j, 2-2j]], dtype=cdouble)),
Chris@87 150 LinalgCase("cdouble_nsq_2_2",
Chris@87 151 array([[1.+1j, 2.+2j], [3.-3j, 4.-9j], [5.-4j, 6.+8j]], dtype=cdouble),
Chris@87 152 array([[2.+1j, 1.+2j], [1-1j, 2-2j], [1-1j, 2-2j]], dtype=cdouble)),
Chris@87 153 LinalgCase("8x11",
Chris@87 154 np.random.rand(8, 11),
Chris@87 155 np.random.rand(11)),
Chris@87 156 LinalgCase("1x5",
Chris@87 157 np.random.rand(1, 5),
Chris@87 158 np.random.rand(5)),
Chris@87 159 LinalgCase("5x1",
Chris@87 160 np.random.rand(5, 1),
Chris@87 161 np.random.rand(1)),
Chris@87 162 ]
Chris@87 163
Chris@87 164 HERMITIAN_CASES = [
Chris@87 165 LinalgCase("hsingle",
Chris@87 166 array([[1., 2.], [2., 1.]], dtype=single),
Chris@87 167 None),
Chris@87 168 LinalgCase("hdouble",
Chris@87 169 array([[1., 2.], [2., 1.]], dtype=double),
Chris@87 170 None),
Chris@87 171 LinalgCase("hcsingle",
Chris@87 172 array([[1., 2+3j], [2-3j, 1]], dtype=csingle),
Chris@87 173 None),
Chris@87 174 LinalgCase("hcdouble",
Chris@87 175 array([[1., 2+3j], [2-3j, 1]], dtype=cdouble),
Chris@87 176 None),
Chris@87 177 LinalgCase("hempty",
Chris@87 178 atleast_2d(array([], dtype = double)),
Chris@87 179 None,
Chris@87 180 linalg.LinAlgError),
Chris@87 181 LinalgCase("hnonarray",
Chris@87 182 [[1, 2], [2, 1]],
Chris@87 183 None),
Chris@87 184 LinalgCase("matrix_b_only",
Chris@87 185 array([[1., 2.], [2., 1.]]),
Chris@87 186 None),
Chris@87 187 LinalgCase("hmatrix_a_and_b",
Chris@87 188 matrix([[1., 2.], [2., 1.]]),
Chris@87 189 None),
Chris@87 190 LinalgCase("hmatrix_1x1",
Chris@87 191 np.random.rand(1, 1),
Chris@87 192 None),
Chris@87 193 ]
Chris@87 194
Chris@87 195
Chris@87 196 #
Chris@87 197 # Gufunc test cases
Chris@87 198 #
Chris@87 199
Chris@87 200 GENERALIZED_SQUARE_CASES = []
Chris@87 201 GENERALIZED_NONSQUARE_CASES = []
Chris@87 202 GENERALIZED_HERMITIAN_CASES = []
Chris@87 203
Chris@87 204 for tgt, src in ((GENERALIZED_SQUARE_CASES, SQUARE_CASES),
Chris@87 205 (GENERALIZED_NONSQUARE_CASES, NONSQUARE_CASES),
Chris@87 206 (GENERALIZED_HERMITIAN_CASES, HERMITIAN_CASES)):
Chris@87 207 for case in src:
Chris@87 208 if not isinstance(case.a, np.ndarray):
Chris@87 209 continue
Chris@87 210
Chris@87 211 a = np.array([case.a, 2*case.a, 3*case.a])
Chris@87 212 if case.b is None:
Chris@87 213 b = None
Chris@87 214 else:
Chris@87 215 b = np.array([case.b, 7*case.b, 6*case.b])
Chris@87 216 new_case = LinalgCase(case.name + "_tile3", a, b,
Chris@87 217 case.exception_cls)
Chris@87 218 tgt.append(new_case)
Chris@87 219
Chris@87 220 a = np.array([case.a]*2*3).reshape((3, 2) + case.a.shape)
Chris@87 221 if case.b is None:
Chris@87 222 b = None
Chris@87 223 else:
Chris@87 224 b = np.array([case.b]*2*3).reshape((3, 2) + case.b.shape)
Chris@87 225 new_case = LinalgCase(case.name + "_tile213", a, b,
Chris@87 226 case.exception_cls)
Chris@87 227 tgt.append(new_case)
Chris@87 228
Chris@87 229 #
Chris@87 230 # Generate stride combination variations of the above
Chris@87 231 #
Chris@87 232
Chris@87 233 def _stride_comb_iter(x):
Chris@87 234 """
Chris@87 235 Generate cartesian product of strides for all axes
Chris@87 236 """
Chris@87 237
Chris@87 238 if not isinstance(x, np.ndarray):
Chris@87 239 yield x, "nop"
Chris@87 240 return
Chris@87 241
Chris@87 242 stride_set = [(1,)]*x.ndim
Chris@87 243 stride_set[-1] = (1, 3, -4)
Chris@87 244 if x.ndim > 1:
Chris@87 245 stride_set[-2] = (1, 3, -4)
Chris@87 246 if x.ndim > 2:
Chris@87 247 stride_set[-3] = (1, -4)
Chris@87 248
Chris@87 249 for repeats in itertools.product(*tuple(stride_set)):
Chris@87 250 new_shape = [abs(a*b) for a, b in zip(x.shape, repeats)]
Chris@87 251 slices = tuple([slice(None, None, repeat) for repeat in repeats])
Chris@87 252
Chris@87 253 # new array with different strides, but same data
Chris@87 254 xi = np.empty(new_shape, dtype=x.dtype)
Chris@87 255 xi.view(np.uint32).fill(0xdeadbeef)
Chris@87 256 xi = xi[slices]
Chris@87 257 xi[...] = x
Chris@87 258 xi = xi.view(x.__class__)
Chris@87 259 assert np.all(xi == x)
Chris@87 260 yield xi, "stride_" + "_".join(["%+d" % j for j in repeats])
Chris@87 261
Chris@87 262 # generate also zero strides if possible
Chris@87 263 if x.ndim >= 1 and x.shape[-1] == 1:
Chris@87 264 s = list(x.strides)
Chris@87 265 s[-1] = 0
Chris@87 266 xi = np.lib.stride_tricks.as_strided(x, strides=s)
Chris@87 267 yield xi, "stride_xxx_0"
Chris@87 268 if x.ndim >= 2 and x.shape[-2] == 1:
Chris@87 269 s = list(x.strides)
Chris@87 270 s[-2] = 0
Chris@87 271 xi = np.lib.stride_tricks.as_strided(x, strides=s)
Chris@87 272 yield xi, "stride_xxx_0_x"
Chris@87 273 if x.ndim >= 2 and x.shape[:-2] == (1, 1):
Chris@87 274 s = list(x.strides)
Chris@87 275 s[-1] = 0
Chris@87 276 s[-2] = 0
Chris@87 277 xi = np.lib.stride_tricks.as_strided(x, strides=s)
Chris@87 278 yield xi, "stride_xxx_0_0"
Chris@87 279
Chris@87 280 for src in (SQUARE_CASES,
Chris@87 281 NONSQUARE_CASES,
Chris@87 282 HERMITIAN_CASES,
Chris@87 283 GENERALIZED_SQUARE_CASES,
Chris@87 284 GENERALIZED_NONSQUARE_CASES,
Chris@87 285 GENERALIZED_HERMITIAN_CASES):
Chris@87 286
Chris@87 287 new_cases = []
Chris@87 288 for case in src:
Chris@87 289 for a, a_tag in _stride_comb_iter(case.a):
Chris@87 290 for b, b_tag in _stride_comb_iter(case.b):
Chris@87 291 new_case = LinalgCase(case.name + "_" + a_tag + "_" + b_tag, a, b,
Chris@87 292 exception_cls=case.exception_cls)
Chris@87 293 new_cases.append(new_case)
Chris@87 294 src.extend(new_cases)
Chris@87 295
Chris@87 296
Chris@87 297 #
Chris@87 298 # Test different routines against the above cases
Chris@87 299 #
Chris@87 300
Chris@87 301 def _check_cases(func, cases):
Chris@87 302 for case in cases:
Chris@87 303 try:
Chris@87 304 case.check(func)
Chris@87 305 except Exception:
Chris@87 306 msg = "In test case: %r\n\n" % case
Chris@87 307 msg += traceback.format_exc()
Chris@87 308 raise AssertionError(msg)
Chris@87 309
Chris@87 310 class LinalgTestCase(object):
Chris@87 311 def test_sq_cases(self):
Chris@87 312 _check_cases(self.do, SQUARE_CASES)
Chris@87 313
Chris@87 314
Chris@87 315 class LinalgNonsquareTestCase(object):
Chris@87 316 def test_sq_cases(self):
Chris@87 317 _check_cases(self.do, NONSQUARE_CASES)
Chris@87 318
Chris@87 319
Chris@87 320 class LinalgGeneralizedTestCase(object):
Chris@87 321 @dec.slow
Chris@87 322 def test_generalized_sq_cases(self):
Chris@87 323 _check_cases(self.do, GENERALIZED_SQUARE_CASES)
Chris@87 324
Chris@87 325
Chris@87 326 class LinalgGeneralizedNonsquareTestCase(object):
Chris@87 327 @dec.slow
Chris@87 328 def test_generalized_nonsq_cases(self):
Chris@87 329 _check_cases(self.do, GENERALIZED_NONSQUARE_CASES)
Chris@87 330
Chris@87 331
Chris@87 332 class HermitianTestCase(object):
Chris@87 333 def test_herm_cases(self):
Chris@87 334 _check_cases(self.do, HERMITIAN_CASES)
Chris@87 335
Chris@87 336
Chris@87 337 class HermitianGeneralizedTestCase(object):
Chris@87 338 @dec.slow
Chris@87 339 def test_generalized_herm_cases(self):
Chris@87 340 _check_cases(self.do, GENERALIZED_HERMITIAN_CASES)
Chris@87 341
Chris@87 342
Chris@87 343 def dot_generalized(a, b):
Chris@87 344 a = asarray(a)
Chris@87 345 if a.ndim >= 3:
Chris@87 346 if a.ndim == b.ndim:
Chris@87 347 # matrix x matrix
Chris@87 348 new_shape = a.shape[:-1] + b.shape[-1:]
Chris@87 349 elif a.ndim == b.ndim + 1:
Chris@87 350 # matrix x vector
Chris@87 351 new_shape = a.shape[:-1]
Chris@87 352 else:
Chris@87 353 raise ValueError("Not implemented...")
Chris@87 354 r = np.empty(new_shape, dtype=np.common_type(a, b))
Chris@87 355 for c in itertools.product(*map(range, a.shape[:-2])):
Chris@87 356 r[c] = dot(a[c], b[c])
Chris@87 357 return r
Chris@87 358 else:
Chris@87 359 return dot(a, b)
Chris@87 360
Chris@87 361
Chris@87 362 def identity_like_generalized(a):
Chris@87 363 a = asarray(a)
Chris@87 364 if a.ndim >= 3:
Chris@87 365 r = np.empty(a.shape, dtype=a.dtype)
Chris@87 366 for c in itertools.product(*map(range, a.shape[:-2])):
Chris@87 367 r[c] = identity(a.shape[-2])
Chris@87 368 return r
Chris@87 369 else:
Chris@87 370 return identity(a.shape[0])
Chris@87 371
Chris@87 372
Chris@87 373 class TestSolve(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 374 def do(self, a, b):
Chris@87 375 x = linalg.solve(a, b)
Chris@87 376 assert_almost_equal(b, dot_generalized(a, x))
Chris@87 377 assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
Chris@87 378
Chris@87 379 def test_types(self):
Chris@87 380 def check(dtype):
Chris@87 381 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 382 assert_equal(linalg.solve(x, x).dtype, dtype)
Chris@87 383 for dtype in [single, double, csingle, cdouble]:
Chris@87 384 yield check, dtype
Chris@87 385
Chris@87 386 def test_0_size(self):
Chris@87 387 class ArraySubclass(np.ndarray):
Chris@87 388 pass
Chris@87 389 # Test system of 0x0 matrices
Chris@87 390 a = np.arange(8).reshape(2, 2, 2)
Chris@87 391 b = np.arange(6).reshape(1, 2, 3).view(ArraySubclass)
Chris@87 392
Chris@87 393 expected = linalg.solve(a, b)[:, 0:0,:]
Chris@87 394 result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0,:])
Chris@87 395 assert_array_equal(result, expected)
Chris@87 396 assert_(isinstance(result, ArraySubclass))
Chris@87 397
Chris@87 398 # Test errors for non-square and only b's dimension being 0
Chris@87 399 assert_raises(linalg.LinAlgError, linalg.solve, a[:, 0:0, 0:1], b)
Chris@87 400 assert_raises(ValueError, linalg.solve, a, b[:, 0:0,:])
Chris@87 401
Chris@87 402 # Test broadcasting error
Chris@87 403 b = np.arange(6).reshape(1, 3, 2) # broadcasting error
Chris@87 404 assert_raises(ValueError, linalg.solve, a, b)
Chris@87 405 assert_raises(ValueError, linalg.solve, a[0:0], b[0:0])
Chris@87 406
Chris@87 407 # Test zero "single equations" with 0x0 matrices.
Chris@87 408 b = np.arange(2).reshape(1, 2).view(ArraySubclass)
Chris@87 409 expected = linalg.solve(a, b)[:, 0:0]
Chris@87 410 result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0])
Chris@87 411 assert_array_equal(result, expected)
Chris@87 412 assert_(isinstance(result, ArraySubclass))
Chris@87 413
Chris@87 414 b = np.arange(3).reshape(1, 3)
Chris@87 415 assert_raises(ValueError, linalg.solve, a, b)
Chris@87 416 assert_raises(ValueError, linalg.solve, a[0:0], b[0:0])
Chris@87 417 assert_raises(ValueError, linalg.solve, a[:, 0:0, 0:0], b)
Chris@87 418
Chris@87 419 def test_0_size_k(self):
Chris@87 420 # test zero multiple equation (K=0) case.
Chris@87 421 class ArraySubclass(np.ndarray):
Chris@87 422 pass
Chris@87 423 a = np.arange(4).reshape(1, 2, 2)
Chris@87 424 b = np.arange(6).reshape(3, 2, 1).view(ArraySubclass)
Chris@87 425
Chris@87 426 expected = linalg.solve(a, b)[:,:, 0:0]
Chris@87 427 result = linalg.solve(a, b[:,:, 0:0])
Chris@87 428 assert_array_equal(result, expected)
Chris@87 429 assert_(isinstance(result, ArraySubclass))
Chris@87 430
Chris@87 431 # test both zero.
Chris@87 432 expected = linalg.solve(a, b)[:, 0:0, 0:0]
Chris@87 433 result = linalg.solve(a[:, 0:0, 0:0], b[:,0:0, 0:0])
Chris@87 434 assert_array_equal(result, expected)
Chris@87 435 assert_(isinstance(result, ArraySubclass))
Chris@87 436
Chris@87 437
Chris@87 438 class TestInv(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 439 def do(self, a, b):
Chris@87 440 a_inv = linalg.inv(a)
Chris@87 441 assert_almost_equal(dot_generalized(a, a_inv),
Chris@87 442 identity_like_generalized(a))
Chris@87 443 assert_(imply(isinstance(a, matrix), isinstance(a_inv, matrix)))
Chris@87 444
Chris@87 445 def test_types(self):
Chris@87 446 def check(dtype):
Chris@87 447 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 448 assert_equal(linalg.inv(x).dtype, dtype)
Chris@87 449 for dtype in [single, double, csingle, cdouble]:
Chris@87 450 yield check, dtype
Chris@87 451
Chris@87 452 def test_0_size(self):
Chris@87 453 # Check that all kinds of 0-sized arrays work
Chris@87 454 class ArraySubclass(np.ndarray):
Chris@87 455 pass
Chris@87 456 a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass)
Chris@87 457 res = linalg.inv(a)
Chris@87 458 assert_(res.dtype.type is np.float64)
Chris@87 459 assert_equal(a.shape, res.shape)
Chris@87 460 assert_(isinstance(a, ArraySubclass))
Chris@87 461
Chris@87 462 a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass)
Chris@87 463 res = linalg.inv(a)
Chris@87 464 assert_(res.dtype.type is np.complex64)
Chris@87 465 assert_equal(a.shape, res.shape)
Chris@87 466
Chris@87 467
Chris@87 468 class TestEigvals(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 469 def do(self, a, b):
Chris@87 470 ev = linalg.eigvals(a)
Chris@87 471 evalues, evectors = linalg.eig(a)
Chris@87 472 assert_almost_equal(ev, evalues)
Chris@87 473
Chris@87 474 def test_types(self):
Chris@87 475 def check(dtype):
Chris@87 476 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 477 assert_equal(linalg.eigvals(x).dtype, dtype)
Chris@87 478 x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
Chris@87 479 assert_equal(linalg.eigvals(x).dtype, get_complex_dtype(dtype))
Chris@87 480 for dtype in [single, double, csingle, cdouble]:
Chris@87 481 yield check, dtype
Chris@87 482
Chris@87 483
Chris@87 484 class TestEig(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 485 def do(self, a, b):
Chris@87 486 evalues, evectors = linalg.eig(a)
Chris@87 487 assert_allclose(dot_generalized(a, evectors),
Chris@87 488 np.asarray(evectors) * np.asarray(evalues)[...,None,:],
Chris@87 489 rtol=get_rtol(evalues.dtype))
Chris@87 490 assert_(imply(isinstance(a, matrix), isinstance(evectors, matrix)))
Chris@87 491
Chris@87 492 def test_types(self):
Chris@87 493 def check(dtype):
Chris@87 494 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 495 w, v = np.linalg.eig(x)
Chris@87 496 assert_equal(w.dtype, dtype)
Chris@87 497 assert_equal(v.dtype, dtype)
Chris@87 498
Chris@87 499 x = np.array([[1, 0.5], [-1, 1]], dtype=dtype)
Chris@87 500 w, v = np.linalg.eig(x)
Chris@87 501 assert_equal(w.dtype, get_complex_dtype(dtype))
Chris@87 502 assert_equal(v.dtype, get_complex_dtype(dtype))
Chris@87 503
Chris@87 504 for dtype in [single, double, csingle, cdouble]:
Chris@87 505 yield check, dtype
Chris@87 506
Chris@87 507
Chris@87 508 class TestSVD(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 509 def do(self, a, b):
Chris@87 510 u, s, vt = linalg.svd(a, 0)
Chris@87 511 assert_allclose(a, dot_generalized(np.asarray(u) * np.asarray(s)[...,None,:],
Chris@87 512 np.asarray(vt)),
Chris@87 513 rtol=get_rtol(u.dtype))
Chris@87 514 assert_(imply(isinstance(a, matrix), isinstance(u, matrix)))
Chris@87 515 assert_(imply(isinstance(a, matrix), isinstance(vt, matrix)))
Chris@87 516
Chris@87 517 def test_types(self):
Chris@87 518 def check(dtype):
Chris@87 519 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 520 u, s, vh = linalg.svd(x)
Chris@87 521 assert_equal(u.dtype, dtype)
Chris@87 522 assert_equal(s.dtype, get_real_dtype(dtype))
Chris@87 523 assert_equal(vh.dtype, dtype)
Chris@87 524 s = linalg.svd(x, compute_uv=False)
Chris@87 525 assert_equal(s.dtype, get_real_dtype(dtype))
Chris@87 526
Chris@87 527 for dtype in [single, double, csingle, cdouble]:
Chris@87 528 yield check, dtype
Chris@87 529
Chris@87 530
Chris@87 531 class TestCondSVD(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 532 def do(self, a, b):
Chris@87 533 c = asarray(a) # a might be a matrix
Chris@87 534 s = linalg.svd(c, compute_uv=False)
Chris@87 535 old_assert_almost_equal(s[0]/s[-1], linalg.cond(a), decimal=5)
Chris@87 536
Chris@87 537
Chris@87 538 class TestCond2(LinalgTestCase):
Chris@87 539 def do(self, a, b):
Chris@87 540 c = asarray(a) # a might be a matrix
Chris@87 541 s = linalg.svd(c, compute_uv=False)
Chris@87 542 old_assert_almost_equal(s[0]/s[-1], linalg.cond(a, 2), decimal=5)
Chris@87 543
Chris@87 544
Chris@87 545 class TestCondInf(object):
Chris@87 546 def test(self):
Chris@87 547 A = array([[1., 0, 0], [0, -2., 0], [0, 0, 3.]])
Chris@87 548 assert_almost_equal(linalg.cond(A, inf), 3.)
Chris@87 549
Chris@87 550
Chris@87 551 class TestPinv(LinalgTestCase):
Chris@87 552 def do(self, a, b):
Chris@87 553 a_ginv = linalg.pinv(a)
Chris@87 554 assert_almost_equal(dot(a, a_ginv), identity(asarray(a).shape[0]))
Chris@87 555 assert_(imply(isinstance(a, matrix), isinstance(a_ginv, matrix)))
Chris@87 556
Chris@87 557
Chris@87 558 class TestDet(LinalgTestCase, LinalgGeneralizedTestCase):
Chris@87 559 def do(self, a, b):
Chris@87 560 d = linalg.det(a)
Chris@87 561 (s, ld) = linalg.slogdet(a)
Chris@87 562 if asarray(a).dtype.type in (single, double):
Chris@87 563 ad = asarray(a).astype(double)
Chris@87 564 else:
Chris@87 565 ad = asarray(a).astype(cdouble)
Chris@87 566 ev = linalg.eigvals(ad)
Chris@87 567 assert_almost_equal(d, multiply.reduce(ev, axis=-1))
Chris@87 568 assert_almost_equal(s * np.exp(ld), multiply.reduce(ev, axis=-1))
Chris@87 569
Chris@87 570 s = np.atleast_1d(s)
Chris@87 571 ld = np.atleast_1d(ld)
Chris@87 572 m = (s != 0)
Chris@87 573 assert_almost_equal(np.abs(s[m]), 1)
Chris@87 574 assert_equal(ld[~m], -inf)
Chris@87 575
Chris@87 576 def test_zero(self):
Chris@87 577 assert_equal(linalg.det([[0.0]]), 0.0)
Chris@87 578 assert_equal(type(linalg.det([[0.0]])), double)
Chris@87 579 assert_equal(linalg.det([[0.0j]]), 0.0)
Chris@87 580 assert_equal(type(linalg.det([[0.0j]])), cdouble)
Chris@87 581
Chris@87 582 assert_equal(linalg.slogdet([[0.0]]), (0.0, -inf))
Chris@87 583 assert_equal(type(linalg.slogdet([[0.0]])[0]), double)
Chris@87 584 assert_equal(type(linalg.slogdet([[0.0]])[1]), double)
Chris@87 585 assert_equal(linalg.slogdet([[0.0j]]), (0.0j, -inf))
Chris@87 586 assert_equal(type(linalg.slogdet([[0.0j]])[0]), cdouble)
Chris@87 587 assert_equal(type(linalg.slogdet([[0.0j]])[1]), double)
Chris@87 588
Chris@87 589 def test_types(self):
Chris@87 590 def check(dtype):
Chris@87 591 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 592 assert_equal(np.linalg.det(x).dtype, dtype)
Chris@87 593 ph, s = np.linalg.slogdet(x)
Chris@87 594 assert_equal(s.dtype, get_real_dtype(dtype))
Chris@87 595 assert_equal(ph.dtype, dtype)
Chris@87 596 for dtype in [single, double, csingle, cdouble]:
Chris@87 597 yield check, dtype
Chris@87 598
Chris@87 599
Chris@87 600 class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase):
Chris@87 601 def do(self, a, b):
Chris@87 602 arr = np.asarray(a)
Chris@87 603 m, n = arr.shape
Chris@87 604 u, s, vt = linalg.svd(a, 0)
Chris@87 605 x, residuals, rank, sv = linalg.lstsq(a, b)
Chris@87 606 if m <= n:
Chris@87 607 assert_almost_equal(b, dot(a, x))
Chris@87 608 assert_equal(rank, m)
Chris@87 609 else:
Chris@87 610 assert_equal(rank, n)
Chris@87 611 assert_almost_equal(sv, sv.__array_wrap__(s))
Chris@87 612 if rank == n and m > n:
Chris@87 613 expect_resids = (np.asarray(abs(np.dot(a, x) - b))**2).sum(axis=0)
Chris@87 614 expect_resids = np.asarray(expect_resids)
Chris@87 615 if len(np.asarray(b).shape) == 1:
Chris@87 616 expect_resids.shape = (1,)
Chris@87 617 assert_equal(residuals.shape, expect_resids.shape)
Chris@87 618 else:
Chris@87 619 expect_resids = np.array([]).view(type(x))
Chris@87 620 assert_almost_equal(residuals, expect_resids)
Chris@87 621 assert_(np.issubdtype(residuals.dtype, np.floating))
Chris@87 622 assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
Chris@87 623 assert_(imply(isinstance(b, matrix), isinstance(residuals, matrix)))
Chris@87 624
Chris@87 625
Chris@87 626 class TestMatrixPower(object):
Chris@87 627 R90 = array([[0, 1], [-1, 0]])
Chris@87 628 Arb22 = array([[4, -7], [-2, 10]])
Chris@87 629 noninv = array([[1, 0], [0, 0]])
Chris@87 630 arbfloat = array([[0.1, 3.2], [1.2, 0.7]])
Chris@87 631
Chris@87 632 large = identity(10)
Chris@87 633 t = large[1,:].copy()
Chris@87 634 large[1,:] = large[0,:]
Chris@87 635 large[0,:] = t
Chris@87 636
Chris@87 637 def test_large_power(self):
Chris@87 638 assert_equal(matrix_power(self.R90, 2**100+2**10+2**5+1), self.R90)
Chris@87 639
Chris@87 640 def test_large_power_trailing_zero(self):
Chris@87 641 assert_equal(matrix_power(self.R90, 2**100+2**10+2**5), identity(2))
Chris@87 642
Chris@87 643 def testip_zero(self):
Chris@87 644 def tz(M):
Chris@87 645 mz = matrix_power(M, 0)
Chris@87 646 assert_equal(mz, identity(M.shape[0]))
Chris@87 647 assert_equal(mz.dtype, M.dtype)
Chris@87 648 for M in [self.Arb22, self.arbfloat, self.large]:
Chris@87 649 yield tz, M
Chris@87 650
Chris@87 651 def testip_one(self):
Chris@87 652 def tz(M):
Chris@87 653 mz = matrix_power(M, 1)
Chris@87 654 assert_equal(mz, M)
Chris@87 655 assert_equal(mz.dtype, M.dtype)
Chris@87 656 for M in [self.Arb22, self.arbfloat, self.large]:
Chris@87 657 yield tz, M
Chris@87 658
Chris@87 659 def testip_two(self):
Chris@87 660 def tz(M):
Chris@87 661 mz = matrix_power(M, 2)
Chris@87 662 assert_equal(mz, dot(M, M))
Chris@87 663 assert_equal(mz.dtype, M.dtype)
Chris@87 664 for M in [self.Arb22, self.arbfloat, self.large]:
Chris@87 665 yield tz, M
Chris@87 666
Chris@87 667 def testip_invert(self):
Chris@87 668 def tz(M):
Chris@87 669 mz = matrix_power(M, -1)
Chris@87 670 assert_almost_equal(identity(M.shape[0]), dot(mz, M))
Chris@87 671 for M in [self.R90, self.Arb22, self.arbfloat, self.large]:
Chris@87 672 yield tz, M
Chris@87 673
Chris@87 674 def test_invert_noninvertible(self):
Chris@87 675 import numpy.linalg
Chris@87 676 assert_raises(numpy.linalg.linalg.LinAlgError,
Chris@87 677 lambda: matrix_power(self.noninv, -1))
Chris@87 678
Chris@87 679
Chris@87 680 class TestBoolPower(object):
Chris@87 681 def test_square(self):
Chris@87 682 A = array([[True, False], [True, True]])
Chris@87 683 assert_equal(matrix_power(A, 2), A)
Chris@87 684
Chris@87 685
Chris@87 686 class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase):
Chris@87 687 def do(self, a, b):
Chris@87 688 # note that eigenvalue arrays must be sorted since
Chris@87 689 # their order isn't guaranteed.
Chris@87 690 ev = linalg.eigvalsh(a, 'L')
Chris@87 691 evalues, evectors = linalg.eig(a)
Chris@87 692 ev.sort(axis=-1)
Chris@87 693 evalues.sort(axis=-1)
Chris@87 694 assert_allclose(ev, evalues,
Chris@87 695 rtol=get_rtol(ev.dtype))
Chris@87 696
Chris@87 697 ev2 = linalg.eigvalsh(a, 'U')
Chris@87 698 ev2.sort(axis=-1)
Chris@87 699 assert_allclose(ev2, evalues,
Chris@87 700 rtol=get_rtol(ev.dtype))
Chris@87 701
Chris@87 702 def test_types(self):
Chris@87 703 def check(dtype):
Chris@87 704 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 705 w = np.linalg.eigvalsh(x)
Chris@87 706 assert_equal(w.dtype, get_real_dtype(dtype))
Chris@87 707 for dtype in [single, double, csingle, cdouble]:
Chris@87 708 yield check, dtype
Chris@87 709
Chris@87 710 def test_invalid(self):
Chris@87 711 x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
Chris@87 712 assert_raises(ValueError, np.linalg.eigvalsh, x, UPLO="lrong")
Chris@87 713 assert_raises(ValueError, np.linalg.eigvalsh, x, "lower")
Chris@87 714 assert_raises(ValueError, np.linalg.eigvalsh, x, "upper")
Chris@87 715
Chris@87 716 def test_UPLO(self):
Chris@87 717 Klo = np.array([[0, 0],[1, 0]], dtype=np.double)
Chris@87 718 Kup = np.array([[0, 1],[0, 0]], dtype=np.double)
Chris@87 719 tgt = np.array([-1, 1], dtype=np.double)
Chris@87 720 rtol = get_rtol(np.double)
Chris@87 721
Chris@87 722 # Check default is 'L'
Chris@87 723 w = np.linalg.eigvalsh(Klo)
Chris@87 724 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 725 # Check 'L'
Chris@87 726 w = np.linalg.eigvalsh(Klo, UPLO='L')
Chris@87 727 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 728 # Check 'l'
Chris@87 729 w = np.linalg.eigvalsh(Klo, UPLO='l')
Chris@87 730 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 731 # Check 'U'
Chris@87 732 w = np.linalg.eigvalsh(Kup, UPLO='U')
Chris@87 733 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 734 # Check 'u'
Chris@87 735 w = np.linalg.eigvalsh(Kup, UPLO='u')
Chris@87 736 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 737
Chris@87 738
Chris@87 739 class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
Chris@87 740 def do(self, a, b):
Chris@87 741 # note that eigenvalue arrays must be sorted since
Chris@87 742 # their order isn't guaranteed.
Chris@87 743 ev, evc = linalg.eigh(a)
Chris@87 744 evalues, evectors = linalg.eig(a)
Chris@87 745 ev.sort(axis=-1)
Chris@87 746 evalues.sort(axis=-1)
Chris@87 747 assert_almost_equal(ev, evalues)
Chris@87 748
Chris@87 749 assert_allclose(dot_generalized(a, evc),
Chris@87 750 np.asarray(ev)[...,None,:] * np.asarray(evc),
Chris@87 751 rtol=get_rtol(ev.dtype))
Chris@87 752
Chris@87 753 ev2, evc2 = linalg.eigh(a, 'U')
Chris@87 754 ev2.sort(axis=-1)
Chris@87 755 assert_almost_equal(ev2, evalues)
Chris@87 756
Chris@87 757 assert_allclose(dot_generalized(a, evc2),
Chris@87 758 np.asarray(ev2)[...,None,:] * np.asarray(evc2),
Chris@87 759 rtol=get_rtol(ev.dtype), err_msg=repr(a))
Chris@87 760
Chris@87 761 def test_types(self):
Chris@87 762 def check(dtype):
Chris@87 763 x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype)
Chris@87 764 w, v = np.linalg.eigh(x)
Chris@87 765 assert_equal(w.dtype, get_real_dtype(dtype))
Chris@87 766 assert_equal(v.dtype, dtype)
Chris@87 767 for dtype in [single, double, csingle, cdouble]:
Chris@87 768 yield check, dtype
Chris@87 769
Chris@87 770 def test_invalid(self):
Chris@87 771 x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
Chris@87 772 assert_raises(ValueError, np.linalg.eigh, x, UPLO="lrong")
Chris@87 773 assert_raises(ValueError, np.linalg.eigh, x, "lower")
Chris@87 774 assert_raises(ValueError, np.linalg.eigh, x, "upper")
Chris@87 775
Chris@87 776 def test_UPLO(self):
Chris@87 777 Klo = np.array([[0, 0],[1, 0]], dtype=np.double)
Chris@87 778 Kup = np.array([[0, 1],[0, 0]], dtype=np.double)
Chris@87 779 tgt = np.array([-1, 1], dtype=np.double)
Chris@87 780 rtol = get_rtol(np.double)
Chris@87 781
Chris@87 782 # Check default is 'L'
Chris@87 783 w, v = np.linalg.eigh(Klo)
Chris@87 784 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 785 # Check 'L'
Chris@87 786 w, v = np.linalg.eigh(Klo, UPLO='L')
Chris@87 787 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 788 # Check 'l'
Chris@87 789 w, v = np.linalg.eigh(Klo, UPLO='l')
Chris@87 790 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 791 # Check 'U'
Chris@87 792 w, v = np.linalg.eigh(Kup, UPLO='U')
Chris@87 793 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 794 # Check 'u'
Chris@87 795 w, v = np.linalg.eigh(Kup, UPLO='u')
Chris@87 796 assert_allclose(np.sort(w), tgt, rtol=rtol)
Chris@87 797
Chris@87 798
Chris@87 799 class _TestNorm(object):
Chris@87 800
Chris@87 801 dt = None
Chris@87 802 dec = None
Chris@87 803
Chris@87 804 def test_empty(self):
Chris@87 805 assert_equal(norm([]), 0.0)
Chris@87 806 assert_equal(norm(array([], dtype=self.dt)), 0.0)
Chris@87 807 assert_equal(norm(atleast_2d(array([], dtype=self.dt))), 0.0)
Chris@87 808
Chris@87 809 def test_vector(self):
Chris@87 810 a = [1, 2, 3, 4]
Chris@87 811 b = [-1, -2, -3, -4]
Chris@87 812 c = [-1, 2, -3, 4]
Chris@87 813
Chris@87 814 def _test(v):
Chris@87 815 np.testing.assert_almost_equal(norm(v), 30**0.5,
Chris@87 816 decimal=self.dec)
Chris@87 817 np.testing.assert_almost_equal(norm(v, inf), 4.0,
Chris@87 818 decimal=self.dec)
Chris@87 819 np.testing.assert_almost_equal(norm(v, -inf), 1.0,
Chris@87 820 decimal=self.dec)
Chris@87 821 np.testing.assert_almost_equal(norm(v, 1), 10.0,
Chris@87 822 decimal=self.dec)
Chris@87 823 np.testing.assert_almost_equal(norm(v, -1), 12.0/25,
Chris@87 824 decimal=self.dec)
Chris@87 825 np.testing.assert_almost_equal(norm(v, 2), 30**0.5,
Chris@87 826 decimal=self.dec)
Chris@87 827 np.testing.assert_almost_equal(norm(v, -2), ((205./144)**-0.5),
Chris@87 828 decimal=self.dec)
Chris@87 829 np.testing.assert_almost_equal(norm(v, 0), 4,
Chris@87 830 decimal=self.dec)
Chris@87 831
Chris@87 832 for v in (a, b, c,):
Chris@87 833 _test(v)
Chris@87 834
Chris@87 835 for v in (array(a, dtype=self.dt), array(b, dtype=self.dt),
Chris@87 836 array(c, dtype=self.dt)):
Chris@87 837 _test(v)
Chris@87 838
Chris@87 839 def test_matrix(self):
Chris@87 840 A = matrix([[1, 3], [5, 7]], dtype=self.dt)
Chris@87 841 assert_almost_equal(norm(A), 84**0.5)
Chris@87 842 assert_almost_equal(norm(A, 'fro'), 84**0.5)
Chris@87 843 assert_almost_equal(norm(A, inf), 12.0)
Chris@87 844 assert_almost_equal(norm(A, -inf), 4.0)
Chris@87 845 assert_almost_equal(norm(A, 1), 10.0)
Chris@87 846 assert_almost_equal(norm(A, -1), 6.0)
Chris@87 847 assert_almost_equal(norm(A, 2), 9.1231056256176615)
Chris@87 848 assert_almost_equal(norm(A, -2), 0.87689437438234041)
Chris@87 849
Chris@87 850 assert_raises(ValueError, norm, A, 'nofro')
Chris@87 851 assert_raises(ValueError, norm, A, -3)
Chris@87 852 assert_raises(ValueError, norm, A, 0)
Chris@87 853
Chris@87 854 def test_axis(self):
Chris@87 855 # Vector norms.
Chris@87 856 # Compare the use of `axis` with computing the norm of each row
Chris@87 857 # or column separately.
Chris@87 858 A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt)
Chris@87 859 for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]:
Chris@87 860 expected0 = [norm(A[:, k], ord=order) for k in range(A.shape[1])]
Chris@87 861 assert_almost_equal(norm(A, ord=order, axis=0), expected0)
Chris@87 862 expected1 = [norm(A[k,:], ord=order) for k in range(A.shape[0])]
Chris@87 863 assert_almost_equal(norm(A, ord=order, axis=1), expected1)
Chris@87 864
Chris@87 865 # Matrix norms.
Chris@87 866 B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
Chris@87 867
Chris@87 868 for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro']:
Chris@87 869 assert_almost_equal(norm(A, ord=order), norm(A, ord=order,
Chris@87 870 axis=(0, 1)))
Chris@87 871
Chris@87 872 n = norm(B, ord=order, axis=(1, 2))
Chris@87 873 expected = [norm(B[k], ord=order) for k in range(B.shape[0])]
Chris@87 874 assert_almost_equal(n, expected)
Chris@87 875
Chris@87 876 n = norm(B, ord=order, axis=(2, 1))
Chris@87 877 expected = [norm(B[k].T, ord=order) for k in range(B.shape[0])]
Chris@87 878 assert_almost_equal(n, expected)
Chris@87 879
Chris@87 880 n = norm(B, ord=order, axis=(0, 2))
Chris@87 881 expected = [norm(B[:, k,:], ord=order) for k in range(B.shape[1])]
Chris@87 882 assert_almost_equal(n, expected)
Chris@87 883
Chris@87 884 n = norm(B, ord=order, axis=(0, 1))
Chris@87 885 expected = [norm(B[:,:, k], ord=order) for k in range(B.shape[2])]
Chris@87 886 assert_almost_equal(n, expected)
Chris@87 887
Chris@87 888 def test_bad_args(self):
Chris@87 889 # Check that bad arguments raise the appropriate exceptions.
Chris@87 890
Chris@87 891 A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt)
Chris@87 892 B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4)
Chris@87 893
Chris@87 894 # Using `axis=<integer>` or passing in a 1-D array implies vector
Chris@87 895 # norms are being computed, so also using `ord='fro'` raises a
Chris@87 896 # ValueError.
Chris@87 897 assert_raises(ValueError, norm, A, 'fro', 0)
Chris@87 898 assert_raises(ValueError, norm, [3, 4], 'fro', None)
Chris@87 899
Chris@87 900 # Similarly, norm should raise an exception when ord is any finite
Chris@87 901 # number other than 1, 2, -1 or -2 when computing matrix norms.
Chris@87 902 for order in [0, 3]:
Chris@87 903 assert_raises(ValueError, norm, A, order, None)
Chris@87 904 assert_raises(ValueError, norm, A, order, (0, 1))
Chris@87 905 assert_raises(ValueError, norm, B, order, (1, 2))
Chris@87 906
Chris@87 907 # Invalid axis
Chris@87 908 assert_raises(ValueError, norm, B, None, 3)
Chris@87 909 assert_raises(ValueError, norm, B, None, (2, 3))
Chris@87 910 assert_raises(ValueError, norm, B, None, (0, 1, 2))
Chris@87 911
Chris@87 912 def test_longdouble_norm(self):
Chris@87 913 # Non-regression test: p-norm of longdouble would previously raise
Chris@87 914 # UnboundLocalError.
Chris@87 915 x = np.arange(10, dtype=np.longdouble)
Chris@87 916 old_assert_almost_equal(norm(x, ord=3), 12.65, decimal=2)
Chris@87 917
Chris@87 918 def test_intmin(self):
Chris@87 919 # Non-regression test: p-norm of signed integer would previously do
Chris@87 920 # float cast and abs in the wrong order.
Chris@87 921 x = np.array([-2 ** 31], dtype=np.int32)
Chris@87 922 old_assert_almost_equal(norm(x, ord=3), 2 ** 31, decimal=5)
Chris@87 923
Chris@87 924 def test_complex_high_ord(self):
Chris@87 925 # gh-4156
Chris@87 926 d = np.empty((2,), dtype=np.clongdouble)
Chris@87 927 d[0] = 6+7j
Chris@87 928 d[1] = -6+7j
Chris@87 929 res = 11.615898132184
Chris@87 930 old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=10)
Chris@87 931 d = d.astype(np.complex128)
Chris@87 932 old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=9)
Chris@87 933 d = d.astype(np.complex64)
Chris@87 934 old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=5)
Chris@87 935
Chris@87 936
Chris@87 937 class TestNormDouble(_TestNorm):
Chris@87 938 dt = np.double
Chris@87 939 dec = 12
Chris@87 940
Chris@87 941
Chris@87 942 class TestNormSingle(_TestNorm):
Chris@87 943 dt = np.float32
Chris@87 944 dec = 6
Chris@87 945
Chris@87 946
Chris@87 947 class TestNormInt64(_TestNorm):
Chris@87 948 dt = np.int64
Chris@87 949 dec = 12
Chris@87 950
Chris@87 951
Chris@87 952 class TestMatrixRank(object):
Chris@87 953 def test_matrix_rank(self):
Chris@87 954 # Full rank matrix
Chris@87 955 yield assert_equal, 4, matrix_rank(np.eye(4))
Chris@87 956 # rank deficient matrix
Chris@87 957 I=np.eye(4); I[-1, -1] = 0.
Chris@87 958 yield assert_equal, matrix_rank(I), 3
Chris@87 959 # All zeros - zero rank
Chris@87 960 yield assert_equal, matrix_rank(np.zeros((4, 4))), 0
Chris@87 961 # 1 dimension - rank 1 unless all 0
Chris@87 962 yield assert_equal, matrix_rank([1, 0, 0, 0]), 1
Chris@87 963 yield assert_equal, matrix_rank(np.zeros((4,))), 0
Chris@87 964 # accepts array-like
Chris@87 965 yield assert_equal, matrix_rank([1]), 1
Chris@87 966 # greater than 2 dimensions raises error
Chris@87 967 yield assert_raises, TypeError, matrix_rank, np.zeros((2, 2, 2))
Chris@87 968 # works on scalar
Chris@87 969 yield assert_equal, matrix_rank(1), 1
Chris@87 970
Chris@87 971
Chris@87 972 def test_reduced_rank():
Chris@87 973 # Test matrices with reduced rank
Chris@87 974 rng = np.random.RandomState(20120714)
Chris@87 975 for i in range(100):
Chris@87 976 # Make a rank deficient matrix
Chris@87 977 X = rng.normal(size=(40, 10))
Chris@87 978 X[:, 0] = X[:, 1] + X[:, 2]
Chris@87 979 # Assert that matrix_rank detected deficiency
Chris@87 980 assert_equal(matrix_rank(X), 9)
Chris@87 981 X[:, 3] = X[:, 4] + X[:, 5]
Chris@87 982 assert_equal(matrix_rank(X), 8)
Chris@87 983
Chris@87 984
Chris@87 985 class TestQR(object):
Chris@87 986
Chris@87 987 def check_qr(self, a):
Chris@87 988 # This test expects the argument `a` to be an ndarray or
Chris@87 989 # a subclass of an ndarray of inexact type.
Chris@87 990 a_type = type(a)
Chris@87 991 a_dtype = a.dtype
Chris@87 992 m, n = a.shape
Chris@87 993 k = min(m, n)
Chris@87 994
Chris@87 995 # mode == 'complete'
Chris@87 996 q, r = linalg.qr(a, mode='complete')
Chris@87 997 assert_(q.dtype == a_dtype)
Chris@87 998 assert_(r.dtype == a_dtype)
Chris@87 999 assert_(isinstance(q, a_type))
Chris@87 1000 assert_(isinstance(r, a_type))
Chris@87 1001 assert_(q.shape == (m, m))
Chris@87 1002 assert_(r.shape == (m, n))
Chris@87 1003 assert_almost_equal(dot(q, r), a)
Chris@87 1004 assert_almost_equal(dot(q.T.conj(), q), np.eye(m))
Chris@87 1005 assert_almost_equal(np.triu(r), r)
Chris@87 1006
Chris@87 1007 # mode == 'reduced'
Chris@87 1008 q1, r1 = linalg.qr(a, mode='reduced')
Chris@87 1009 assert_(q1.dtype == a_dtype)
Chris@87 1010 assert_(r1.dtype == a_dtype)
Chris@87 1011 assert_(isinstance(q1, a_type))
Chris@87 1012 assert_(isinstance(r1, a_type))
Chris@87 1013 assert_(q1.shape == (m, k))
Chris@87 1014 assert_(r1.shape == (k, n))
Chris@87 1015 assert_almost_equal(dot(q1, r1), a)
Chris@87 1016 assert_almost_equal(dot(q1.T.conj(), q1), np.eye(k))
Chris@87 1017 assert_almost_equal(np.triu(r1), r1)
Chris@87 1018
Chris@87 1019 # mode == 'r'
Chris@87 1020 r2 = linalg.qr(a, mode='r')
Chris@87 1021 assert_(r2.dtype == a_dtype)
Chris@87 1022 assert_(isinstance(r2, a_type))
Chris@87 1023 assert_almost_equal(r2, r1)
Chris@87 1024
Chris@87 1025 def test_qr_empty(self):
Chris@87 1026 a = np.zeros((0, 2))
Chris@87 1027 assert_raises(linalg.LinAlgError, linalg.qr, a)
Chris@87 1028
Chris@87 1029 def test_mode_raw(self):
Chris@87 1030 # The factorization is not unique and varies between libraries,
Chris@87 1031 # so it is not possible to check against known values. Functional
Chris@87 1032 # testing is a possibility, but awaits the exposure of more
Chris@87 1033 # of the functions in lapack_lite. Consequently, this test is
Chris@87 1034 # very limited in scope. Note that the results are in FORTRAN
Chris@87 1035 # order, hence the h arrays are transposed.
Chris@87 1036 a = array([[1, 2], [3, 4], [5, 6]], dtype=np.double)
Chris@87 1037 b = a.astype(np.single)
Chris@87 1038
Chris@87 1039 # Test double
Chris@87 1040 h, tau = linalg.qr(a, mode='raw')
Chris@87 1041 assert_(h.dtype == np.double)
Chris@87 1042 assert_(tau.dtype == np.double)
Chris@87 1043 assert_(h.shape == (2, 3))
Chris@87 1044 assert_(tau.shape == (2,))
Chris@87 1045
Chris@87 1046 h, tau = linalg.qr(a.T, mode='raw')
Chris@87 1047 assert_(h.dtype == np.double)
Chris@87 1048 assert_(tau.dtype == np.double)
Chris@87 1049 assert_(h.shape == (3, 2))
Chris@87 1050 assert_(tau.shape == (2,))
Chris@87 1051
Chris@87 1052 def test_mode_all_but_economic(self):
Chris@87 1053 a = array([[1, 2], [3, 4]])
Chris@87 1054 b = array([[1, 2], [3, 4], [5, 6]])
Chris@87 1055 for dt in "fd":
Chris@87 1056 m1 = a.astype(dt)
Chris@87 1057 m2 = b.astype(dt)
Chris@87 1058 self.check_qr(m1)
Chris@87 1059 self.check_qr(m2)
Chris@87 1060 self.check_qr(m2.T)
Chris@87 1061 self.check_qr(matrix(m1))
Chris@87 1062 for dt in "fd":
Chris@87 1063 m1 = 1 + 1j * a.astype(dt)
Chris@87 1064 m2 = 1 + 1j * b.astype(dt)
Chris@87 1065 self.check_qr(m1)
Chris@87 1066 self.check_qr(m2)
Chris@87 1067 self.check_qr(m2.T)
Chris@87 1068 self.check_qr(matrix(m1))
Chris@87 1069
Chris@87 1070
Chris@87 1071 def test_byteorder_check():
Chris@87 1072 # Byte order check should pass for native order
Chris@87 1073 if sys.byteorder == 'little':
Chris@87 1074 native = '<'
Chris@87 1075 else:
Chris@87 1076 native = '>'
Chris@87 1077
Chris@87 1078 for dtt in (np.float32, np.float64):
Chris@87 1079 arr = np.eye(4, dtype=dtt)
Chris@87 1080 n_arr = arr.newbyteorder(native)
Chris@87 1081 sw_arr = arr.newbyteorder('S').byteswap()
Chris@87 1082 assert_equal(arr.dtype.byteorder, '=')
Chris@87 1083 for routine in (linalg.inv, linalg.det, linalg.pinv):
Chris@87 1084 # Normal call
Chris@87 1085 res = routine(arr)
Chris@87 1086 # Native but not '='
Chris@87 1087 assert_array_equal(res, routine(n_arr))
Chris@87 1088 # Swapped
Chris@87 1089 assert_array_equal(res, routine(sw_arr))
Chris@87 1090
Chris@87 1091
Chris@87 1092 def test_generalized_raise_multiloop():
Chris@87 1093 # It should raise an error even if the error doesn't occur in the
Chris@87 1094 # last iteration of the ufunc inner loop
Chris@87 1095
Chris@87 1096 invertible = np.array([[1, 2], [3, 4]])
Chris@87 1097 non_invertible = np.array([[1, 1], [1, 1]])
Chris@87 1098
Chris@87 1099 x = np.zeros([4, 4, 2, 2])[1::2]
Chris@87 1100 x[...] = invertible
Chris@87 1101 x[0, 0] = non_invertible
Chris@87 1102
Chris@87 1103 assert_raises(np.linalg.LinAlgError, np.linalg.inv, x)
Chris@87 1104
Chris@87 1105 def test_xerbla_override():
Chris@87 1106 # Check that our xerbla has been successfully linked in. If it is not,
Chris@87 1107 # the default xerbla routine is called, which prints a message to stdout
Chris@87 1108 # and may, or may not, abort the process depending on the LAPACK package.
Chris@87 1109 from nose import SkipTest
Chris@87 1110
Chris@87 1111 try:
Chris@87 1112 pid = os.fork()
Chris@87 1113 except (OSError, AttributeError):
Chris@87 1114 # fork failed, or not running on POSIX
Chris@87 1115 raise SkipTest("Not POSIX or fork failed.")
Chris@87 1116
Chris@87 1117 if pid == 0:
Chris@87 1118 # child; close i/o file handles
Chris@87 1119 os.close(1)
Chris@87 1120 os.close(0)
Chris@87 1121 # Avoid producing core files.
Chris@87 1122 import resource
Chris@87 1123 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
Chris@87 1124 # These calls may abort.
Chris@87 1125 try:
Chris@87 1126 np.linalg.lapack_lite.xerbla()
Chris@87 1127 except ValueError:
Chris@87 1128 pass
Chris@87 1129 except:
Chris@87 1130 os._exit(os.EX_CONFIG)
Chris@87 1131
Chris@87 1132 try:
Chris@87 1133 a = np.array([[1.]])
Chris@87 1134 np.linalg.lapack_lite.dorgqr(
Chris@87 1135 1, 1, 1, a,
Chris@87 1136 0, # <- invalid value
Chris@87 1137 a, a, 0, 0)
Chris@87 1138 except ValueError as e:
Chris@87 1139 if "DORGQR parameter number 5" in str(e):
Chris@87 1140 # success
Chris@87 1141 os._exit(os.EX_OK)
Chris@87 1142
Chris@87 1143 # Did not abort, but our xerbla was not linked in.
Chris@87 1144 os._exit(os.EX_CONFIG)
Chris@87 1145 else:
Chris@87 1146 # parent
Chris@87 1147 pid, status = os.wait()
Chris@87 1148 if os.WEXITSTATUS(status) != os.EX_OK or os.WIFSIGNALED(status):
Chris@87 1149 raise SkipTest('Numpy xerbla not linked in.')
Chris@87 1150
Chris@87 1151
Chris@87 1152 if __name__ == "__main__":
Chris@87 1153 run_module_suite()