using for loop to install conda package
This commit is contained in:
0
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__init__.py
vendored
Normal file
0
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__init__.py
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/__init__.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/__init__.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_basic.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_basic.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_blas.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_blas.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_cython_blas.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_cython_blas.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_cython_lapack.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_cython_lapack.cpython-311.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_cholesky.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_cholesky.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_cossin.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_cossin.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_ldl.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_ldl.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_polar.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_polar.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_update.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_decomp_update.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_fblas.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_fblas.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_interpolative.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_interpolative.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_lapack.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_lapack.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_matfuncs.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_matfuncs.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_matmul_toeplitz.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_matmul_toeplitz.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_misc.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_misc.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_procrustes.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_procrustes.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_sketches.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_sketches.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_solve_toeplitz.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_solve_toeplitz.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_solvers.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_solvers.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_special_matrices.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/__pycache__/test_special_matrices.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_15_data.npz
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_15_data.npz
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_18_data.npz
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_18_data.npz
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_19_data.npz
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_19_data.npz
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_20_data.npz
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_20_data.npz
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_6_data.npz
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/carex_6_data.npz
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/gendare_20170120_data.npz
vendored
Normal file
BIN
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/data/gendare_20170120_data.npz
vendored
Normal file
Binary file not shown.
1714
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_basic.py
vendored
Normal file
1714
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_basic.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1096
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_blas.py
vendored
Normal file
1096
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_blas.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
120
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_cython_blas.py
vendored
Normal file
120
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_cython_blas.py
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
import numpy as np
|
||||
from numpy.testing import (assert_allclose,
|
||||
assert_equal)
|
||||
import scipy.linalg.cython_blas as blas
|
||||
|
||||
class TestDGEMM:
|
||||
|
||||
def test_transposes(self):
|
||||
|
||||
a = np.arange(12, dtype='d').reshape((3, 4))[:2,:2]
|
||||
b = np.arange(1, 13, dtype='d').reshape((4, 3))[:2,:2]
|
||||
c = np.empty((2, 4))[:2,:2]
|
||||
|
||||
blas._test_dgemm(1., a, b, 0., c)
|
||||
assert_allclose(c, a.dot(b))
|
||||
|
||||
blas._test_dgemm(1., a.T, b, 0., c)
|
||||
assert_allclose(c, a.T.dot(b))
|
||||
|
||||
blas._test_dgemm(1., a, b.T, 0., c)
|
||||
assert_allclose(c, a.dot(b.T))
|
||||
|
||||
blas._test_dgemm(1., a.T, b.T, 0., c)
|
||||
assert_allclose(c, a.T.dot(b.T))
|
||||
|
||||
blas._test_dgemm(1., a, b, 0., c.T)
|
||||
assert_allclose(c, a.dot(b).T)
|
||||
|
||||
blas._test_dgemm(1., a.T, b, 0., c.T)
|
||||
assert_allclose(c, a.T.dot(b).T)
|
||||
|
||||
blas._test_dgemm(1., a, b.T, 0., c.T)
|
||||
assert_allclose(c, a.dot(b.T).T)
|
||||
|
||||
blas._test_dgemm(1., a.T, b.T, 0., c.T)
|
||||
assert_allclose(c, a.T.dot(b.T).T)
|
||||
|
||||
def test_shapes(self):
|
||||
a = np.arange(6, dtype='d').reshape((3, 2))
|
||||
b = np.arange(-6, 2, dtype='d').reshape((2, 4))
|
||||
c = np.empty((3, 4))
|
||||
|
||||
blas._test_dgemm(1., a, b, 0., c)
|
||||
assert_allclose(c, a.dot(b))
|
||||
|
||||
blas._test_dgemm(1., b.T, a.T, 0., c.T)
|
||||
assert_allclose(c, b.T.dot(a.T).T)
|
||||
|
||||
class TestWfuncPointers:
|
||||
""" Test the function pointers that are expected to fail on
|
||||
Mac OS X without the additional entry statement in their definitions
|
||||
in fblas_l1.pyf.src. """
|
||||
|
||||
def test_complex_args(self):
|
||||
|
||||
cx = np.array([.5 + 1.j, .25 - .375j, 12.5 - 4.j], np.complex64)
|
||||
cy = np.array([.8 + 2.j, .875 - .625j, -1. + 2.j], np.complex64)
|
||||
|
||||
assert_allclose(blas._test_cdotc(cx, cy),
|
||||
-17.6468753815+21.3718757629j, 5)
|
||||
assert_allclose(blas._test_cdotu(cx, cy),
|
||||
-6.11562538147+30.3156242371j, 5)
|
||||
|
||||
assert_equal(blas._test_icamax(cx), 3)
|
||||
|
||||
assert_allclose(blas._test_scasum(cx), 18.625, 5)
|
||||
assert_allclose(blas._test_scnrm2(cx), 13.1796483994, 5)
|
||||
|
||||
assert_allclose(blas._test_cdotc(cx[::2], cy[::2]),
|
||||
-18.1000003815+21.2000007629j, 5)
|
||||
assert_allclose(blas._test_cdotu(cx[::2], cy[::2]),
|
||||
-6.10000038147+30.7999992371j, 5)
|
||||
assert_allclose(blas._test_scasum(cx[::2]), 18., 5)
|
||||
assert_allclose(blas._test_scnrm2(cx[::2]), 13.1719398499, 5)
|
||||
|
||||
def test_double_args(self):
|
||||
|
||||
x = np.array([5., -3, -.5], np.float64)
|
||||
y = np.array([2, 1, .5], np.float64)
|
||||
|
||||
assert_allclose(blas._test_dasum(x), 8.5, 10)
|
||||
assert_allclose(blas._test_ddot(x, y), 6.75, 10)
|
||||
assert_allclose(blas._test_dnrm2(x), 5.85234975815, 10)
|
||||
|
||||
assert_allclose(blas._test_dasum(x[::2]), 5.5, 10)
|
||||
assert_allclose(blas._test_ddot(x[::2], y[::2]), 9.75, 10)
|
||||
assert_allclose(blas._test_dnrm2(x[::2]), 5.0249376297, 10)
|
||||
|
||||
assert_equal(blas._test_idamax(x), 1)
|
||||
|
||||
def test_float_args(self):
|
||||
|
||||
x = np.array([5., -3, -.5], np.float32)
|
||||
y = np.array([2, 1, .5], np.float32)
|
||||
|
||||
assert_equal(blas._test_isamax(x), 1)
|
||||
|
||||
assert_allclose(blas._test_sasum(x), 8.5, 5)
|
||||
assert_allclose(blas._test_sdot(x, y), 6.75, 5)
|
||||
assert_allclose(blas._test_snrm2(x), 5.85234975815, 5)
|
||||
|
||||
assert_allclose(blas._test_sasum(x[::2]), 5.5, 5)
|
||||
assert_allclose(blas._test_sdot(x[::2], y[::2]), 9.75, 5)
|
||||
assert_allclose(blas._test_snrm2(x[::2]), 5.0249376297, 5)
|
||||
|
||||
def test_double_complex_args(self):
|
||||
|
||||
cx = np.array([.5 + 1.j, .25 - .375j, 13. - 4.j], np.complex128)
|
||||
cy = np.array([.875 + 2.j, .875 - .625j, -1. + 2.j], np.complex128)
|
||||
|
||||
assert_equal(blas._test_izamax(cx), 3)
|
||||
|
||||
assert_allclose(blas._test_zdotc(cx, cy), -18.109375+22.296875j, 10)
|
||||
assert_allclose(blas._test_zdotu(cx, cy), -6.578125+31.390625j, 10)
|
||||
|
||||
assert_allclose(blas._test_zdotc(cx[::2], cy[::2]),
|
||||
-18.5625+22.125j, 10)
|
||||
assert_allclose(blas._test_zdotu(cx[::2], cy[::2]),
|
||||
-6.5625+31.875j, 10)
|
||||
|
||||
17
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_cython_lapack.py
vendored
Normal file
17
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_cython_lapack.py
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
from numpy.testing import assert_allclose
|
||||
from scipy.linalg import cython_lapack as cython_lapack
|
||||
from scipy.linalg import lapack
|
||||
|
||||
|
||||
class TestLamch:
|
||||
|
||||
def test_slamch(self):
|
||||
for c in [b'e', b's', b'b', b'p', b'n', b'r', b'm', b'u', b'l', b'o']:
|
||||
assert_allclose(cython_lapack._test_slamch(c),
|
||||
lapack.slamch(c))
|
||||
|
||||
def test_dlamch(self):
|
||||
for c in [b'e', b's', b'b', b'p', b'n', b'r', b'm', b'u', b'l', b'o']:
|
||||
assert_allclose(cython_lapack._test_dlamch(c),
|
||||
lapack.dlamch(c))
|
||||
|
||||
121
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_cythonized_array_utils.py
vendored
Normal file
121
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_cythonized_array_utils.py
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
import numpy as np
|
||||
from scipy.linalg import bandwidth, issymmetric, ishermitian
|
||||
import pytest
|
||||
from pytest import raises
|
||||
|
||||
|
||||
def test_bandwidth_dtypes():
|
||||
n = 5
|
||||
for t in np.typecodes['All']:
|
||||
A = np.zeros([n, n], dtype=t)
|
||||
if t in 'eUVOMm':
|
||||
raises(TypeError, bandwidth, A)
|
||||
elif t == 'G': # No-op test. On win these pass on others fail.
|
||||
pass
|
||||
else:
|
||||
_ = bandwidth(A)
|
||||
|
||||
|
||||
def test_bandwidth_non2d_input():
|
||||
A = np.array([1, 2, 3])
|
||||
raises(ValueError, bandwidth, A)
|
||||
A = np.array([[[1, 2, 3], [4, 5, 6]]])
|
||||
raises(ValueError, bandwidth, A)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('T', [x for x in np.typecodes['All']
|
||||
if x not in 'eGUVOMm'])
|
||||
def test_bandwidth_square_inputs(T):
|
||||
n = 20
|
||||
k = 4
|
||||
R = np.zeros([n, n], dtype=T, order='F')
|
||||
# form a banded matrix inplace
|
||||
R[[x for x in range(n)], [x for x in range(n)]] = 1
|
||||
R[[x for x in range(n-k)], [x for x in range(k, n)]] = 1
|
||||
R[[x for x in range(1, n)], [x for x in range(n-1)]] = 1
|
||||
R[[x for x in range(k, n)], [x for x in range(n-k)]] = 1
|
||||
assert bandwidth(R) == (k, k)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('T', [x for x in np.typecodes['All']
|
||||
if x not in 'eGUVOMm'])
|
||||
def test_bandwidth_rect_inputs(T):
|
||||
n, m = 10, 20
|
||||
k = 5
|
||||
R = np.zeros([n, m], dtype=T, order='F')
|
||||
# form a banded matrix inplace
|
||||
R[[x for x in range(n)], [x for x in range(n)]] = 1
|
||||
R[[x for x in range(n-k)], [x for x in range(k, n)]] = 1
|
||||
R[[x for x in range(1, n)], [x for x in range(n-1)]] = 1
|
||||
R[[x for x in range(k, n)], [x for x in range(n-k)]] = 1
|
||||
assert bandwidth(R) == (k, k)
|
||||
|
||||
|
||||
def test_issymetric_ishermitian_dtypes():
|
||||
n = 5
|
||||
for t in np.typecodes['All']:
|
||||
A = np.zeros([n, n], dtype=t)
|
||||
if t in 'eUVOMm':
|
||||
raises(TypeError, issymmetric, A)
|
||||
raises(TypeError, ishermitian, A)
|
||||
elif t == 'G': # No-op test. On win these pass on others fail.
|
||||
pass
|
||||
else:
|
||||
assert issymmetric(A)
|
||||
assert ishermitian(A)
|
||||
|
||||
|
||||
def test_issymmetric_ishermitian_invalid_input():
|
||||
A = np.array([1, 2, 3])
|
||||
raises(ValueError, issymmetric, A)
|
||||
raises(ValueError, ishermitian, A)
|
||||
A = np.array([[[1, 2, 3], [4, 5, 6]]])
|
||||
raises(ValueError, issymmetric, A)
|
||||
raises(ValueError, ishermitian, A)
|
||||
A = np.array([[1, 2, 3], [4, 5, 6]])
|
||||
raises(ValueError, issymmetric, A)
|
||||
raises(ValueError, ishermitian, A)
|
||||
|
||||
|
||||
def test_issymetric_complex_decimals():
|
||||
A = np.arange(1, 10).astype(complex).reshape(3, 3)
|
||||
A += np.arange(-4, 5).astype(complex).reshape(3, 3)*1j
|
||||
# make entries decimal
|
||||
A /= np.pi
|
||||
A = A + A.T
|
||||
assert issymmetric(A)
|
||||
|
||||
|
||||
def test_ishermitian_complex_decimals():
|
||||
A = np.arange(1, 10).astype(complex).reshape(3, 3)
|
||||
A += np.arange(-4, 5).astype(complex).reshape(3, 3)*1j
|
||||
# make entries decimal
|
||||
A /= np.pi
|
||||
A = A + A.T.conj()
|
||||
assert ishermitian(A)
|
||||
|
||||
|
||||
def test_issymmetric_approximate_results():
|
||||
n = 20
|
||||
rng = np.random.RandomState(123456789)
|
||||
x = rng.uniform(high=5., size=[n, n])
|
||||
y = x @ x.T # symmetric
|
||||
p = rng.standard_normal([n, n])
|
||||
z = p @ y @ p.T
|
||||
assert issymmetric(z, atol=1e-10)
|
||||
assert issymmetric(z, atol=1e-10, rtol=0.)
|
||||
assert issymmetric(z, atol=0., rtol=1e-12)
|
||||
assert issymmetric(z, atol=1e-13, rtol=1e-12)
|
||||
|
||||
|
||||
def test_ishermitian_approximate_results():
|
||||
n = 20
|
||||
rng = np.random.RandomState(987654321)
|
||||
x = rng.uniform(high=5., size=[n, n])
|
||||
y = x @ x.T # symmetric
|
||||
p = rng.standard_normal([n, n]) + rng.standard_normal([n, n])*1j
|
||||
z = p @ y @ p.conj().T
|
||||
assert ishermitian(z, atol=1e-10)
|
||||
assert ishermitian(z, atol=1e-10, rtol=0.)
|
||||
assert ishermitian(z, atol=0., rtol=1e-12)
|
||||
assert ishermitian(z, atol=1e-13, rtol=1e-12)
|
||||
2904
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp.py
vendored
Normal file
2904
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
202
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_cholesky.py
vendored
Normal file
202
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_cholesky.py
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
from numpy.testing import assert_array_almost_equal, assert_array_equal
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from numpy import array, transpose, dot, conjugate, zeros_like, empty
|
||||
from numpy.random import random
|
||||
from scipy.linalg import cholesky, cholesky_banded, cho_solve_banded, \
|
||||
cho_factor, cho_solve
|
||||
|
||||
from scipy.linalg._testutils import assert_no_overwrite
|
||||
|
||||
|
||||
class TestCholesky:
|
||||
|
||||
def test_simple(self):
|
||||
a = [[8, 2, 3], [2, 9, 3], [3, 3, 6]]
|
||||
c = cholesky(a)
|
||||
assert_array_almost_equal(dot(transpose(c), c), a)
|
||||
c = transpose(c)
|
||||
a = dot(c, transpose(c))
|
||||
assert_array_almost_equal(cholesky(a, lower=1), c)
|
||||
|
||||
def test_check_finite(self):
|
||||
a = [[8, 2, 3], [2, 9, 3], [3, 3, 6]]
|
||||
c = cholesky(a, check_finite=False)
|
||||
assert_array_almost_equal(dot(transpose(c), c), a)
|
||||
c = transpose(c)
|
||||
a = dot(c, transpose(c))
|
||||
assert_array_almost_equal(cholesky(a, lower=1, check_finite=False), c)
|
||||
|
||||
def test_simple_complex(self):
|
||||
m = array([[3+1j, 3+4j, 5], [0, 2+2j, 2+7j], [0, 0, 7+4j]])
|
||||
a = dot(transpose(conjugate(m)), m)
|
||||
c = cholesky(a)
|
||||
a1 = dot(transpose(conjugate(c)), c)
|
||||
assert_array_almost_equal(a, a1)
|
||||
c = transpose(c)
|
||||
a = dot(c, transpose(conjugate(c)))
|
||||
assert_array_almost_equal(cholesky(a, lower=1), c)
|
||||
|
||||
def test_random(self):
|
||||
n = 20
|
||||
for k in range(2):
|
||||
m = random([n, n])
|
||||
for i in range(n):
|
||||
m[i, i] = 20*(.1+m[i, i])
|
||||
a = dot(transpose(m), m)
|
||||
c = cholesky(a)
|
||||
a1 = dot(transpose(c), c)
|
||||
assert_array_almost_equal(a, a1)
|
||||
c = transpose(c)
|
||||
a = dot(c, transpose(c))
|
||||
assert_array_almost_equal(cholesky(a, lower=1), c)
|
||||
|
||||
def test_random_complex(self):
|
||||
n = 20
|
||||
for k in range(2):
|
||||
m = random([n, n])+1j*random([n, n])
|
||||
for i in range(n):
|
||||
m[i, i] = 20*(.1+abs(m[i, i]))
|
||||
a = dot(transpose(conjugate(m)), m)
|
||||
c = cholesky(a)
|
||||
a1 = dot(transpose(conjugate(c)), c)
|
||||
assert_array_almost_equal(a, a1)
|
||||
c = transpose(c)
|
||||
a = dot(c, transpose(conjugate(c)))
|
||||
assert_array_almost_equal(cholesky(a, lower=1), c)
|
||||
|
||||
|
||||
class TestCholeskyBanded:
|
||||
"""Tests for cholesky_banded() and cho_solve_banded."""
|
||||
|
||||
def test_check_finite(self):
|
||||
# Symmetric positive definite banded matrix `a`
|
||||
a = array([[4.0, 1.0, 0.0, 0.0],
|
||||
[1.0, 4.0, 0.5, 0.0],
|
||||
[0.0, 0.5, 4.0, 0.2],
|
||||
[0.0, 0.0, 0.2, 4.0]])
|
||||
# Banded storage form of `a`.
|
||||
ab = array([[-1.0, 1.0, 0.5, 0.2],
|
||||
[4.0, 4.0, 4.0, 4.0]])
|
||||
c = cholesky_banded(ab, lower=False, check_finite=False)
|
||||
ufac = zeros_like(a)
|
||||
ufac[list(range(4)), list(range(4))] = c[-1]
|
||||
ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
|
||||
assert_array_almost_equal(a, dot(ufac.T, ufac))
|
||||
|
||||
b = array([0.0, 0.5, 4.2, 4.2])
|
||||
x = cho_solve_banded((c, False), b, check_finite=False)
|
||||
assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
|
||||
|
||||
def test_upper_real(self):
|
||||
# Symmetric positive definite banded matrix `a`
|
||||
a = array([[4.0, 1.0, 0.0, 0.0],
|
||||
[1.0, 4.0, 0.5, 0.0],
|
||||
[0.0, 0.5, 4.0, 0.2],
|
||||
[0.0, 0.0, 0.2, 4.0]])
|
||||
# Banded storage form of `a`.
|
||||
ab = array([[-1.0, 1.0, 0.5, 0.2],
|
||||
[4.0, 4.0, 4.0, 4.0]])
|
||||
c = cholesky_banded(ab, lower=False)
|
||||
ufac = zeros_like(a)
|
||||
ufac[list(range(4)), list(range(4))] = c[-1]
|
||||
ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
|
||||
assert_array_almost_equal(a, dot(ufac.T, ufac))
|
||||
|
||||
b = array([0.0, 0.5, 4.2, 4.2])
|
||||
x = cho_solve_banded((c, False), b)
|
||||
assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
|
||||
|
||||
def test_upper_complex(self):
|
||||
# Hermitian positive definite banded matrix `a`
|
||||
a = array([[4.0, 1.0, 0.0, 0.0],
|
||||
[1.0, 4.0, 0.5, 0.0],
|
||||
[0.0, 0.5, 4.0, -0.2j],
|
||||
[0.0, 0.0, 0.2j, 4.0]])
|
||||
# Banded storage form of `a`.
|
||||
ab = array([[-1.0, 1.0, 0.5, -0.2j],
|
||||
[4.0, 4.0, 4.0, 4.0]])
|
||||
c = cholesky_banded(ab, lower=False)
|
||||
ufac = zeros_like(a)
|
||||
ufac[list(range(4)), list(range(4))] = c[-1]
|
||||
ufac[(0, 1, 2), (1, 2, 3)] = c[0, 1:]
|
||||
assert_array_almost_equal(a, dot(ufac.conj().T, ufac))
|
||||
|
||||
b = array([0.0, 0.5, 4.0-0.2j, 0.2j + 4.0])
|
||||
x = cho_solve_banded((c, False), b)
|
||||
assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
|
||||
|
||||
def test_lower_real(self):
|
||||
# Symmetric positive definite banded matrix `a`
|
||||
a = array([[4.0, 1.0, 0.0, 0.0],
|
||||
[1.0, 4.0, 0.5, 0.0],
|
||||
[0.0, 0.5, 4.0, 0.2],
|
||||
[0.0, 0.0, 0.2, 4.0]])
|
||||
# Banded storage form of `a`.
|
||||
ab = array([[4.0, 4.0, 4.0, 4.0],
|
||||
[1.0, 0.5, 0.2, -1.0]])
|
||||
c = cholesky_banded(ab, lower=True)
|
||||
lfac = zeros_like(a)
|
||||
lfac[list(range(4)), list(range(4))] = c[0]
|
||||
lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
|
||||
assert_array_almost_equal(a, dot(lfac, lfac.T))
|
||||
|
||||
b = array([0.0, 0.5, 4.2, 4.2])
|
||||
x = cho_solve_banded((c, True), b)
|
||||
assert_array_almost_equal(x, [0.0, 0.0, 1.0, 1.0])
|
||||
|
||||
def test_lower_complex(self):
|
||||
# Hermitian positive definite banded matrix `a`
|
||||
a = array([[4.0, 1.0, 0.0, 0.0],
|
||||
[1.0, 4.0, 0.5, 0.0],
|
||||
[0.0, 0.5, 4.0, -0.2j],
|
||||
[0.0, 0.0, 0.2j, 4.0]])
|
||||
# Banded storage form of `a`.
|
||||
ab = array([[4.0, 4.0, 4.0, 4.0],
|
||||
[1.0, 0.5, 0.2j, -1.0]])
|
||||
c = cholesky_banded(ab, lower=True)
|
||||
lfac = zeros_like(a)
|
||||
lfac[list(range(4)), list(range(4))] = c[0]
|
||||
lfac[(1, 2, 3), (0, 1, 2)] = c[1, :3]
|
||||
assert_array_almost_equal(a, dot(lfac, lfac.conj().T))
|
||||
|
||||
b = array([0.0, 0.5j, 3.8j, 3.8])
|
||||
x = cho_solve_banded((c, True), b)
|
||||
assert_array_almost_equal(x, [0.0, 0.0, 1.0j, 1.0])
|
||||
|
||||
|
||||
class TestOverwrite:
|
||||
def test_cholesky(self):
|
||||
assert_no_overwrite(cholesky, [(3, 3)])
|
||||
|
||||
def test_cho_factor(self):
|
||||
assert_no_overwrite(cho_factor, [(3, 3)])
|
||||
|
||||
def test_cho_solve(self):
|
||||
x = array([[2, -1, 0], [-1, 2, -1], [0, -1, 2]])
|
||||
xcho = cho_factor(x)
|
||||
assert_no_overwrite(lambda b: cho_solve(xcho, b), [(3,)])
|
||||
|
||||
def test_cholesky_banded(self):
|
||||
assert_no_overwrite(cholesky_banded, [(2, 3)])
|
||||
|
||||
def test_cho_solve_banded(self):
|
||||
x = array([[0, -1, -1], [2, 2, 2]])
|
||||
xcho = cholesky_banded(x)
|
||||
assert_no_overwrite(lambda b: cho_solve_banded((xcho, False), b),
|
||||
[(3,)])
|
||||
|
||||
|
||||
class TestEmptyArray:
|
||||
def test_cho_factor_empty_square(self):
|
||||
a = empty((0, 0))
|
||||
b = array([])
|
||||
c = array([[]])
|
||||
d = []
|
||||
e = [[]]
|
||||
|
||||
x, _ = cho_factor(a)
|
||||
assert_array_equal(x, a)
|
||||
|
||||
for x in ([b, c, d, e]):
|
||||
assert_raises(ValueError, cho_factor, x)
|
||||
155
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_cossin.py
vendored
Normal file
155
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_cossin.py
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
import pytest
|
||||
import numpy as np
|
||||
from numpy.random import seed
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
from scipy.linalg.lapack import _compute_lwork
|
||||
from scipy.stats import ortho_group, unitary_group
|
||||
from scipy.linalg import cossin, get_lapack_funcs
|
||||
|
||||
REAL_DTYPES = (np.float32, np.float64)
|
||||
COMPLEX_DTYPES = (np.complex64, np.complex128)
|
||||
DTYPES = REAL_DTYPES + COMPLEX_DTYPES
|
||||
|
||||
|
||||
@pytest.mark.parametrize('dtype_', DTYPES)
|
||||
@pytest.mark.parametrize('m, p, q',
|
||||
[
|
||||
(2, 1, 1),
|
||||
(3, 2, 1),
|
||||
(3, 1, 2),
|
||||
(4, 2, 2),
|
||||
(4, 1, 2),
|
||||
(40, 12, 20),
|
||||
(40, 30, 1),
|
||||
(40, 1, 30),
|
||||
(100, 50, 1),
|
||||
(100, 50, 50),
|
||||
])
|
||||
@pytest.mark.parametrize('swap_sign', [True, False])
|
||||
def test_cossin(dtype_, m, p, q, swap_sign):
|
||||
seed(1234)
|
||||
if dtype_ in COMPLEX_DTYPES:
|
||||
x = np.array(unitary_group.rvs(m), dtype=dtype_)
|
||||
else:
|
||||
x = np.array(ortho_group.rvs(m), dtype=dtype_)
|
||||
|
||||
u, cs, vh = cossin(x, p, q,
|
||||
swap_sign=swap_sign)
|
||||
assert_allclose(x, u @ cs @ vh, rtol=0., atol=m*1e3*np.finfo(dtype_).eps)
|
||||
assert u.dtype == dtype_
|
||||
# Test for float32 or float 64
|
||||
assert cs.dtype == np.real(u).dtype
|
||||
assert vh.dtype == dtype_
|
||||
|
||||
u, cs, vh = cossin([x[:p, :q], x[:p, q:], x[p:, :q], x[p:, q:]],
|
||||
swap_sign=swap_sign)
|
||||
assert_allclose(x, u @ cs @ vh, rtol=0., atol=m*1e3*np.finfo(dtype_).eps)
|
||||
assert u.dtype == dtype_
|
||||
assert cs.dtype == np.real(u).dtype
|
||||
assert vh.dtype == dtype_
|
||||
|
||||
_, cs2, vh2 = cossin(x, p, q,
|
||||
compute_u=False,
|
||||
swap_sign=swap_sign)
|
||||
assert_allclose(cs, cs2, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
assert_allclose(vh, vh2, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
|
||||
u2, cs2, _ = cossin(x, p, q,
|
||||
compute_vh=False,
|
||||
swap_sign=swap_sign)
|
||||
assert_allclose(u, u2, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
assert_allclose(cs, cs2, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
|
||||
_, cs2, _ = cossin(x, p, q,
|
||||
compute_u=False,
|
||||
compute_vh=False,
|
||||
swap_sign=swap_sign)
|
||||
assert_allclose(cs, cs2, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
|
||||
|
||||
def test_cossin_mixed_types():
|
||||
seed(1234)
|
||||
x = np.array(ortho_group.rvs(4), dtype=np.float64)
|
||||
u, cs, vh = cossin([x[:2, :2],
|
||||
np.array(x[:2, 2:], dtype=np.complex128),
|
||||
x[2:, :2],
|
||||
x[2:, 2:]])
|
||||
|
||||
assert u.dtype == np.complex128
|
||||
assert cs.dtype == np.float64
|
||||
assert vh.dtype == np.complex128
|
||||
assert_allclose(x, u @ cs @ vh, rtol=0.,
|
||||
atol=1e4 * np.finfo(np.complex128).eps)
|
||||
|
||||
|
||||
def test_cossin_error_incorrect_subblocks():
|
||||
with pytest.raises(ValueError, match="be due to missing p, q arguments."):
|
||||
cossin(([1, 2], [3, 4, 5], [6, 7], [8, 9, 10]))
|
||||
|
||||
|
||||
def test_cossin_error_empty_subblocks():
|
||||
with pytest.raises(ValueError, match="x11.*empty"):
|
||||
cossin(([], [], [], []))
|
||||
with pytest.raises(ValueError, match="x12.*empty"):
|
||||
cossin(([1, 2], [], [6, 7], [8, 9, 10]))
|
||||
with pytest.raises(ValueError, match="x21.*empty"):
|
||||
cossin(([1, 2], [3, 4, 5], [], [8, 9, 10]))
|
||||
with pytest.raises(ValueError, match="x22.*empty"):
|
||||
cossin(([1, 2], [3, 4, 5], [2], []))
|
||||
|
||||
|
||||
def test_cossin_error_missing_partitioning():
|
||||
with pytest.raises(ValueError, match=".*exactly four arrays.* got 2"):
|
||||
cossin(unitary_group.rvs(2))
|
||||
|
||||
with pytest.raises(ValueError, match=".*might be due to missing p, q"):
|
||||
cossin(unitary_group.rvs(4))
|
||||
|
||||
|
||||
def test_cossin_error_non_iterable():
|
||||
with pytest.raises(ValueError, match="containing the subblocks of X"):
|
||||
cossin(12j)
|
||||
|
||||
|
||||
def test_cossin_error_non_square():
|
||||
with pytest.raises(ValueError, match="only supports square"):
|
||||
cossin(np.array([[1, 2]]), 1, 1)
|
||||
|
||||
def test_cossin_error_partitioning():
|
||||
x = np.array(ortho_group.rvs(4), dtype=np.float64)
|
||||
with pytest.raises(ValueError, match="invalid p=0.*0<p<4.*"):
|
||||
cossin(x, 0, 1)
|
||||
with pytest.raises(ValueError, match="invalid p=4.*0<p<4.*"):
|
||||
cossin(x, 4, 1)
|
||||
with pytest.raises(ValueError, match="invalid q=-2.*0<q<4.*"):
|
||||
cossin(x, 1, -2)
|
||||
with pytest.raises(ValueError, match="invalid q=5.*0<q<4.*"):
|
||||
cossin(x, 1, 5)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("dtype_", DTYPES)
|
||||
def test_cossin_separate(dtype_):
|
||||
seed(1234)
|
||||
m, p, q = 250, 80, 170
|
||||
|
||||
pfx = 'or' if dtype_ in REAL_DTYPES else 'un'
|
||||
X = ortho_group.rvs(m) if pfx == 'or' else unitary_group.rvs(m)
|
||||
X = np.array(X, dtype=dtype_)
|
||||
|
||||
drv, dlw = get_lapack_funcs((pfx + 'csd', pfx + 'csd_lwork'),[X])
|
||||
lwval = _compute_lwork(dlw, m, p, q)
|
||||
lwvals = {'lwork': lwval} if pfx == 'or' else dict(zip(['lwork',
|
||||
'lrwork'],
|
||||
lwval))
|
||||
|
||||
*_, theta, u1, u2, v1t, v2t, _ = \
|
||||
drv(X[:p, :q], X[:p, q:], X[p:, :q], X[p:, q:], **lwvals)
|
||||
|
||||
(u1_2, u2_2), theta2, (v1t_2, v2t_2) = cossin(X, p, q, separate=True)
|
||||
|
||||
assert_allclose(u1_2, u1, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
assert_allclose(u2_2, u2, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
assert_allclose(v1t_2, v1t, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
assert_allclose(v2t_2, v2t, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
assert_allclose(theta2, theta, rtol=0., atol=10*np.finfo(dtype_).eps)
|
||||
136
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_ldl.py
vendored
Normal file
136
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_ldl.py
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
from numpy.testing import assert_array_almost_equal, assert_allclose, assert_
|
||||
from numpy import (array, eye, zeros, empty_like, empty, tril_indices_from,
|
||||
tril, triu_indices_from, spacing, float32, float64,
|
||||
complex64, complex128)
|
||||
from numpy.random import rand, randint, seed
|
||||
from scipy.linalg import ldl
|
||||
import pytest
|
||||
from pytest import raises as assert_raises, warns
|
||||
from numpy import ComplexWarning
|
||||
|
||||
|
||||
def test_args():
|
||||
A = eye(3)
|
||||
# Nonsquare array
|
||||
assert_raises(ValueError, ldl, A[:, :2])
|
||||
# Complex matrix with imaginary diagonal entries with "hermitian=True"
|
||||
with warns(ComplexWarning):
|
||||
ldl(A*1j)
|
||||
|
||||
|
||||
def test_empty_array():
|
||||
a = empty((0, 0), dtype=complex)
|
||||
l, d, p = ldl(empty((0, 0)))
|
||||
assert_array_almost_equal(l, empty_like(a))
|
||||
assert_array_almost_equal(d, empty_like(a))
|
||||
assert_array_almost_equal(p, array([], dtype=int))
|
||||
|
||||
|
||||
def test_simple():
|
||||
a = array([[-0.39-0.71j, 5.14-0.64j, -7.86-2.96j, 3.80+0.92j],
|
||||
[5.14-0.64j, 8.86+1.81j, -3.52+0.58j, 5.32-1.59j],
|
||||
[-7.86-2.96j, -3.52+0.58j, -2.83-0.03j, -1.54-2.86j],
|
||||
[3.80+0.92j, 5.32-1.59j, -1.54-2.86j, -0.56+0.12j]])
|
||||
b = array([[5., 10, 1, 18],
|
||||
[10., 2, 11, 1],
|
||||
[1., 11, 19, 9],
|
||||
[18., 1, 9, 0]])
|
||||
c = array([[52., 97, 112, 107, 50],
|
||||
[97., 114, 89, 98, 13],
|
||||
[112., 89, 64, 33, 6],
|
||||
[107., 98, 33, 60, 73],
|
||||
[50., 13, 6, 73, 77]])
|
||||
|
||||
d = array([[2., 2, -4, 0, 4],
|
||||
[2., -2, -2, 10, -8],
|
||||
[-4., -2, 6, -8, -4],
|
||||
[0., 10, -8, 6, -6],
|
||||
[4., -8, -4, -6, 10]])
|
||||
e = array([[-1.36+0.00j, 0+0j, 0+0j, 0+0j],
|
||||
[1.58-0.90j, -8.87+0j, 0+0j, 0+0j],
|
||||
[2.21+0.21j, -1.84+0.03j, -4.63+0j, 0+0j],
|
||||
[3.91-1.50j, -1.78-1.18j, 0.11-0.11j, -1.84+0.00j]])
|
||||
for x in (b, c, d):
|
||||
l, d, p = ldl(x)
|
||||
assert_allclose(l.dot(d).dot(l.T), x, atol=spacing(1000.), rtol=0)
|
||||
|
||||
u, d, p = ldl(x, lower=False)
|
||||
assert_allclose(u.dot(d).dot(u.T), x, atol=spacing(1000.), rtol=0)
|
||||
|
||||
l, d, p = ldl(a, hermitian=False)
|
||||
assert_allclose(l.dot(d).dot(l.T), a, atol=spacing(1000.), rtol=0)
|
||||
|
||||
u, d, p = ldl(a, lower=False, hermitian=False)
|
||||
assert_allclose(u.dot(d).dot(u.T), a, atol=spacing(1000.), rtol=0)
|
||||
|
||||
# Use upper part for the computation and use the lower part for comparison
|
||||
l, d, p = ldl(e.conj().T, lower=0)
|
||||
assert_allclose(tril(l.dot(d).dot(l.conj().T)-e), zeros((4, 4)),
|
||||
atol=spacing(1000.), rtol=0)
|
||||
|
||||
|
||||
def test_permutations():
|
||||
seed(1234)
|
||||
for _ in range(10):
|
||||
n = randint(1, 100)
|
||||
# Random real/complex array
|
||||
x = rand(n, n) if randint(2) else rand(n, n) + rand(n, n)*1j
|
||||
x = x + x.conj().T
|
||||
x += eye(n)*randint(5, 1e6)
|
||||
l_ind = tril_indices_from(x, k=-1)
|
||||
u_ind = triu_indices_from(x, k=1)
|
||||
|
||||
# Test whether permutations lead to a triangular array
|
||||
u, d, p = ldl(x, lower=0)
|
||||
# lower part should be zero
|
||||
assert_(not any(u[p, :][l_ind]), 'Spin {} failed'.format(_))
|
||||
|
||||
l, d, p = ldl(x, lower=1)
|
||||
# upper part should be zero
|
||||
assert_(not any(l[p, :][u_ind]), 'Spin {} failed'.format(_))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("dtype", [float32, float64])
|
||||
@pytest.mark.parametrize("n", [30, 150])
|
||||
def test_ldl_type_size_combinations_real(n, dtype):
|
||||
seed(1234)
|
||||
msg = ("Failed for size: {}, dtype: {}".format(n, dtype))
|
||||
|
||||
x = rand(n, n).astype(dtype)
|
||||
x = x + x.T
|
||||
x += eye(n, dtype=dtype)*dtype(randint(5, 1e6))
|
||||
|
||||
l, d1, p = ldl(x)
|
||||
u, d2, p = ldl(x, lower=0)
|
||||
rtol = 1e-4 if dtype is float32 else 1e-10
|
||||
assert_allclose(l.dot(d1).dot(l.T), x, rtol=rtol, err_msg=msg)
|
||||
assert_allclose(u.dot(d2).dot(u.T), x, rtol=rtol, err_msg=msg)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("dtype", [complex64, complex128])
|
||||
@pytest.mark.parametrize("n", [30, 150])
|
||||
def test_ldl_type_size_combinations_complex(n, dtype):
|
||||
seed(1234)
|
||||
msg1 = ("Her failed for size: {}, dtype: {}".format(n, dtype))
|
||||
msg2 = ("Sym failed for size: {}, dtype: {}".format(n, dtype))
|
||||
|
||||
# Complex hermitian upper/lower
|
||||
x = (rand(n, n)+1j*rand(n, n)).astype(dtype)
|
||||
x = x+x.conj().T
|
||||
x += eye(n, dtype=dtype)*dtype(randint(5, 1e6))
|
||||
|
||||
l, d1, p = ldl(x)
|
||||
u, d2, p = ldl(x, lower=0)
|
||||
rtol = 1e-4 if dtype is complex64 else 1e-10
|
||||
assert_allclose(l.dot(d1).dot(l.conj().T), x, rtol=rtol, err_msg=msg1)
|
||||
assert_allclose(u.dot(d2).dot(u.conj().T), x, rtol=rtol, err_msg=msg1)
|
||||
|
||||
# Complex symmetric upper/lower
|
||||
x = (rand(n, n)+1j*rand(n, n)).astype(dtype)
|
||||
x = x+x.T
|
||||
x += eye(n, dtype=dtype)*dtype(randint(5, 1e6))
|
||||
|
||||
l, d1, p = ldl(x, hermitian=0)
|
||||
u, d2, p = ldl(x, lower=0, hermitian=0)
|
||||
assert_allclose(l.dot(d1).dot(l.T), x, rtol=rtol, err_msg=msg2)
|
||||
assert_allclose(u.dot(d2).dot(u.T), x, rtol=rtol, err_msg=msg2)
|
||||
90
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_polar.py
vendored
Normal file
90
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_polar.py
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
import numpy as np
|
||||
from numpy.linalg import norm
|
||||
from numpy.testing import (assert_, assert_allclose, assert_equal)
|
||||
from scipy.linalg import polar, eigh
|
||||
|
||||
|
||||
diag2 = np.array([[2, 0], [0, 3]])
|
||||
a13 = np.array([[1, 2, 2]])
|
||||
|
||||
precomputed_cases = [
|
||||
[[[0]], 'right', [[1]], [[0]]],
|
||||
[[[0]], 'left', [[1]], [[0]]],
|
||||
[[[9]], 'right', [[1]], [[9]]],
|
||||
[[[9]], 'left', [[1]], [[9]]],
|
||||
[diag2, 'right', np.eye(2), diag2],
|
||||
[diag2, 'left', np.eye(2), diag2],
|
||||
[a13, 'right', a13/norm(a13[0]), a13.T.dot(a13)/norm(a13[0])],
|
||||
]
|
||||
|
||||
verify_cases = [
|
||||
[[1, 2], [3, 4]],
|
||||
[[1, 2, 3]],
|
||||
[[1], [2], [3]],
|
||||
[[1, 2, 3], [3, 4, 0]],
|
||||
[[1, 2], [3, 4], [5, 5]],
|
||||
[[1, 2], [3, 4+5j]],
|
||||
[[1, 2, 3j]],
|
||||
[[1], [2], [3j]],
|
||||
[[1, 2, 3+2j], [3, 4-1j, -4j]],
|
||||
[[1, 2], [3-2j, 4+0.5j], [5, 5]],
|
||||
[[10000, 10, 1], [-1, 2, 3j], [0, 1, 2]],
|
||||
]
|
||||
|
||||
|
||||
def check_precomputed_polar(a, side, expected_u, expected_p):
|
||||
# Compare the result of the polar decomposition to a
|
||||
# precomputed result.
|
||||
u, p = polar(a, side=side)
|
||||
assert_allclose(u, expected_u, atol=1e-15)
|
||||
assert_allclose(p, expected_p, atol=1e-15)
|
||||
|
||||
|
||||
def verify_polar(a):
|
||||
# Compute the polar decomposition, and then verify that
|
||||
# the result has all the expected properties.
|
||||
product_atol = np.sqrt(np.finfo(float).eps)
|
||||
|
||||
aa = np.asarray(a)
|
||||
m, n = aa.shape
|
||||
|
||||
u, p = polar(a, side='right')
|
||||
assert_equal(u.shape, (m, n))
|
||||
assert_equal(p.shape, (n, n))
|
||||
# a = up
|
||||
assert_allclose(u.dot(p), a, atol=product_atol)
|
||||
if m >= n:
|
||||
assert_allclose(u.conj().T.dot(u), np.eye(n), atol=1e-15)
|
||||
else:
|
||||
assert_allclose(u.dot(u.conj().T), np.eye(m), atol=1e-15)
|
||||
# p is Hermitian positive semidefinite.
|
||||
assert_allclose(p.conj().T, p)
|
||||
evals = eigh(p, eigvals_only=True)
|
||||
nonzero_evals = evals[abs(evals) > 1e-14]
|
||||
assert_((nonzero_evals >= 0).all())
|
||||
|
||||
u, p = polar(a, side='left')
|
||||
assert_equal(u.shape, (m, n))
|
||||
assert_equal(p.shape, (m, m))
|
||||
# a = pu
|
||||
assert_allclose(p.dot(u), a, atol=product_atol)
|
||||
if m >= n:
|
||||
assert_allclose(u.conj().T.dot(u), np.eye(n), atol=1e-15)
|
||||
else:
|
||||
assert_allclose(u.dot(u.conj().T), np.eye(m), atol=1e-15)
|
||||
# p is Hermitian positive semidefinite.
|
||||
assert_allclose(p.conj().T, p)
|
||||
evals = eigh(p, eigvals_only=True)
|
||||
nonzero_evals = evals[abs(evals) > 1e-14]
|
||||
assert_((nonzero_evals >= 0).all())
|
||||
|
||||
|
||||
def test_precomputed_cases():
|
||||
for a, side, expected_u, expected_p in precomputed_cases:
|
||||
check_precomputed_polar(a, side, expected_u, expected_p)
|
||||
|
||||
|
||||
def test_verify_cases():
|
||||
for a in verify_cases:
|
||||
verify_polar(a)
|
||||
|
||||
1700
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_update.py
vendored
Normal file
1700
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_decomp_update.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
607
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_fblas.py
vendored
Normal file
607
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_fblas.py
vendored
Normal file
@@ -0,0 +1,607 @@
|
||||
# Test interfaces to fortran blas.
|
||||
#
|
||||
# The tests are more of interface than they are of the underlying blas.
|
||||
# Only very small matrices checked -- N=3 or so.
|
||||
#
|
||||
# !! Complex calculations really aren't checked that carefully.
|
||||
# !! Only real valued complex numbers are used in tests.
|
||||
|
||||
from numpy import float32, float64, complex64, complex128, arange, array, \
|
||||
zeros, shape, transpose, newaxis, common_type, conjugate
|
||||
|
||||
from scipy.linalg import _fblas as fblas
|
||||
|
||||
from numpy.testing import assert_array_equal, \
|
||||
assert_allclose, assert_array_almost_equal, assert_
|
||||
|
||||
import pytest
|
||||
|
||||
# decimal accuracy to require between Python and LAPACK/BLAS calculations
|
||||
accuracy = 5
|
||||
|
||||
# Since numpy.dot likely uses the same blas, use this routine
|
||||
# to check.
|
||||
|
||||
|
||||
def matrixmultiply(a, b):
|
||||
if len(b.shape) == 1:
|
||||
b_is_vector = True
|
||||
b = b[:, newaxis]
|
||||
else:
|
||||
b_is_vector = False
|
||||
assert_(a.shape[1] == b.shape[0])
|
||||
c = zeros((a.shape[0], b.shape[1]), common_type(a, b))
|
||||
for i in range(a.shape[0]):
|
||||
for j in range(b.shape[1]):
|
||||
s = 0
|
||||
for k in range(a.shape[1]):
|
||||
s += a[i, k] * b[k, j]
|
||||
c[i, j] = s
|
||||
if b_is_vector:
|
||||
c = c.reshape((a.shape[0],))
|
||||
return c
|
||||
|
||||
##################################################
|
||||
# Test blas ?axpy
|
||||
|
||||
|
||||
class BaseAxpy:
|
||||
''' Mixin class for axpy tests '''
|
||||
|
||||
def test_default_a(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = arange(3., dtype=x.dtype)
|
||||
real_y = x*1.+y
|
||||
y = self.blas_func(x, y)
|
||||
assert_array_equal(real_y, y)
|
||||
|
||||
def test_simple(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = arange(3., dtype=x.dtype)
|
||||
real_y = x*3.+y
|
||||
y = self.blas_func(x, y, a=3.)
|
||||
assert_array_equal(real_y, y)
|
||||
|
||||
def test_x_stride(self):
|
||||
x = arange(6., dtype=self.dtype)
|
||||
y = zeros(3, x.dtype)
|
||||
y = arange(3., dtype=x.dtype)
|
||||
real_y = x[::2]*3.+y
|
||||
y = self.blas_func(x, y, a=3., n=3, incx=2)
|
||||
assert_array_equal(real_y, y)
|
||||
|
||||
def test_y_stride(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
real_y = x*3.+y[::2]
|
||||
y = self.blas_func(x, y, a=3., n=3, incy=2)
|
||||
assert_array_equal(real_y, y[::2])
|
||||
|
||||
def test_x_and_y_stride(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
real_y = x[::4]*3.+y[::2]
|
||||
y = self.blas_func(x, y, a=3., n=3, incx=4, incy=2)
|
||||
assert_array_equal(real_y, y[::2])
|
||||
|
||||
def test_x_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(x, y, n=4, incx=5)
|
||||
|
||||
def test_y_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(x, y, n=3, incy=5)
|
||||
|
||||
|
||||
try:
|
||||
class TestSaxpy(BaseAxpy):
|
||||
blas_func = fblas.saxpy
|
||||
dtype = float32
|
||||
except AttributeError:
|
||||
class TestSaxpy:
|
||||
pass
|
||||
|
||||
|
||||
class TestDaxpy(BaseAxpy):
|
||||
blas_func = fblas.daxpy
|
||||
dtype = float64
|
||||
|
||||
|
||||
try:
|
||||
class TestCaxpy(BaseAxpy):
|
||||
blas_func = fblas.caxpy
|
||||
dtype = complex64
|
||||
except AttributeError:
|
||||
class TestCaxpy:
|
||||
pass
|
||||
|
||||
|
||||
class TestZaxpy(BaseAxpy):
|
||||
blas_func = fblas.zaxpy
|
||||
dtype = complex128
|
||||
|
||||
|
||||
##################################################
|
||||
# Test blas ?scal
|
||||
|
||||
class BaseScal:
|
||||
''' Mixin class for scal testing '''
|
||||
|
||||
def test_simple(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
real_x = x*3.
|
||||
x = self.blas_func(3., x)
|
||||
assert_array_equal(real_x, x)
|
||||
|
||||
def test_x_stride(self):
|
||||
x = arange(6., dtype=self.dtype)
|
||||
real_x = x.copy()
|
||||
real_x[::2] = x[::2]*array(3., self.dtype)
|
||||
x = self.blas_func(3., x, n=3, incx=2)
|
||||
assert_array_equal(real_x, x)
|
||||
|
||||
def test_x_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(2., x, n=4, incx=5)
|
||||
|
||||
|
||||
try:
|
||||
class TestSscal(BaseScal):
|
||||
blas_func = fblas.sscal
|
||||
dtype = float32
|
||||
except AttributeError:
|
||||
class TestSscal:
|
||||
pass
|
||||
|
||||
|
||||
class TestDscal(BaseScal):
|
||||
blas_func = fblas.dscal
|
||||
dtype = float64
|
||||
|
||||
|
||||
try:
|
||||
class TestCscal(BaseScal):
|
||||
blas_func = fblas.cscal
|
||||
dtype = complex64
|
||||
except AttributeError:
|
||||
class TestCscal:
|
||||
pass
|
||||
|
||||
|
||||
class TestZscal(BaseScal):
|
||||
blas_func = fblas.zscal
|
||||
dtype = complex128
|
||||
|
||||
|
||||
##################################################
|
||||
# Test blas ?copy
|
||||
|
||||
class BaseCopy:
|
||||
''' Mixin class for copy testing '''
|
||||
|
||||
def test_simple(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = zeros(shape(x), x.dtype)
|
||||
y = self.blas_func(x, y)
|
||||
assert_array_equal(x, y)
|
||||
|
||||
def test_x_stride(self):
|
||||
x = arange(6., dtype=self.dtype)
|
||||
y = zeros(3, x.dtype)
|
||||
y = self.blas_func(x, y, n=3, incx=2)
|
||||
assert_array_equal(x[::2], y)
|
||||
|
||||
def test_y_stride(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
y = self.blas_func(x, y, n=3, incy=2)
|
||||
assert_array_equal(x, y[::2])
|
||||
|
||||
def test_x_and_y_stride(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
y = self.blas_func(x, y, n=3, incx=4, incy=2)
|
||||
assert_array_equal(x[::4], y[::2])
|
||||
|
||||
def test_x_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(x, y, n=4, incx=5)
|
||||
|
||||
def test_y_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(x, y, n=3, incy=5)
|
||||
|
||||
# def test_y_bad_type(self):
|
||||
## Hmmm. Should this work? What should be the output.
|
||||
# x = arange(3.,dtype=self.dtype)
|
||||
# y = zeros(shape(x))
|
||||
# self.blas_func(x,y)
|
||||
# assert_array_equal(x,y)
|
||||
|
||||
|
||||
try:
|
||||
class TestScopy(BaseCopy):
|
||||
blas_func = fblas.scopy
|
||||
dtype = float32
|
||||
except AttributeError:
|
||||
class TestScopy:
|
||||
pass
|
||||
|
||||
|
||||
class TestDcopy(BaseCopy):
|
||||
blas_func = fblas.dcopy
|
||||
dtype = float64
|
||||
|
||||
|
||||
try:
|
||||
class TestCcopy(BaseCopy):
|
||||
blas_func = fblas.ccopy
|
||||
dtype = complex64
|
||||
except AttributeError:
|
||||
class TestCcopy:
|
||||
pass
|
||||
|
||||
|
||||
class TestZcopy(BaseCopy):
|
||||
blas_func = fblas.zcopy
|
||||
dtype = complex128
|
||||
|
||||
|
||||
##################################################
|
||||
# Test blas ?swap
|
||||
|
||||
class BaseSwap:
|
||||
''' Mixin class for swap tests '''
|
||||
|
||||
def test_simple(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = zeros(shape(x), x.dtype)
|
||||
desired_x = y.copy()
|
||||
desired_y = x.copy()
|
||||
x, y = self.blas_func(x, y)
|
||||
assert_array_equal(desired_x, x)
|
||||
assert_array_equal(desired_y, y)
|
||||
|
||||
def test_x_stride(self):
|
||||
x = arange(6., dtype=self.dtype)
|
||||
y = zeros(3, x.dtype)
|
||||
desired_x = y.copy()
|
||||
desired_y = x.copy()[::2]
|
||||
x, y = self.blas_func(x, y, n=3, incx=2)
|
||||
assert_array_equal(desired_x, x[::2])
|
||||
assert_array_equal(desired_y, y)
|
||||
|
||||
def test_y_stride(self):
|
||||
x = arange(3., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
desired_x = y.copy()[::2]
|
||||
desired_y = x.copy()
|
||||
x, y = self.blas_func(x, y, n=3, incy=2)
|
||||
assert_array_equal(desired_x, x)
|
||||
assert_array_equal(desired_y, y[::2])
|
||||
|
||||
def test_x_and_y_stride(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
desired_x = y.copy()[::2]
|
||||
desired_y = x.copy()[::4]
|
||||
x, y = self.blas_func(x, y, n=3, incx=4, incy=2)
|
||||
assert_array_equal(desired_x, x[::4])
|
||||
assert_array_equal(desired_y, y[::2])
|
||||
|
||||
def test_x_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(x, y, n=4, incx=5)
|
||||
|
||||
def test_y_bad_size(self):
|
||||
x = arange(12., dtype=self.dtype)
|
||||
y = zeros(6, x.dtype)
|
||||
with pytest.raises(Exception, match='failed for 1st keyword'):
|
||||
self.blas_func(x, y, n=3, incy=5)
|
||||
|
||||
|
||||
try:
|
||||
class TestSswap(BaseSwap):
|
||||
blas_func = fblas.sswap
|
||||
dtype = float32
|
||||
except AttributeError:
|
||||
class TestSswap:
|
||||
pass
|
||||
|
||||
|
||||
class TestDswap(BaseSwap):
|
||||
blas_func = fblas.dswap
|
||||
dtype = float64
|
||||
|
||||
|
||||
try:
|
||||
class TestCswap(BaseSwap):
|
||||
blas_func = fblas.cswap
|
||||
dtype = complex64
|
||||
except AttributeError:
|
||||
class TestCswap:
|
||||
pass
|
||||
|
||||
|
||||
class TestZswap(BaseSwap):
|
||||
blas_func = fblas.zswap
|
||||
dtype = complex128
|
||||
|
||||
##################################################
|
||||
# Test blas ?gemv
|
||||
# This will be a mess to test all cases.
|
||||
|
||||
|
||||
class BaseGemv:
|
||||
''' Mixin class for gemv tests '''
|
||||
|
||||
def get_data(self, x_stride=1, y_stride=1):
|
||||
mult = array(1, dtype=self.dtype)
|
||||
if self.dtype in [complex64, complex128]:
|
||||
mult = array(1+1j, dtype=self.dtype)
|
||||
from numpy.random import normal, seed
|
||||
seed(1234)
|
||||
alpha = array(1., dtype=self.dtype) * mult
|
||||
beta = array(1., dtype=self.dtype) * mult
|
||||
a = normal(0., 1., (3, 3)).astype(self.dtype) * mult
|
||||
x = arange(shape(a)[0]*x_stride, dtype=self.dtype) * mult
|
||||
y = arange(shape(a)[1]*y_stride, dtype=self.dtype) * mult
|
||||
return alpha, beta, a, x, y
|
||||
|
||||
def test_simple(self):
|
||||
alpha, beta, a, x, y = self.get_data()
|
||||
desired_y = alpha*matrixmultiply(a, x)+beta*y
|
||||
y = self.blas_func(alpha, a, x, beta, y)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_default_beta_y(self):
|
||||
alpha, beta, a, x, y = self.get_data()
|
||||
desired_y = matrixmultiply(a, x)
|
||||
y = self.blas_func(1, a, x)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_simple_transpose(self):
|
||||
alpha, beta, a, x, y = self.get_data()
|
||||
desired_y = alpha*matrixmultiply(transpose(a), x)+beta*y
|
||||
y = self.blas_func(alpha, a, x, beta, y, trans=1)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_simple_transpose_conj(self):
|
||||
alpha, beta, a, x, y = self.get_data()
|
||||
desired_y = alpha*matrixmultiply(transpose(conjugate(a)), x)+beta*y
|
||||
y = self.blas_func(alpha, a, x, beta, y, trans=2)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_x_stride(self):
|
||||
alpha, beta, a, x, y = self.get_data(x_stride=2)
|
||||
desired_y = alpha*matrixmultiply(a, x[::2])+beta*y
|
||||
y = self.blas_func(alpha, a, x, beta, y, incx=2)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_x_stride_transpose(self):
|
||||
alpha, beta, a, x, y = self.get_data(x_stride=2)
|
||||
desired_y = alpha*matrixmultiply(transpose(a), x[::2])+beta*y
|
||||
y = self.blas_func(alpha, a, x, beta, y, trans=1, incx=2)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_x_stride_assert(self):
|
||||
# What is the use of this test?
|
||||
alpha, beta, a, x, y = self.get_data(x_stride=2)
|
||||
with pytest.raises(Exception, match='failed for 3rd argument'):
|
||||
y = self.blas_func(1, a, x, 1, y, trans=0, incx=3)
|
||||
with pytest.raises(Exception, match='failed for 3rd argument'):
|
||||
y = self.blas_func(1, a, x, 1, y, trans=1, incx=3)
|
||||
|
||||
def test_y_stride(self):
|
||||
alpha, beta, a, x, y = self.get_data(y_stride=2)
|
||||
desired_y = y.copy()
|
||||
desired_y[::2] = alpha*matrixmultiply(a, x)+beta*y[::2]
|
||||
y = self.blas_func(alpha, a, x, beta, y, incy=2)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_y_stride_transpose(self):
|
||||
alpha, beta, a, x, y = self.get_data(y_stride=2)
|
||||
desired_y = y.copy()
|
||||
desired_y[::2] = alpha*matrixmultiply(transpose(a), x)+beta*y[::2]
|
||||
y = self.blas_func(alpha, a, x, beta, y, trans=1, incy=2)
|
||||
assert_array_almost_equal(desired_y, y)
|
||||
|
||||
def test_y_stride_assert(self):
|
||||
# What is the use of this test?
|
||||
alpha, beta, a, x, y = self.get_data(y_stride=2)
|
||||
with pytest.raises(Exception, match='failed for 2nd keyword'):
|
||||
y = self.blas_func(1, a, x, 1, y, trans=0, incy=3)
|
||||
with pytest.raises(Exception, match='failed for 2nd keyword'):
|
||||
y = self.blas_func(1, a, x, 1, y, trans=1, incy=3)
|
||||
|
||||
|
||||
try:
|
||||
class TestSgemv(BaseGemv):
|
||||
blas_func = fblas.sgemv
|
||||
dtype = float32
|
||||
|
||||
def test_sgemv_on_osx(self):
|
||||
from itertools import product
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
return
|
||||
|
||||
def aligned_array(shape, align, dtype, order='C'):
|
||||
# Make array shape `shape` with aligned at `align` bytes
|
||||
d = dtype()
|
||||
# Make array of correct size with `align` extra bytes
|
||||
N = np.prod(shape)
|
||||
tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
|
||||
address = tmp.__array_interface__["data"][0]
|
||||
# Find offset into array giving desired alignment
|
||||
for offset in range(align):
|
||||
if (address + offset) % align == 0:
|
||||
break
|
||||
tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
|
||||
return tmp.reshape(shape, order=order)
|
||||
|
||||
def as_aligned(arr, align, dtype, order='C'):
|
||||
# Copy `arr` into an aligned array with same shape
|
||||
aligned = aligned_array(arr.shape, align, dtype, order)
|
||||
aligned[:] = arr[:]
|
||||
return aligned
|
||||
|
||||
def assert_dot_close(A, X, desired):
|
||||
assert_allclose(self.blas_func(1.0, A, X), desired,
|
||||
rtol=1e-5, atol=1e-7)
|
||||
|
||||
testdata = product((15, 32), (10000,), (200, 89), ('C', 'F'))
|
||||
for align, m, n, a_order in testdata:
|
||||
A_d = np.random.rand(m, n)
|
||||
X_d = np.random.rand(n)
|
||||
desired = np.dot(A_d, X_d)
|
||||
# Calculation with aligned single precision
|
||||
A_f = as_aligned(A_d, align, np.float32, order=a_order)
|
||||
X_f = as_aligned(X_d, align, np.float32, order=a_order)
|
||||
assert_dot_close(A_f, X_f, desired)
|
||||
|
||||
except AttributeError:
|
||||
class TestSgemv:
|
||||
pass
|
||||
|
||||
|
||||
class TestDgemv(BaseGemv):
|
||||
blas_func = fblas.dgemv
|
||||
dtype = float64
|
||||
|
||||
|
||||
try:
|
||||
class TestCgemv(BaseGemv):
|
||||
blas_func = fblas.cgemv
|
||||
dtype = complex64
|
||||
except AttributeError:
|
||||
class TestCgemv:
|
||||
pass
|
||||
|
||||
|
||||
class TestZgemv(BaseGemv):
|
||||
blas_func = fblas.zgemv
|
||||
dtype = complex128
|
||||
|
||||
|
||||
"""
|
||||
##################################################
|
||||
### Test blas ?ger
|
||||
### This will be a mess to test all cases.
|
||||
|
||||
class BaseGer:
|
||||
def get_data(self,x_stride=1,y_stride=1):
|
||||
from numpy.random import normal, seed
|
||||
seed(1234)
|
||||
alpha = array(1., dtype = self.dtype)
|
||||
a = normal(0.,1.,(3,3)).astype(self.dtype)
|
||||
x = arange(shape(a)[0]*x_stride,dtype=self.dtype)
|
||||
y = arange(shape(a)[1]*y_stride,dtype=self.dtype)
|
||||
return alpha,a,x,y
|
||||
def test_simple(self):
|
||||
alpha,a,x,y = self.get_data()
|
||||
# tranpose takes care of Fortran vs. C(and Python) memory layout
|
||||
desired_a = alpha*transpose(x[:,newaxis]*y) + a
|
||||
self.blas_func(x,y,a)
|
||||
assert_array_almost_equal(desired_a,a)
|
||||
def test_x_stride(self):
|
||||
alpha,a,x,y = self.get_data(x_stride=2)
|
||||
desired_a = alpha*transpose(x[::2,newaxis]*y) + a
|
||||
self.blas_func(x,y,a,incx=2)
|
||||
assert_array_almost_equal(desired_a,a)
|
||||
def test_x_stride_assert(self):
|
||||
alpha,a,x,y = self.get_data(x_stride=2)
|
||||
with pytest.raises(ValueError, match='foo'):
|
||||
self.blas_func(x,y,a,incx=3)
|
||||
def test_y_stride(self):
|
||||
alpha,a,x,y = self.get_data(y_stride=2)
|
||||
desired_a = alpha*transpose(x[:,newaxis]*y[::2]) + a
|
||||
self.blas_func(x,y,a,incy=2)
|
||||
assert_array_almost_equal(desired_a,a)
|
||||
|
||||
def test_y_stride_assert(self):
|
||||
alpha,a,x,y = self.get_data(y_stride=2)
|
||||
with pytest.raises(ValueError, match='foo'):
|
||||
self.blas_func(a,x,y,incy=3)
|
||||
|
||||
class TestSger(BaseGer):
|
||||
blas_func = fblas.sger
|
||||
dtype = float32
|
||||
class TestDger(BaseGer):
|
||||
blas_func = fblas.dger
|
||||
dtype = float64
|
||||
"""
|
||||
##################################################
|
||||
# Test blas ?gerc
|
||||
# This will be a mess to test all cases.
|
||||
|
||||
"""
|
||||
class BaseGerComplex(BaseGer):
|
||||
def get_data(self,x_stride=1,y_stride=1):
|
||||
from numpy.random import normal, seed
|
||||
seed(1234)
|
||||
alpha = array(1+1j, dtype = self.dtype)
|
||||
a = normal(0.,1.,(3,3)).astype(self.dtype)
|
||||
a = a + normal(0.,1.,(3,3)) * array(1j, dtype = self.dtype)
|
||||
x = normal(0.,1.,shape(a)[0]*x_stride).astype(self.dtype)
|
||||
x = x + x * array(1j, dtype = self.dtype)
|
||||
y = normal(0.,1.,shape(a)[1]*y_stride).astype(self.dtype)
|
||||
y = y + y * array(1j, dtype = self.dtype)
|
||||
return alpha,a,x,y
|
||||
def test_simple(self):
|
||||
alpha,a,x,y = self.get_data()
|
||||
# tranpose takes care of Fortran vs. C(and Python) memory layout
|
||||
a = a * array(0.,dtype = self.dtype)
|
||||
#desired_a = alpha*transpose(x[:,newaxis]*self.transform(y)) + a
|
||||
desired_a = alpha*transpose(x[:,newaxis]*y) + a
|
||||
#self.blas_func(x,y,a,alpha = alpha)
|
||||
fblas.cgeru(x,y,a,alpha = alpha)
|
||||
assert_array_almost_equal(desired_a,a)
|
||||
|
||||
#def test_x_stride(self):
|
||||
# alpha,a,x,y = self.get_data(x_stride=2)
|
||||
# desired_a = alpha*transpose(x[::2,newaxis]*self.transform(y)) + a
|
||||
# self.blas_func(x,y,a,incx=2)
|
||||
# assert_array_almost_equal(desired_a,a)
|
||||
#def test_y_stride(self):
|
||||
# alpha,a,x,y = self.get_data(y_stride=2)
|
||||
# desired_a = alpha*transpose(x[:,newaxis]*self.transform(y[::2])) + a
|
||||
# self.blas_func(x,y,a,incy=2)
|
||||
# assert_array_almost_equal(desired_a,a)
|
||||
|
||||
class TestCgeru(BaseGerComplex):
|
||||
blas_func = fblas.cgeru
|
||||
dtype = complex64
|
||||
def transform(self,x):
|
||||
return x
|
||||
class TestZgeru(BaseGerComplex):
|
||||
blas_func = fblas.zgeru
|
||||
dtype = complex128
|
||||
def transform(self,x):
|
||||
return x
|
||||
|
||||
class TestCgerc(BaseGerComplex):
|
||||
blas_func = fblas.cgerc
|
||||
dtype = complex64
|
||||
def transform(self,x):
|
||||
return conjugate(x)
|
||||
|
||||
class TestZgerc(BaseGerComplex):
|
||||
blas_func = fblas.zgerc
|
||||
dtype = complex128
|
||||
def transform(self,x):
|
||||
return conjugate(x)
|
||||
"""
|
||||
241
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_interpolative.py
vendored
Normal file
241
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_interpolative.py
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2013 Kenneth L. Ho
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer. Redistributions in binary
|
||||
# form must reproduce the above copyright notice, this list of conditions and
|
||||
# the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# None of the names of the copyright holders may be used to endorse or
|
||||
# promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#******************************************************************************
|
||||
|
||||
import scipy.linalg.interpolative as pymatrixid
|
||||
import numpy as np
|
||||
from scipy.linalg import hilbert, svdvals, norm
|
||||
from scipy.sparse.linalg import aslinearoperator
|
||||
from scipy.linalg.interpolative import interp_decomp
|
||||
|
||||
from numpy.testing import (assert_, assert_allclose, assert_equal,
|
||||
assert_array_equal)
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
import sys
|
||||
_IS_32BIT = (sys.maxsize < 2**32)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def eps():
|
||||
yield 1e-12
|
||||
|
||||
|
||||
@pytest.fixture(params=[np.float64, np.complex128])
|
||||
def A(request):
|
||||
# construct Hilbert matrix
|
||||
# set parameters
|
||||
n = 300
|
||||
yield hilbert(n).astype(request.param)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def L(A):
|
||||
yield aslinearoperator(A)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def rank(A, eps):
|
||||
S = np.linalg.svd(A, compute_uv=False)
|
||||
try:
|
||||
rank = np.nonzero(S < eps)[0][0]
|
||||
except IndexError:
|
||||
rank = A.shape[0]
|
||||
return rank
|
||||
|
||||
|
||||
class TestInterpolativeDecomposition:
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"rand,lin_op",
|
||||
[(False, False), (True, False), (True, True)])
|
||||
def test_real_id_fixed_precision(self, A, L, eps, rand, lin_op):
|
||||
if _IS_32BIT and A.dtype == np.complex_ and rand:
|
||||
pytest.xfail("bug in external fortran code")
|
||||
# Test ID routines on a Hilbert matrix.
|
||||
A_or_L = A if not lin_op else L
|
||||
|
||||
k, idx, proj = pymatrixid.interp_decomp(A_or_L, eps, rand=rand)
|
||||
B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
|
||||
assert_allclose(A, B, rtol=eps, atol=1e-08)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"rand,lin_op",
|
||||
[(False, False), (True, False), (True, True)])
|
||||
def test_real_id_fixed_rank(self, A, L, eps, rank, rand, lin_op):
|
||||
if _IS_32BIT and A.dtype == np.complex_ and rand:
|
||||
pytest.xfail("bug in external fortran code")
|
||||
k = rank
|
||||
A_or_L = A if not lin_op else L
|
||||
|
||||
idx, proj = pymatrixid.interp_decomp(A_or_L, k, rand=rand)
|
||||
B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
|
||||
assert_allclose(A, B, rtol=eps, atol=1e-08)
|
||||
|
||||
@pytest.mark.parametrize("rand,lin_op", [(False, False)])
|
||||
def test_real_id_skel_and_interp_matrices(
|
||||
self, A, L, eps, rank, rand, lin_op):
|
||||
k = rank
|
||||
A_or_L = A if not lin_op else L
|
||||
|
||||
idx, proj = pymatrixid.interp_decomp(A_or_L, k, rand=rand)
|
||||
P = pymatrixid.reconstruct_interp_matrix(idx, proj)
|
||||
B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
|
||||
assert_allclose(B, A[:, idx[:k]], rtol=eps, atol=1e-08)
|
||||
assert_allclose(B @ P, A, rtol=eps, atol=1e-08)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"rand,lin_op",
|
||||
[(False, False), (True, False), (True, True)])
|
||||
def test_svd_fixed_precison(self, A, L, eps, rand, lin_op):
|
||||
if _IS_32BIT and A.dtype == np.complex_ and rand:
|
||||
pytest.xfail("bug in external fortran code")
|
||||
A_or_L = A if not lin_op else L
|
||||
|
||||
U, S, V = pymatrixid.svd(A_or_L, eps, rand=rand)
|
||||
B = U * S @ V.T.conj()
|
||||
assert_allclose(A, B, rtol=eps, atol=1e-08)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"rand,lin_op",
|
||||
[(False, False), (True, False), (True, True)])
|
||||
def test_svd_fixed_rank(self, A, L, eps, rank, rand, lin_op):
|
||||
if _IS_32BIT and A.dtype == np.complex_ and rand:
|
||||
pytest.xfail("bug in external fortran code")
|
||||
k = rank
|
||||
A_or_L = A if not lin_op else L
|
||||
|
||||
U, S, V = pymatrixid.svd(A_or_L, k, rand=rand)
|
||||
B = U * S @ V.T.conj()
|
||||
assert_allclose(A, B, rtol=eps, atol=1e-08)
|
||||
|
||||
def test_id_to_svd(self, A, eps, rank):
|
||||
k = rank
|
||||
|
||||
idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
|
||||
U, S, V = pymatrixid.id_to_svd(A[:, idx[:k]], idx, proj)
|
||||
B = U * S @ V.T.conj()
|
||||
assert_allclose(A, B, rtol=eps, atol=1e-08)
|
||||
|
||||
def test_estimate_spectral_norm(self, A):
|
||||
s = svdvals(A)
|
||||
norm_2_est = pymatrixid.estimate_spectral_norm(A)
|
||||
assert_allclose(norm_2_est, s[0], rtol=1e-6, atol=1e-8)
|
||||
|
||||
def test_estimate_spectral_norm_diff(self, A):
|
||||
B = A.copy()
|
||||
B[:, 0] *= 1.2
|
||||
s = svdvals(A - B)
|
||||
norm_2_est = pymatrixid.estimate_spectral_norm_diff(A, B)
|
||||
assert_allclose(norm_2_est, s[0], rtol=1e-6, atol=1e-8)
|
||||
|
||||
def test_rank_estimates_array(self, A):
|
||||
B = np.array([[1, 1, 0], [0, 0, 1], [0, 0, 1]], dtype=A.dtype)
|
||||
|
||||
for M in [A, B]:
|
||||
rank_tol = 1e-9
|
||||
rank_np = np.linalg.matrix_rank(M, norm(M, 2) * rank_tol)
|
||||
rank_est = pymatrixid.estimate_rank(M, rank_tol)
|
||||
assert_(rank_est >= rank_np)
|
||||
assert_(rank_est <= rank_np + 10)
|
||||
|
||||
def test_rank_estimates_lin_op(self, A):
|
||||
B = np.array([[1, 1, 0], [0, 0, 1], [0, 0, 1]], dtype=A.dtype)
|
||||
|
||||
for M in [A, B]:
|
||||
ML = aslinearoperator(M)
|
||||
rank_tol = 1e-9
|
||||
rank_np = np.linalg.matrix_rank(M, norm(M, 2) * rank_tol)
|
||||
rank_est = pymatrixid.estimate_rank(ML, rank_tol)
|
||||
assert_(rank_est >= rank_np - 4)
|
||||
assert_(rank_est <= rank_np + 4)
|
||||
|
||||
def test_rand(self):
|
||||
pymatrixid.seed('default')
|
||||
assert_allclose(pymatrixid.rand(2), [0.8932059, 0.64500803],
|
||||
rtol=1e-4, atol=1e-8)
|
||||
|
||||
pymatrixid.seed(1234)
|
||||
x1 = pymatrixid.rand(2)
|
||||
assert_allclose(x1, [0.7513823, 0.06861718], rtol=1e-4, atol=1e-8)
|
||||
|
||||
np.random.seed(1234)
|
||||
pymatrixid.seed()
|
||||
x2 = pymatrixid.rand(2)
|
||||
|
||||
np.random.seed(1234)
|
||||
pymatrixid.seed(np.random.rand(55))
|
||||
x3 = pymatrixid.rand(2)
|
||||
|
||||
assert_allclose(x1, x2)
|
||||
assert_allclose(x1, x3)
|
||||
|
||||
def test_badcall(self):
|
||||
A = hilbert(5).astype(np.float32)
|
||||
with assert_raises(ValueError):
|
||||
pymatrixid.interp_decomp(A, 1e-6, rand=False)
|
||||
|
||||
def test_rank_too_large(self):
|
||||
# svd(array, k) should not segfault
|
||||
a = np.ones((4, 3))
|
||||
with assert_raises(ValueError):
|
||||
pymatrixid.svd(a, 4)
|
||||
|
||||
def test_full_rank(self):
|
||||
eps = 1.0e-12
|
||||
|
||||
# fixed precision
|
||||
A = np.random.rand(16, 8)
|
||||
k, idx, proj = pymatrixid.interp_decomp(A, eps)
|
||||
assert_equal(k, A.shape[1])
|
||||
|
||||
P = pymatrixid.reconstruct_interp_matrix(idx, proj)
|
||||
B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
|
||||
assert_allclose(A, B @ P)
|
||||
|
||||
# fixed rank
|
||||
idx, proj = pymatrixid.interp_decomp(A, k)
|
||||
|
||||
P = pymatrixid.reconstruct_interp_matrix(idx, proj)
|
||||
B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
|
||||
assert_allclose(A, B @ P)
|
||||
|
||||
@pytest.mark.parametrize("dtype", [np.float_, np.complex_])
|
||||
@pytest.mark.parametrize("rand", [True, False])
|
||||
@pytest.mark.parametrize("eps", [1, 0.1])
|
||||
def test_bug_9793(self, dtype, rand, eps):
|
||||
if _IS_32BIT and dtype == np.complex_ and rand:
|
||||
pytest.xfail("bug in external fortran code")
|
||||
A = np.array([[-1, -1, -1, 0, 0, 0],
|
||||
[0, 0, 0, 1, 1, 1],
|
||||
[1, 0, 0, 1, 0, 0],
|
||||
[0, 1, 0, 0, 1, 0],
|
||||
[0, 0, 1, 0, 0, 1]],
|
||||
dtype=dtype, order="C")
|
||||
B = A.copy()
|
||||
interp_decomp(A.T, eps, rand=rand)
|
||||
assert_array_equal(A, B)
|
||||
3282
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_lapack.py
vendored
Normal file
3282
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_lapack.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
974
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_matfuncs.py
vendored
Normal file
974
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_matfuncs.py
vendored
Normal file
@@ -0,0 +1,974 @@
|
||||
#
|
||||
# Created by: Pearu Peterson, March 2002
|
||||
#
|
||||
""" Test functions for linalg.matfuncs module
|
||||
|
||||
"""
|
||||
import random
|
||||
import functools
|
||||
|
||||
import numpy as np
|
||||
from numpy import array, identity, dot, sqrt
|
||||
from numpy.testing import (assert_array_almost_equal, assert_allclose, assert_,
|
||||
assert_array_less, assert_array_equal, assert_warns)
|
||||
import pytest
|
||||
|
||||
import scipy.linalg
|
||||
from scipy.linalg import (funm, signm, logm, sqrtm, fractional_matrix_power,
|
||||
expm, expm_frechet, expm_cond, norm, khatri_rao)
|
||||
from scipy.linalg import _matfuncs_inv_ssq
|
||||
import scipy.linalg._expm_frechet
|
||||
|
||||
from scipy.optimize import minimize
|
||||
|
||||
|
||||
def _get_al_mohy_higham_2012_experiment_1():
|
||||
"""
|
||||
Return the test matrix from Experiment (1) of [1]_.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Awad H. Al-Mohy and Nicholas J. Higham (2012)
|
||||
"Improved Inverse Scaling and Squaring Algorithms
|
||||
for the Matrix Logarithm."
|
||||
SIAM Journal on Scientific Computing, 34 (4). C152-C169.
|
||||
ISSN 1095-7197
|
||||
|
||||
"""
|
||||
A = np.array([
|
||||
[3.2346e-1, 3e4, 3e4, 3e4],
|
||||
[0, 3.0089e-1, 3e4, 3e4],
|
||||
[0, 0, 3.2210e-1, 3e4],
|
||||
[0, 0, 0, 3.0744e-1]], dtype=float)
|
||||
return A
|
||||
|
||||
|
||||
class TestSignM:
|
||||
|
||||
def test_nils(self):
|
||||
a = array([[29.2, -24.2, 69.5, 49.8, 7.],
|
||||
[-9.2, 5.2, -18., -16.8, -2.],
|
||||
[-10., 6., -20., -18., -2.],
|
||||
[-9.6, 9.6, -25.5, -15.4, -2.],
|
||||
[9.8, -4.8, 18., 18.2, 2.]])
|
||||
cr = array([[11.94933333,-2.24533333,15.31733333,21.65333333,-2.24533333],
|
||||
[-3.84266667,0.49866667,-4.59066667,-7.18666667,0.49866667],
|
||||
[-4.08,0.56,-4.92,-7.6,0.56],
|
||||
[-4.03466667,1.04266667,-5.59866667,-7.02666667,1.04266667],
|
||||
[4.15733333,-0.50133333,4.90933333,7.81333333,-0.50133333]])
|
||||
r = signm(a)
|
||||
assert_array_almost_equal(r,cr)
|
||||
|
||||
def test_defective1(self):
|
||||
a = array([[0.0,1,0,0],[1,0,1,0],[0,0,0,1],[0,0,1,0]])
|
||||
signm(a, disp=False)
|
||||
#XXX: what would be the correct result?
|
||||
|
||||
def test_defective2(self):
|
||||
a = array((
|
||||
[29.2,-24.2,69.5,49.8,7.0],
|
||||
[-9.2,5.2,-18.0,-16.8,-2.0],
|
||||
[-10.0,6.0,-20.0,-18.0,-2.0],
|
||||
[-9.6,9.6,-25.5,-15.4,-2.0],
|
||||
[9.8,-4.8,18.0,18.2,2.0]))
|
||||
signm(a, disp=False)
|
||||
#XXX: what would be the correct result?
|
||||
|
||||
def test_defective3(self):
|
||||
a = array([[-2., 25., 0., 0., 0., 0., 0.],
|
||||
[0., -3., 10., 3., 3., 3., 0.],
|
||||
[0., 0., 2., 15., 3., 3., 0.],
|
||||
[0., 0., 0., 0., 15., 3., 0.],
|
||||
[0., 0., 0., 0., 3., 10., 0.],
|
||||
[0., 0., 0., 0., 0., -2., 25.],
|
||||
[0., 0., 0., 0., 0., 0., -3.]])
|
||||
signm(a, disp=False)
|
||||
#XXX: what would be the correct result?
|
||||
|
||||
|
||||
class TestLogM:
|
||||
|
||||
def test_nils(self):
|
||||
a = array([[-2., 25., 0., 0., 0., 0., 0.],
|
||||
[0., -3., 10., 3., 3., 3., 0.],
|
||||
[0., 0., 2., 15., 3., 3., 0.],
|
||||
[0., 0., 0., 0., 15., 3., 0.],
|
||||
[0., 0., 0., 0., 3., 10., 0.],
|
||||
[0., 0., 0., 0., 0., -2., 25.],
|
||||
[0., 0., 0., 0., 0., 0., -3.]])
|
||||
m = (identity(7)*3.1+0j)-a
|
||||
logm(m, disp=False)
|
||||
#XXX: what would be the correct result?
|
||||
|
||||
def test_al_mohy_higham_2012_experiment_1_logm(self):
|
||||
# The logm completes the round trip successfully.
|
||||
# Note that the expm leg of the round trip is badly conditioned.
|
||||
A = _get_al_mohy_higham_2012_experiment_1()
|
||||
A_logm, info = logm(A, disp=False)
|
||||
A_round_trip = expm(A_logm)
|
||||
assert_allclose(A_round_trip, A, rtol=5e-5, atol=1e-14)
|
||||
|
||||
def test_al_mohy_higham_2012_experiment_1_funm_log(self):
|
||||
# The raw funm with np.log does not complete the round trip.
|
||||
# Note that the expm leg of the round trip is badly conditioned.
|
||||
A = _get_al_mohy_higham_2012_experiment_1()
|
||||
A_funm_log, info = funm(A, np.log, disp=False)
|
||||
A_round_trip = expm(A_funm_log)
|
||||
assert_(not np.allclose(A_round_trip, A, rtol=1e-5, atol=1e-14))
|
||||
|
||||
def test_round_trip_random_float(self):
|
||||
np.random.seed(1234)
|
||||
for n in range(1, 6):
|
||||
M_unscaled = np.random.randn(n, n)
|
||||
for scale in np.logspace(-4, 4, 9):
|
||||
M = M_unscaled * scale
|
||||
|
||||
# Eigenvalues are related to the branch cut.
|
||||
W = np.linalg.eigvals(M)
|
||||
err_msg = 'M:{0} eivals:{1}'.format(M, W)
|
||||
|
||||
# Check sqrtm round trip because it is used within logm.
|
||||
M_sqrtm, info = sqrtm(M, disp=False)
|
||||
M_sqrtm_round_trip = M_sqrtm.dot(M_sqrtm)
|
||||
assert_allclose(M_sqrtm_round_trip, M)
|
||||
|
||||
# Check logm round trip.
|
||||
M_logm, info = logm(M, disp=False)
|
||||
M_logm_round_trip = expm(M_logm)
|
||||
assert_allclose(M_logm_round_trip, M, err_msg=err_msg)
|
||||
|
||||
def test_round_trip_random_complex(self):
|
||||
np.random.seed(1234)
|
||||
for n in range(1, 6):
|
||||
M_unscaled = np.random.randn(n, n) + 1j * np.random.randn(n, n)
|
||||
for scale in np.logspace(-4, 4, 9):
|
||||
M = M_unscaled * scale
|
||||
M_logm, info = logm(M, disp=False)
|
||||
M_round_trip = expm(M_logm)
|
||||
assert_allclose(M_round_trip, M)
|
||||
|
||||
def test_logm_type_preservation_and_conversion(self):
|
||||
# The logm matrix function should preserve the type of a matrix
|
||||
# whose eigenvalues are positive with zero imaginary part.
|
||||
# Test this preservation for variously structured matrices.
|
||||
complex_dtype_chars = ('F', 'D', 'G')
|
||||
for matrix_as_list in (
|
||||
[[1, 0], [0, 1]],
|
||||
[[1, 0], [1, 1]],
|
||||
[[2, 1], [1, 1]],
|
||||
[[2, 3], [1, 2]]):
|
||||
|
||||
# check that the spectrum has the expected properties
|
||||
W = scipy.linalg.eigvals(matrix_as_list)
|
||||
assert_(not any(w.imag or w.real < 0 for w in W))
|
||||
|
||||
# check float type preservation
|
||||
A = np.array(matrix_as_list, dtype=float)
|
||||
A_logm, info = logm(A, disp=False)
|
||||
assert_(A_logm.dtype.char not in complex_dtype_chars)
|
||||
|
||||
# check complex type preservation
|
||||
A = np.array(matrix_as_list, dtype=complex)
|
||||
A_logm, info = logm(A, disp=False)
|
||||
assert_(A_logm.dtype.char in complex_dtype_chars)
|
||||
|
||||
# check float->complex type conversion for the matrix negation
|
||||
A = -np.array(matrix_as_list, dtype=float)
|
||||
A_logm, info = logm(A, disp=False)
|
||||
assert_(A_logm.dtype.char in complex_dtype_chars)
|
||||
|
||||
def test_complex_spectrum_real_logm(self):
|
||||
# This matrix has complex eigenvalues and real logm.
|
||||
# Its output dtype depends on its input dtype.
|
||||
M = [[1, 1, 2], [2, 1, 1], [1, 2, 1]]
|
||||
for dt in float, complex:
|
||||
X = np.array(M, dtype=dt)
|
||||
w = scipy.linalg.eigvals(X)
|
||||
assert_(1e-2 < np.absolute(w.imag).sum())
|
||||
Y, info = logm(X, disp=False)
|
||||
assert_(np.issubdtype(Y.dtype, np.inexact))
|
||||
assert_allclose(expm(Y), X)
|
||||
|
||||
def test_real_mixed_sign_spectrum(self):
|
||||
# These matrices have real eigenvalues with mixed signs.
|
||||
# The output logm dtype is complex, regardless of input dtype.
|
||||
for M in (
|
||||
[[1, 0], [0, -1]],
|
||||
[[0, 1], [1, 0]]):
|
||||
for dt in float, complex:
|
||||
A = np.array(M, dtype=dt)
|
||||
A_logm, info = logm(A, disp=False)
|
||||
assert_(np.issubdtype(A_logm.dtype, np.complexfloating))
|
||||
|
||||
def test_exactly_singular(self):
|
||||
A = np.array([[0, 0], [1j, 1j]])
|
||||
B = np.asarray([[1, 1], [0, 0]])
|
||||
for M in A, A.T, B, B.T:
|
||||
expected_warning = _matfuncs_inv_ssq.LogmExactlySingularWarning
|
||||
L, info = assert_warns(expected_warning, logm, M, disp=False)
|
||||
E = expm(L)
|
||||
assert_allclose(E, M, atol=1e-14)
|
||||
|
||||
def test_nearly_singular(self):
|
||||
M = np.array([[1e-100]])
|
||||
expected_warning = _matfuncs_inv_ssq.LogmNearlySingularWarning
|
||||
L, info = assert_warns(expected_warning, logm, M, disp=False)
|
||||
E = expm(L)
|
||||
assert_allclose(E, M, atol=1e-14)
|
||||
|
||||
def test_opposite_sign_complex_eigenvalues(self):
|
||||
# See gh-6113
|
||||
E = [[0, 1], [-1, 0]]
|
||||
L = [[0, np.pi*0.5], [-np.pi*0.5, 0]]
|
||||
assert_allclose(expm(L), E, atol=1e-14)
|
||||
assert_allclose(logm(E), L, atol=1e-14)
|
||||
E = [[1j, 4], [0, -1j]]
|
||||
L = [[1j*np.pi*0.5, 2*np.pi], [0, -1j*np.pi*0.5]]
|
||||
assert_allclose(expm(L), E, atol=1e-14)
|
||||
assert_allclose(logm(E), L, atol=1e-14)
|
||||
E = [[1j, 0], [0, -1j]]
|
||||
L = [[1j*np.pi*0.5, 0], [0, -1j*np.pi*0.5]]
|
||||
assert_allclose(expm(L), E, atol=1e-14)
|
||||
assert_allclose(logm(E), L, atol=1e-14)
|
||||
|
||||
|
||||
class TestSqrtM:
|
||||
def test_round_trip_random_float(self):
|
||||
np.random.seed(1234)
|
||||
for n in range(1, 6):
|
||||
M_unscaled = np.random.randn(n, n)
|
||||
for scale in np.logspace(-4, 4, 9):
|
||||
M = M_unscaled * scale
|
||||
M_sqrtm, info = sqrtm(M, disp=False)
|
||||
M_sqrtm_round_trip = M_sqrtm.dot(M_sqrtm)
|
||||
assert_allclose(M_sqrtm_round_trip, M)
|
||||
|
||||
def test_round_trip_random_complex(self):
|
||||
np.random.seed(1234)
|
||||
for n in range(1, 6):
|
||||
M_unscaled = np.random.randn(n, n) + 1j * np.random.randn(n, n)
|
||||
for scale in np.logspace(-4, 4, 9):
|
||||
M = M_unscaled * scale
|
||||
M_sqrtm, info = sqrtm(M, disp=False)
|
||||
M_sqrtm_round_trip = M_sqrtm.dot(M_sqrtm)
|
||||
assert_allclose(M_sqrtm_round_trip, M)
|
||||
|
||||
def test_bad(self):
|
||||
# See https://web.archive.org/web/20051220232650/http://www.maths.man.ac.uk/~nareports/narep336.ps.gz
|
||||
e = 2**-5
|
||||
se = sqrt(e)
|
||||
a = array([[1.0,0,0,1],
|
||||
[0,e,0,0],
|
||||
[0,0,e,0],
|
||||
[0,0,0,1]])
|
||||
sa = array([[1,0,0,0.5],
|
||||
[0,se,0,0],
|
||||
[0,0,se,0],
|
||||
[0,0,0,1]])
|
||||
n = a.shape[0]
|
||||
assert_array_almost_equal(dot(sa,sa),a)
|
||||
# Check default sqrtm.
|
||||
esa = sqrtm(a, disp=False, blocksize=n)[0]
|
||||
assert_array_almost_equal(dot(esa,esa),a)
|
||||
# Check sqrtm with 2x2 blocks.
|
||||
esa = sqrtm(a, disp=False, blocksize=2)[0]
|
||||
assert_array_almost_equal(dot(esa,esa),a)
|
||||
|
||||
def test_sqrtm_type_preservation_and_conversion(self):
|
||||
# The sqrtm matrix function should preserve the type of a matrix
|
||||
# whose eigenvalues are nonnegative with zero imaginary part.
|
||||
# Test this preservation for variously structured matrices.
|
||||
complex_dtype_chars = ('F', 'D', 'G')
|
||||
for matrix_as_list in (
|
||||
[[1, 0], [0, 1]],
|
||||
[[1, 0], [1, 1]],
|
||||
[[2, 1], [1, 1]],
|
||||
[[2, 3], [1, 2]],
|
||||
[[1, 1], [1, 1]]):
|
||||
|
||||
# check that the spectrum has the expected properties
|
||||
W = scipy.linalg.eigvals(matrix_as_list)
|
||||
assert_(not any(w.imag or w.real < 0 for w in W))
|
||||
|
||||
# check float type preservation
|
||||
A = np.array(matrix_as_list, dtype=float)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
assert_(A_sqrtm.dtype.char not in complex_dtype_chars)
|
||||
|
||||
# check complex type preservation
|
||||
A = np.array(matrix_as_list, dtype=complex)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
assert_(A_sqrtm.dtype.char in complex_dtype_chars)
|
||||
|
||||
# check float->complex type conversion for the matrix negation
|
||||
A = -np.array(matrix_as_list, dtype=float)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
assert_(A_sqrtm.dtype.char in complex_dtype_chars)
|
||||
|
||||
def test_sqrtm_type_conversion_mixed_sign_or_complex_spectrum(self):
|
||||
complex_dtype_chars = ('F', 'D', 'G')
|
||||
for matrix_as_list in (
|
||||
[[1, 0], [0, -1]],
|
||||
[[0, 1], [1, 0]],
|
||||
[[0, 1, 0], [0, 0, 1], [1, 0, 0]]):
|
||||
|
||||
# check that the spectrum has the expected properties
|
||||
W = scipy.linalg.eigvals(matrix_as_list)
|
||||
assert_(any(w.imag or w.real < 0 for w in W))
|
||||
|
||||
# check complex->complex
|
||||
A = np.array(matrix_as_list, dtype=complex)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
assert_(A_sqrtm.dtype.char in complex_dtype_chars)
|
||||
|
||||
# check float->complex
|
||||
A = np.array(matrix_as_list, dtype=float)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
assert_(A_sqrtm.dtype.char in complex_dtype_chars)
|
||||
|
||||
def test_blocksizes(self):
|
||||
# Make sure I do not goof up the blocksizes when they do not divide n.
|
||||
np.random.seed(1234)
|
||||
for n in range(1, 8):
|
||||
A = np.random.rand(n, n) + 1j*np.random.randn(n, n)
|
||||
A_sqrtm_default, info = sqrtm(A, disp=False, blocksize=n)
|
||||
assert_allclose(A, np.linalg.matrix_power(A_sqrtm_default, 2))
|
||||
for blocksize in range(1, 10):
|
||||
A_sqrtm_new, info = sqrtm(A, disp=False, blocksize=blocksize)
|
||||
assert_allclose(A_sqrtm_default, A_sqrtm_new)
|
||||
|
||||
def test_al_mohy_higham_2012_experiment_1(self):
|
||||
# Matrix square root of a tricky upper triangular matrix.
|
||||
A = _get_al_mohy_higham_2012_experiment_1()
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
A_round_trip = A_sqrtm.dot(A_sqrtm)
|
||||
assert_allclose(A_round_trip, A, rtol=1e-5)
|
||||
assert_allclose(np.tril(A_round_trip), np.tril(A))
|
||||
|
||||
def test_strict_upper_triangular(self):
|
||||
# This matrix has no square root.
|
||||
for dt in int, float:
|
||||
A = np.array([
|
||||
[0, 3, 0, 0],
|
||||
[0, 0, 3, 0],
|
||||
[0, 0, 0, 3],
|
||||
[0, 0, 0, 0]], dtype=dt)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
assert_(np.isnan(A_sqrtm).all())
|
||||
|
||||
def test_weird_matrix(self):
|
||||
# The square root of matrix B exists.
|
||||
for dt in int, float:
|
||||
A = np.array([
|
||||
[0, 0, 1],
|
||||
[0, 0, 0],
|
||||
[0, 1, 0]], dtype=dt)
|
||||
B = np.array([
|
||||
[0, 1, 0],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]], dtype=dt)
|
||||
assert_array_equal(B, A.dot(A))
|
||||
|
||||
# But scipy sqrtm is not clever enough to find it.
|
||||
B_sqrtm, info = sqrtm(B, disp=False)
|
||||
assert_(np.isnan(B_sqrtm).all())
|
||||
|
||||
def test_disp(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
A = np.random.rand(3, 3)
|
||||
B = sqrtm(A, disp=True)
|
||||
assert_allclose(B.dot(B), A)
|
||||
|
||||
def test_opposite_sign_complex_eigenvalues(self):
|
||||
M = [[2j, 4], [0, -2j]]
|
||||
R = [[1+1j, 2], [0, 1-1j]]
|
||||
assert_allclose(np.dot(R, R), M, atol=1e-14)
|
||||
assert_allclose(sqrtm(M), R, atol=1e-14)
|
||||
|
||||
def test_gh4866(self):
|
||||
M = np.array([[1, 0, 0, 1],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[1, 0, 0, 1]])
|
||||
R = np.array([[sqrt(0.5), 0, 0, sqrt(0.5)],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[sqrt(0.5), 0, 0, sqrt(0.5)]])
|
||||
assert_allclose(np.dot(R, R), M, atol=1e-14)
|
||||
assert_allclose(sqrtm(M), R, atol=1e-14)
|
||||
|
||||
def test_gh5336(self):
|
||||
M = np.diag([2, 1, 0])
|
||||
R = np.diag([sqrt(2), 1, 0])
|
||||
assert_allclose(np.dot(R, R), M, atol=1e-14)
|
||||
assert_allclose(sqrtm(M), R, atol=1e-14)
|
||||
|
||||
def test_gh7839(self):
|
||||
M = np.zeros((2, 2))
|
||||
R = np.zeros((2, 2))
|
||||
assert_allclose(np.dot(R, R), M, atol=1e-14)
|
||||
assert_allclose(sqrtm(M), R, atol=1e-14)
|
||||
|
||||
def test_data_size_preservation_uint_in_float_out(self):
|
||||
M = np.zeros((10, 10), dtype=np.uint8)
|
||||
# input bit size is 8, but minimum float bit size is 16
|
||||
assert sqrtm(M).dtype == np.float16
|
||||
M = np.zeros((10, 10), dtype=np.uint16)
|
||||
assert sqrtm(M).dtype == np.float16
|
||||
M = np.zeros((10, 10), dtype=np.uint32)
|
||||
assert sqrtm(M).dtype == np.float32
|
||||
M = np.zeros((10, 10), dtype=np.uint64)
|
||||
assert sqrtm(M).dtype == np.float64
|
||||
|
||||
def test_data_size_preservation_int_in_float_out(self):
|
||||
M = np.zeros((10, 10), dtype=np.int8)
|
||||
# input bit size is 8, but minimum float bit size is 16
|
||||
assert sqrtm(M).dtype == np.float16
|
||||
M = np.zeros((10, 10), dtype=np.int16)
|
||||
assert sqrtm(M).dtype == np.float16
|
||||
M = np.zeros((10, 10), dtype=np.int32)
|
||||
assert sqrtm(M).dtype == np.float32
|
||||
M = np.zeros((10, 10), dtype=np.int64)
|
||||
assert sqrtm(M).dtype == np.float64
|
||||
|
||||
def test_data_size_preservation_int_in_comp_out(self):
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.int8)
|
||||
# input bit size is 8, but minimum complex bit size is 64
|
||||
assert sqrtm(M).dtype == np.complex64
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.int16)
|
||||
# input bit size is 16, but minimum complex bit size is 64
|
||||
assert sqrtm(M).dtype == np.complex64
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.int32)
|
||||
assert sqrtm(M).dtype == np.complex64
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.int64)
|
||||
assert sqrtm(M).dtype == np.complex128
|
||||
|
||||
def test_data_size_preservation_float_in_float_out(self):
|
||||
M = np.zeros((10, 10), dtype=np.float16)
|
||||
assert sqrtm(M).dtype == np.float16
|
||||
M = np.zeros((10, 10), dtype=np.float32)
|
||||
assert sqrtm(M).dtype == np.float32
|
||||
M = np.zeros((10, 10), dtype=np.float64)
|
||||
assert sqrtm(M).dtype == np.float64
|
||||
if hasattr(np, 'float128'):
|
||||
M = np.zeros((10, 10), dtype=np.float128)
|
||||
assert sqrtm(M).dtype == np.float128
|
||||
|
||||
def test_data_size_preservation_float_in_comp_out(self):
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.float16)
|
||||
# input bit size is 16, but minimum complex bit size is 64
|
||||
assert sqrtm(M).dtype == np.complex64
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.float32)
|
||||
assert sqrtm(M).dtype == np.complex64
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.float64)
|
||||
assert sqrtm(M).dtype == np.complex128
|
||||
if hasattr(np, 'float128') and hasattr(np, 'complex256'):
|
||||
M = np.array([[2, 4], [0, -2]], dtype=np.float128)
|
||||
assert sqrtm(M).dtype == np.complex256
|
||||
|
||||
def test_data_size_preservation_comp_in_comp_out(self):
|
||||
M = np.array([[2j, 4], [0, -2j]], dtype=np.complex64)
|
||||
assert sqrtm(M).dtype == np.complex128
|
||||
if hasattr(np, 'complex256'):
|
||||
M = np.array([[2j, 4], [0, -2j]], dtype=np.complex128)
|
||||
assert sqrtm(M).dtype == np.complex256
|
||||
M = np.array([[2j, 4], [0, -2j]], dtype=np.complex256)
|
||||
assert sqrtm(M).dtype == np.complex256
|
||||
|
||||
|
||||
class TestFractionalMatrixPower:
|
||||
def test_round_trip_random_complex(self):
|
||||
np.random.seed(1234)
|
||||
for p in range(1, 5):
|
||||
for n in range(1, 5):
|
||||
M_unscaled = np.random.randn(n, n) + 1j * np.random.randn(n, n)
|
||||
for scale in np.logspace(-4, 4, 9):
|
||||
M = M_unscaled * scale
|
||||
M_root = fractional_matrix_power(M, 1/p)
|
||||
M_round_trip = np.linalg.matrix_power(M_root, p)
|
||||
assert_allclose(M_round_trip, M)
|
||||
|
||||
def test_round_trip_random_float(self):
|
||||
# This test is more annoying because it can hit the branch cut;
|
||||
# this happens when the matrix has an eigenvalue
|
||||
# with no imaginary component and with a real negative component,
|
||||
# and it means that the principal branch does not exist.
|
||||
np.random.seed(1234)
|
||||
for p in range(1, 5):
|
||||
for n in range(1, 5):
|
||||
M_unscaled = np.random.randn(n, n)
|
||||
for scale in np.logspace(-4, 4, 9):
|
||||
M = M_unscaled * scale
|
||||
M_root = fractional_matrix_power(M, 1/p)
|
||||
M_round_trip = np.linalg.matrix_power(M_root, p)
|
||||
assert_allclose(M_round_trip, M)
|
||||
|
||||
def test_larger_abs_fractional_matrix_powers(self):
|
||||
np.random.seed(1234)
|
||||
for n in (2, 3, 5):
|
||||
for i in range(10):
|
||||
M = np.random.randn(n, n) + 1j * np.random.randn(n, n)
|
||||
M_one_fifth = fractional_matrix_power(M, 0.2)
|
||||
# Test the round trip.
|
||||
M_round_trip = np.linalg.matrix_power(M_one_fifth, 5)
|
||||
assert_allclose(M, M_round_trip)
|
||||
# Test a large abs fractional power.
|
||||
X = fractional_matrix_power(M, -5.4)
|
||||
Y = np.linalg.matrix_power(M_one_fifth, -27)
|
||||
assert_allclose(X, Y)
|
||||
# Test another large abs fractional power.
|
||||
X = fractional_matrix_power(M, 3.8)
|
||||
Y = np.linalg.matrix_power(M_one_fifth, 19)
|
||||
assert_allclose(X, Y)
|
||||
|
||||
def test_random_matrices_and_powers(self):
|
||||
# Each independent iteration of this fuzz test picks random parameters.
|
||||
# It tries to hit some edge cases.
|
||||
np.random.seed(1234)
|
||||
nsamples = 20
|
||||
for i in range(nsamples):
|
||||
# Sample a matrix size and a random real power.
|
||||
n = random.randrange(1, 5)
|
||||
p = np.random.randn()
|
||||
|
||||
# Sample a random real or complex matrix.
|
||||
matrix_scale = np.exp(random.randrange(-4, 5))
|
||||
A = np.random.randn(n, n)
|
||||
if random.choice((True, False)):
|
||||
A = A + 1j * np.random.randn(n, n)
|
||||
A = A * matrix_scale
|
||||
|
||||
# Check a couple of analytically equivalent ways
|
||||
# to compute the fractional matrix power.
|
||||
# These can be compared because they both use the principal branch.
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
A_logm, info = logm(A, disp=False)
|
||||
A_power_expm_logm = expm(A_logm * p)
|
||||
assert_allclose(A_power, A_power_expm_logm)
|
||||
|
||||
def test_al_mohy_higham_2012_experiment_1(self):
|
||||
# Fractional powers of a tricky upper triangular matrix.
|
||||
A = _get_al_mohy_higham_2012_experiment_1()
|
||||
|
||||
# Test remainder matrix power.
|
||||
A_funm_sqrt, info = funm(A, np.sqrt, disp=False)
|
||||
A_sqrtm, info = sqrtm(A, disp=False)
|
||||
A_rem_power = _matfuncs_inv_ssq._remainder_matrix_power(A, 0.5)
|
||||
A_power = fractional_matrix_power(A, 0.5)
|
||||
assert_array_equal(A_rem_power, A_power)
|
||||
assert_allclose(A_sqrtm, A_power)
|
||||
assert_allclose(A_sqrtm, A_funm_sqrt)
|
||||
|
||||
# Test more fractional powers.
|
||||
for p in (1/2, 5/3):
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
A_round_trip = fractional_matrix_power(A_power, 1/p)
|
||||
assert_allclose(A_round_trip, A, rtol=1e-2)
|
||||
assert_allclose(np.tril(A_round_trip, 1), np.tril(A, 1))
|
||||
|
||||
def test_briggs_helper_function(self):
|
||||
np.random.seed(1234)
|
||||
for a in np.random.randn(10) + 1j * np.random.randn(10):
|
||||
for k in range(5):
|
||||
x_observed = _matfuncs_inv_ssq._briggs_helper_function(a, k)
|
||||
x_expected = a ** np.exp2(-k) - 1
|
||||
assert_allclose(x_observed, x_expected)
|
||||
|
||||
def test_type_preservation_and_conversion(self):
|
||||
# The fractional_matrix_power matrix function should preserve
|
||||
# the type of a matrix whose eigenvalues
|
||||
# are positive with zero imaginary part.
|
||||
# Test this preservation for variously structured matrices.
|
||||
complex_dtype_chars = ('F', 'D', 'G')
|
||||
for matrix_as_list in (
|
||||
[[1, 0], [0, 1]],
|
||||
[[1, 0], [1, 1]],
|
||||
[[2, 1], [1, 1]],
|
||||
[[2, 3], [1, 2]]):
|
||||
|
||||
# check that the spectrum has the expected properties
|
||||
W = scipy.linalg.eigvals(matrix_as_list)
|
||||
assert_(not any(w.imag or w.real < 0 for w in W))
|
||||
|
||||
# Check various positive and negative powers
|
||||
# with absolute values bigger and smaller than 1.
|
||||
for p in (-2.4, -0.9, 0.2, 3.3):
|
||||
|
||||
# check float type preservation
|
||||
A = np.array(matrix_as_list, dtype=float)
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
assert_(A_power.dtype.char not in complex_dtype_chars)
|
||||
|
||||
# check complex type preservation
|
||||
A = np.array(matrix_as_list, dtype=complex)
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
assert_(A_power.dtype.char in complex_dtype_chars)
|
||||
|
||||
# check float->complex for the matrix negation
|
||||
A = -np.array(matrix_as_list, dtype=float)
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
assert_(A_power.dtype.char in complex_dtype_chars)
|
||||
|
||||
def test_type_conversion_mixed_sign_or_complex_spectrum(self):
|
||||
complex_dtype_chars = ('F', 'D', 'G')
|
||||
for matrix_as_list in (
|
||||
[[1, 0], [0, -1]],
|
||||
[[0, 1], [1, 0]],
|
||||
[[0, 1, 0], [0, 0, 1], [1, 0, 0]]):
|
||||
|
||||
# check that the spectrum has the expected properties
|
||||
W = scipy.linalg.eigvals(matrix_as_list)
|
||||
assert_(any(w.imag or w.real < 0 for w in W))
|
||||
|
||||
# Check various positive and negative powers
|
||||
# with absolute values bigger and smaller than 1.
|
||||
for p in (-2.4, -0.9, 0.2, 3.3):
|
||||
|
||||
# check complex->complex
|
||||
A = np.array(matrix_as_list, dtype=complex)
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
assert_(A_power.dtype.char in complex_dtype_chars)
|
||||
|
||||
# check float->complex
|
||||
A = np.array(matrix_as_list, dtype=float)
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
assert_(A_power.dtype.char in complex_dtype_chars)
|
||||
|
||||
@pytest.mark.xfail(reason='Too unstable across LAPACKs.')
|
||||
def test_singular(self):
|
||||
# Negative fractional powers do not work with singular matrices.
|
||||
for matrix_as_list in (
|
||||
[[0, 0], [0, 0]],
|
||||
[[1, 1], [1, 1]],
|
||||
[[1, 2], [3, 6]],
|
||||
[[0, 0, 0], [0, 1, 1], [0, -1, 1]]):
|
||||
|
||||
# Check fractional powers both for float and for complex types.
|
||||
for newtype in (float, complex):
|
||||
A = np.array(matrix_as_list, dtype=newtype)
|
||||
for p in (-0.7, -0.9, -2.4, -1.3):
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
assert_(np.isnan(A_power).all())
|
||||
for p in (0.2, 1.43):
|
||||
A_power = fractional_matrix_power(A, p)
|
||||
A_round_trip = fractional_matrix_power(A_power, 1/p)
|
||||
assert_allclose(A_round_trip, A)
|
||||
|
||||
def test_opposite_sign_complex_eigenvalues(self):
|
||||
M = [[2j, 4], [0, -2j]]
|
||||
R = [[1+1j, 2], [0, 1-1j]]
|
||||
assert_allclose(np.dot(R, R), M, atol=1e-14)
|
||||
assert_allclose(fractional_matrix_power(M, 0.5), R, atol=1e-14)
|
||||
|
||||
|
||||
class TestExpM:
|
||||
def test_zero(self):
|
||||
a = array([[0.,0],[0,0]])
|
||||
assert_array_almost_equal(expm(a),[[1,0],[0,1]])
|
||||
|
||||
def test_single_elt(self):
|
||||
elt = expm(1)
|
||||
assert_allclose(elt, np.array([[np.e]]))
|
||||
|
||||
def test_empty_matrix_input(self):
|
||||
# handle gh-11082
|
||||
A = np.zeros((0, 0))
|
||||
result = expm(A)
|
||||
assert result.size == 0
|
||||
|
||||
def test_2x2_input(self):
|
||||
E = np.e
|
||||
a = array([[1, 4], [1, 1]])
|
||||
aa = (E**4 + 1)/(2*E)
|
||||
bb = (E**4 - 1)/E
|
||||
assert_allclose(expm(a), array([[aa, bb], [bb/4, aa]]))
|
||||
assert expm(a.astype(np.complex64)).dtype.char == 'F'
|
||||
assert expm(a.astype(np.float32)).dtype.char == 'f'
|
||||
|
||||
def test_nx2x2_input(self):
|
||||
E = np.e
|
||||
# These are integer matrices with integer eigenvalues
|
||||
a = np.array([[[1, 4], [1, 1]],
|
||||
[[1, 3], [1, -1]],
|
||||
[[1, 3], [4, 5]],
|
||||
[[1, 3], [5, 3]],
|
||||
[[4, 5], [-3, -4]]], order='F')
|
||||
# Exact results are computed symbolically
|
||||
a_res = np.array([
|
||||
[[(E**4+1)/(2*E), (E**4-1)/E],
|
||||
[(E**4-1)/4/E, (E**4+1)/(2*E)]],
|
||||
[[1/(4*E**2)+(3*E**2)/4, (3*E**2)/4-3/(4*E**2)],
|
||||
[E**2/4-1/(4*E**2), 3/(4*E**2)+E**2/4]],
|
||||
[[3/(4*E)+E**7/4, -3/(8*E)+(3*E**7)/8],
|
||||
[-1/(2*E)+E**7/2, 1/(4*E)+(3*E**7)/4]],
|
||||
[[5/(8*E**2)+(3*E**6)/8, -3/(8*E**2)+(3*E**6)/8],
|
||||
[-5/(8*E**2)+(5*E**6)/8, 3/(8*E**2)+(5*E**6)/8]],
|
||||
[[-3/(2*E)+(5*E)/2, -5/(2*E)+(5*E)/2],
|
||||
[3/(2*E)-(3*E)/2, 5/(2*E)-(3*E)/2]]
|
||||
])
|
||||
assert_allclose(expm(a), a_res)
|
||||
|
||||
|
||||
class TestExpmFrechet:
|
||||
|
||||
def test_expm_frechet(self):
|
||||
# a test of the basic functionality
|
||||
M = np.array([
|
||||
[1, 2, 3, 4],
|
||||
[5, 6, 7, 8],
|
||||
[0, 0, 1, 2],
|
||||
[0, 0, 5, 6],
|
||||
], dtype=float)
|
||||
A = np.array([
|
||||
[1, 2],
|
||||
[5, 6],
|
||||
], dtype=float)
|
||||
E = np.array([
|
||||
[3, 4],
|
||||
[7, 8],
|
||||
], dtype=float)
|
||||
expected_expm = scipy.linalg.expm(A)
|
||||
expected_frechet = scipy.linalg.expm(M)[:2, 2:]
|
||||
for kwargs in ({}, {'method':'SPS'}, {'method':'blockEnlarge'}):
|
||||
observed_expm, observed_frechet = expm_frechet(A, E, **kwargs)
|
||||
assert_allclose(expected_expm, observed_expm)
|
||||
assert_allclose(expected_frechet, observed_frechet)
|
||||
|
||||
def test_small_norm_expm_frechet(self):
|
||||
# methodically test matrices with a range of norms, for better coverage
|
||||
M_original = np.array([
|
||||
[1, 2, 3, 4],
|
||||
[5, 6, 7, 8],
|
||||
[0, 0, 1, 2],
|
||||
[0, 0, 5, 6],
|
||||
], dtype=float)
|
||||
A_original = np.array([
|
||||
[1, 2],
|
||||
[5, 6],
|
||||
], dtype=float)
|
||||
E_original = np.array([
|
||||
[3, 4],
|
||||
[7, 8],
|
||||
], dtype=float)
|
||||
A_original_norm_1 = scipy.linalg.norm(A_original, 1)
|
||||
selected_m_list = [1, 3, 5, 7, 9, 11, 13, 15]
|
||||
m_neighbor_pairs = zip(selected_m_list[:-1], selected_m_list[1:])
|
||||
for ma, mb in m_neighbor_pairs:
|
||||
ell_a = scipy.linalg._expm_frechet.ell_table_61[ma]
|
||||
ell_b = scipy.linalg._expm_frechet.ell_table_61[mb]
|
||||
target_norm_1 = 0.5 * (ell_a + ell_b)
|
||||
scale = target_norm_1 / A_original_norm_1
|
||||
M = scale * M_original
|
||||
A = scale * A_original
|
||||
E = scale * E_original
|
||||
expected_expm = scipy.linalg.expm(A)
|
||||
expected_frechet = scipy.linalg.expm(M)[:2, 2:]
|
||||
observed_expm, observed_frechet = expm_frechet(A, E)
|
||||
assert_allclose(expected_expm, observed_expm)
|
||||
assert_allclose(expected_frechet, observed_frechet)
|
||||
|
||||
def test_fuzz(self):
|
||||
# try a bunch of crazy inputs
|
||||
rfuncs = (
|
||||
np.random.uniform,
|
||||
np.random.normal,
|
||||
np.random.standard_cauchy,
|
||||
np.random.exponential)
|
||||
ntests = 100
|
||||
for i in range(ntests):
|
||||
rfunc = random.choice(rfuncs)
|
||||
target_norm_1 = random.expovariate(1.0)
|
||||
n = random.randrange(2, 16)
|
||||
A_original = rfunc(size=(n,n))
|
||||
E_original = rfunc(size=(n,n))
|
||||
A_original_norm_1 = scipy.linalg.norm(A_original, 1)
|
||||
scale = target_norm_1 / A_original_norm_1
|
||||
A = scale * A_original
|
||||
E = scale * E_original
|
||||
M = np.vstack([
|
||||
np.hstack([A, E]),
|
||||
np.hstack([np.zeros_like(A), A])])
|
||||
expected_expm = scipy.linalg.expm(A)
|
||||
expected_frechet = scipy.linalg.expm(M)[:n, n:]
|
||||
observed_expm, observed_frechet = expm_frechet(A, E)
|
||||
assert_allclose(expected_expm, observed_expm, atol=5e-8)
|
||||
assert_allclose(expected_frechet, observed_frechet, atol=1e-7)
|
||||
|
||||
def test_problematic_matrix(self):
|
||||
# this test case uncovered a bug which has since been fixed
|
||||
A = np.array([
|
||||
[1.50591997, 1.93537998],
|
||||
[0.41203263, 0.23443516],
|
||||
], dtype=float)
|
||||
E = np.array([
|
||||
[1.87864034, 2.07055038],
|
||||
[1.34102727, 0.67341123],
|
||||
], dtype=float)
|
||||
scipy.linalg.norm(A, 1)
|
||||
sps_expm, sps_frechet = expm_frechet(
|
||||
A, E, method='SPS')
|
||||
blockEnlarge_expm, blockEnlarge_frechet = expm_frechet(
|
||||
A, E, method='blockEnlarge')
|
||||
assert_allclose(sps_expm, blockEnlarge_expm)
|
||||
assert_allclose(sps_frechet, blockEnlarge_frechet)
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skip(reason='this test is deliberately slow')
|
||||
def test_medium_matrix(self):
|
||||
# profile this to see the speed difference
|
||||
n = 1000
|
||||
A = np.random.exponential(size=(n, n))
|
||||
E = np.random.exponential(size=(n, n))
|
||||
sps_expm, sps_frechet = expm_frechet(
|
||||
A, E, method='SPS')
|
||||
blockEnlarge_expm, blockEnlarge_frechet = expm_frechet(
|
||||
A, E, method='blockEnlarge')
|
||||
assert_allclose(sps_expm, blockEnlarge_expm)
|
||||
assert_allclose(sps_frechet, blockEnlarge_frechet)
|
||||
|
||||
|
||||
def _help_expm_cond_search(A, A_norm, X, X_norm, eps, p):
|
||||
p = np.reshape(p, A.shape)
|
||||
p_norm = norm(p)
|
||||
perturbation = eps * p * (A_norm / p_norm)
|
||||
X_prime = expm(A + perturbation)
|
||||
scaled_relative_error = norm(X_prime - X) / (X_norm * eps)
|
||||
return -scaled_relative_error
|
||||
|
||||
|
||||
def _normalized_like(A, B):
|
||||
return A * (scipy.linalg.norm(B) / scipy.linalg.norm(A))
|
||||
|
||||
|
||||
def _relative_error(f, A, perturbation):
|
||||
X = f(A)
|
||||
X_prime = f(A + perturbation)
|
||||
return norm(X_prime - X) / norm(X)
|
||||
|
||||
|
||||
class TestExpmConditionNumber:
|
||||
def test_expm_cond_smoke(self):
|
||||
np.random.seed(1234)
|
||||
for n in range(1, 4):
|
||||
A = np.random.randn(n, n)
|
||||
kappa = expm_cond(A)
|
||||
assert_array_less(0, kappa)
|
||||
|
||||
def test_expm_bad_condition_number(self):
|
||||
A = np.array([
|
||||
[-1.128679820, 9.614183771e4, -4.524855739e9, 2.924969411e14],
|
||||
[0, -1.201010529, 9.634696872e4, -4.681048289e9],
|
||||
[0, 0, -1.132893222, 9.532491830e4],
|
||||
[0, 0, 0, -1.179475332],
|
||||
])
|
||||
kappa = expm_cond(A)
|
||||
assert_array_less(1e36, kappa)
|
||||
|
||||
def test_univariate(self):
|
||||
np.random.seed(12345)
|
||||
for x in np.linspace(-5, 5, num=11):
|
||||
A = np.array([[x]])
|
||||
assert_allclose(expm_cond(A), abs(x))
|
||||
for x in np.logspace(-2, 2, num=11):
|
||||
A = np.array([[x]])
|
||||
assert_allclose(expm_cond(A), abs(x))
|
||||
for i in range(10):
|
||||
A = np.random.randn(1, 1)
|
||||
assert_allclose(expm_cond(A), np.absolute(A)[0, 0])
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_expm_cond_fuzz(self):
|
||||
np.random.seed(12345)
|
||||
eps = 1e-5
|
||||
nsamples = 10
|
||||
for i in range(nsamples):
|
||||
n = np.random.randint(2, 5)
|
||||
A = np.random.randn(n, n)
|
||||
A_norm = scipy.linalg.norm(A)
|
||||
X = expm(A)
|
||||
X_norm = scipy.linalg.norm(X)
|
||||
kappa = expm_cond(A)
|
||||
|
||||
# Look for the small perturbation that gives the greatest
|
||||
# relative error.
|
||||
f = functools.partial(_help_expm_cond_search,
|
||||
A, A_norm, X, X_norm, eps)
|
||||
guess = np.ones(n*n)
|
||||
out = minimize(f, guess, method='L-BFGS-B')
|
||||
xopt = out.x
|
||||
yopt = f(xopt)
|
||||
p_best = eps * _normalized_like(np.reshape(xopt, A.shape), A)
|
||||
p_best_relerr = _relative_error(expm, A, p_best)
|
||||
assert_allclose(p_best_relerr, -yopt * eps)
|
||||
|
||||
# Check that the identified perturbation indeed gives greater
|
||||
# relative error than random perturbations with similar norms.
|
||||
for j in range(5):
|
||||
p_rand = eps * _normalized_like(np.random.randn(*A.shape), A)
|
||||
assert_allclose(norm(p_best), norm(p_rand))
|
||||
p_rand_relerr = _relative_error(expm, A, p_rand)
|
||||
assert_array_less(p_rand_relerr, p_best_relerr)
|
||||
|
||||
# The greatest relative error should not be much greater than
|
||||
# eps times the condition number kappa.
|
||||
# In the limit as eps approaches zero it should never be greater.
|
||||
assert_array_less(p_best_relerr, (1 + 2*eps) * eps * kappa)
|
||||
|
||||
|
||||
class TestKhatriRao:
|
||||
|
||||
def test_basic(self):
|
||||
a = khatri_rao(array([[1, 2], [3, 4]]),
|
||||
array([[5, 6], [7, 8]]))
|
||||
|
||||
assert_array_equal(a, array([[5, 12],
|
||||
[7, 16],
|
||||
[15, 24],
|
||||
[21, 32]]))
|
||||
|
||||
b = khatri_rao(np.empty([2, 2]), np.empty([2, 2]))
|
||||
assert_array_equal(b.shape, (4, 2))
|
||||
|
||||
def test_number_of_columns_equality(self):
|
||||
with pytest.raises(ValueError):
|
||||
a = array([[1, 2, 3],
|
||||
[4, 5, 6]])
|
||||
b = array([[1, 2],
|
||||
[3, 4]])
|
||||
khatri_rao(a, b)
|
||||
|
||||
def test_to_assure_2d_array(self):
|
||||
with pytest.raises(ValueError):
|
||||
# both arrays are 1-D
|
||||
a = array([1, 2, 3])
|
||||
b = array([4, 5, 6])
|
||||
khatri_rao(a, b)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# first array is 1-D
|
||||
a = array([1, 2, 3])
|
||||
b = array([
|
||||
[1, 2, 3],
|
||||
[4, 5, 6]
|
||||
])
|
||||
khatri_rao(a, b)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# second array is 1-D
|
||||
a = array([
|
||||
[1, 2, 3],
|
||||
[7, 8, 9]
|
||||
])
|
||||
b = array([4, 5, 6])
|
||||
khatri_rao(a, b)
|
||||
|
||||
def test_equality_of_two_equations(self):
|
||||
a = array([[1, 2], [3, 4]])
|
||||
b = array([[5, 6], [7, 8]])
|
||||
|
||||
res1 = khatri_rao(a, b)
|
||||
res2 = np.vstack([np.kron(a[:, k], b[:, k])
|
||||
for k in range(b.shape[1])]).T
|
||||
|
||||
assert_array_equal(res1, res2)
|
||||
125
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_matmul_toeplitz.py
vendored
Normal file
125
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_matmul_toeplitz.py
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
"""Test functions for linalg.matmul_toeplitz function
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from scipy.linalg import toeplitz, matmul_toeplitz
|
||||
|
||||
from pytest import raises as assert_raises
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
|
||||
class TestMatmulToeplitz:
|
||||
|
||||
def setup_method(self):
|
||||
self.rng = np.random.RandomState(42)
|
||||
self.tolerance = 1.5e-13
|
||||
|
||||
def test_real(self):
|
||||
cases = []
|
||||
|
||||
n = 1
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n)
|
||||
x = self.rng.normal(size=(n, 1))
|
||||
cases.append((x, c, r, False))
|
||||
|
||||
n = 2
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n)
|
||||
x = self.rng.normal(size=(n, 1))
|
||||
cases.append((x, c, r, False))
|
||||
|
||||
n = 101
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n)
|
||||
x = self.rng.normal(size=(n, 1))
|
||||
cases.append((x, c, r, True))
|
||||
|
||||
n = 1000
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n)
|
||||
x = self.rng.normal(size=(n, 1))
|
||||
cases.append((x, c, r, False))
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n)
|
||||
x = self.rng.normal(size=(n, self.rng.randint(1, 10)))
|
||||
cases.append((x, c, r, False))
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=(n, 1))
|
||||
r = self.rng.normal(size=(n, 1))
|
||||
x = self.rng.normal(size=(n, self.rng.randint(1, 10)))
|
||||
cases.append((x, c, r, True))
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=(n, 1))
|
||||
r = None
|
||||
x = self.rng.normal(size=(n, self.rng.randint(1, 10)))
|
||||
cases.append((x, c, r, True, -1))
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=(n, 1))
|
||||
r = None
|
||||
x = self.rng.normal(size=n)
|
||||
cases.append((x, c, r, False))
|
||||
|
||||
n = 101
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n-27)
|
||||
x = self.rng.normal(size=(n-27, 1))
|
||||
cases.append((x, c, r, True))
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n//4)
|
||||
x = self.rng.normal(size=(n//4, self.rng.randint(1, 10)))
|
||||
cases.append((x, c, r, True))
|
||||
|
||||
[self.do(*i) for i in cases]
|
||||
|
||||
def test_complex(self):
|
||||
n = 127
|
||||
c = self.rng.normal(size=(n, 1)) + self.rng.normal(size=(n, 1))*1j
|
||||
r = self.rng.normal(size=(n, 1)) + self.rng.normal(size=(n, 1))*1j
|
||||
x = self.rng.normal(size=(n, 3)) + self.rng.normal(size=(n, 3))*1j
|
||||
self.do(x, c, r, False)
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=(n, 1)) + self.rng.normal(size=(n, 1))*1j
|
||||
r = self.rng.normal(size=(n//2, 1)) +\
|
||||
self.rng.normal(size=(n//2, 1))*1j
|
||||
x = self.rng.normal(size=(n//2, 3)) +\
|
||||
self.rng.normal(size=(n//2, 3))*1j
|
||||
self.do(x, c, r, False)
|
||||
|
||||
def test_exceptions(self):
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=2*n)
|
||||
x = self.rng.normal(size=n)
|
||||
assert_raises(ValueError, matmul_toeplitz, (c, r), x, True)
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n)
|
||||
x = self.rng.normal(size=n-1)
|
||||
assert_raises(ValueError, matmul_toeplitz, (c, r), x, True)
|
||||
|
||||
n = 100
|
||||
c = self.rng.normal(size=n)
|
||||
r = self.rng.normal(size=n//2)
|
||||
x = self.rng.normal(size=n//2-1)
|
||||
assert_raises(ValueError, matmul_toeplitz, (c, r), x, True)
|
||||
|
||||
# For toeplitz matrices, matmul_toeplitz() should be equivalent to @.
|
||||
def do(self, x, c, r=None, check_finite=False, workers=None):
|
||||
if r is None:
|
||||
actual = matmul_toeplitz(c, x, check_finite, workers)
|
||||
else:
|
||||
actual = matmul_toeplitz((c, r), x, check_finite)
|
||||
desired = toeplitz(c, r) @ x
|
||||
assert_allclose(actual, desired,
|
||||
rtol=self.tolerance, atol=self.tolerance)
|
||||
5
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_misc.py
vendored
Normal file
5
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_misc.py
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
from scipy.linalg import norm
|
||||
|
||||
|
||||
def test_norm():
|
||||
assert norm([]) == 0.0
|
||||
191
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_procrustes.py
vendored
Normal file
191
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_procrustes.py
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
from itertools import product, permutations
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_array_less, assert_allclose
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from scipy.linalg import inv, eigh, norm
|
||||
from scipy.linalg import orthogonal_procrustes
|
||||
from scipy.sparse._sputils import matrix
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_ndim_too_large():
|
||||
np.random.seed(1234)
|
||||
A = np.random.randn(3, 4, 5)
|
||||
B = np.random.randn(3, 4, 5)
|
||||
assert_raises(ValueError, orthogonal_procrustes, A, B)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_ndim_too_small():
|
||||
np.random.seed(1234)
|
||||
A = np.random.randn(3)
|
||||
B = np.random.randn(3)
|
||||
assert_raises(ValueError, orthogonal_procrustes, A, B)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_shape_mismatch():
|
||||
np.random.seed(1234)
|
||||
shapes = ((3, 3), (3, 4), (4, 3), (4, 4))
|
||||
for a, b in permutations(shapes, 2):
|
||||
A = np.random.randn(*a)
|
||||
B = np.random.randn(*b)
|
||||
assert_raises(ValueError, orthogonal_procrustes, A, B)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_checkfinite_exception():
|
||||
np.random.seed(1234)
|
||||
m, n = 2, 3
|
||||
A_good = np.random.randn(m, n)
|
||||
B_good = np.random.randn(m, n)
|
||||
for bad_value in np.inf, -np.inf, np.nan:
|
||||
A_bad = A_good.copy()
|
||||
A_bad[1, 2] = bad_value
|
||||
B_bad = B_good.copy()
|
||||
B_bad[1, 2] = bad_value
|
||||
for A, B in ((A_good, B_bad), (A_bad, B_good), (A_bad, B_bad)):
|
||||
assert_raises(ValueError, orthogonal_procrustes, A, B)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_scale_invariance():
|
||||
np.random.seed(1234)
|
||||
m, n = 4, 3
|
||||
for i in range(3):
|
||||
A_orig = np.random.randn(m, n)
|
||||
B_orig = np.random.randn(m, n)
|
||||
R_orig, s = orthogonal_procrustes(A_orig, B_orig)
|
||||
for A_scale in np.square(np.random.randn(3)):
|
||||
for B_scale in np.square(np.random.randn(3)):
|
||||
R, s = orthogonal_procrustes(A_orig * A_scale, B_orig * B_scale)
|
||||
assert_allclose(R, R_orig)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_array_conversion():
|
||||
np.random.seed(1234)
|
||||
for m, n in ((6, 4), (4, 4), (4, 6)):
|
||||
A_arr = np.random.randn(m, n)
|
||||
B_arr = np.random.randn(m, n)
|
||||
As = (A_arr, A_arr.tolist(), matrix(A_arr))
|
||||
Bs = (B_arr, B_arr.tolist(), matrix(B_arr))
|
||||
R_arr, s = orthogonal_procrustes(A_arr, B_arr)
|
||||
AR_arr = A_arr.dot(R_arr)
|
||||
for A, B in product(As, Bs):
|
||||
R, s = orthogonal_procrustes(A, B)
|
||||
AR = A_arr.dot(R)
|
||||
assert_allclose(AR, AR_arr)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes():
|
||||
np.random.seed(1234)
|
||||
for m, n in ((6, 4), (4, 4), (4, 6)):
|
||||
# Sample a random target matrix.
|
||||
B = np.random.randn(m, n)
|
||||
# Sample a random orthogonal matrix
|
||||
# by computing eigh of a sampled symmetric matrix.
|
||||
X = np.random.randn(n, n)
|
||||
w, V = eigh(X.T + X)
|
||||
assert_allclose(inv(V), V.T)
|
||||
# Compute a matrix with a known orthogonal transformation that gives B.
|
||||
A = np.dot(B, V.T)
|
||||
# Check that an orthogonal transformation from A to B can be recovered.
|
||||
R, s = orthogonal_procrustes(A, B)
|
||||
assert_allclose(inv(R), R.T)
|
||||
assert_allclose(A.dot(R), B)
|
||||
# Create a perturbed input matrix.
|
||||
A_perturbed = A + 1e-2 * np.random.randn(m, n)
|
||||
# Check that the orthogonal procrustes function can find an orthogonal
|
||||
# transformation that is better than the orthogonal transformation
|
||||
# computed from the original input matrix.
|
||||
R_prime, s = orthogonal_procrustes(A_perturbed, B)
|
||||
assert_allclose(inv(R_prime), R_prime.T)
|
||||
# Compute the naive and optimal transformations of the perturbed input.
|
||||
naive_approx = A_perturbed.dot(R)
|
||||
optim_approx = A_perturbed.dot(R_prime)
|
||||
# Compute the Frobenius norm errors of the matrix approximations.
|
||||
naive_approx_error = norm(naive_approx - B, ord='fro')
|
||||
optim_approx_error = norm(optim_approx - B, ord='fro')
|
||||
# Check that the orthogonal Procrustes approximation is better.
|
||||
assert_array_less(optim_approx_error, naive_approx_error)
|
||||
|
||||
|
||||
def _centered(A):
|
||||
mu = A.mean(axis=0)
|
||||
return A - mu, mu
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_exact_example():
|
||||
# Check a small application.
|
||||
# It uses translation, scaling, reflection, and rotation.
|
||||
#
|
||||
# |
|
||||
# a b |
|
||||
# |
|
||||
# d c | w
|
||||
# |
|
||||
# --------+--- x ----- z ---
|
||||
# |
|
||||
# | y
|
||||
# |
|
||||
#
|
||||
A_orig = np.array([[-3, 3], [-2, 3], [-2, 2], [-3, 2]], dtype=float)
|
||||
B_orig = np.array([[3, 2], [1, 0], [3, -2], [5, 0]], dtype=float)
|
||||
A, A_mu = _centered(A_orig)
|
||||
B, B_mu = _centered(B_orig)
|
||||
R, s = orthogonal_procrustes(A, B)
|
||||
scale = s / np.square(norm(A))
|
||||
B_approx = scale * np.dot(A, R) + B_mu
|
||||
assert_allclose(B_approx, B_orig, atol=1e-8)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_stretched_example():
|
||||
# Try again with a target with a stretched y axis.
|
||||
A_orig = np.array([[-3, 3], [-2, 3], [-2, 2], [-3, 2]], dtype=float)
|
||||
B_orig = np.array([[3, 40], [1, 0], [3, -40], [5, 0]], dtype=float)
|
||||
A, A_mu = _centered(A_orig)
|
||||
B, B_mu = _centered(B_orig)
|
||||
R, s = orthogonal_procrustes(A, B)
|
||||
scale = s / np.square(norm(A))
|
||||
B_approx = scale * np.dot(A, R) + B_mu
|
||||
expected = np.array([[3, 21], [-18, 0], [3, -21], [24, 0]], dtype=float)
|
||||
assert_allclose(B_approx, expected, atol=1e-8)
|
||||
# Check disparity symmetry.
|
||||
expected_disparity = 0.4501246882793018
|
||||
AB_disparity = np.square(norm(B_approx - B_orig) / norm(B))
|
||||
assert_allclose(AB_disparity, expected_disparity)
|
||||
R, s = orthogonal_procrustes(B, A)
|
||||
scale = s / np.square(norm(B))
|
||||
A_approx = scale * np.dot(B, R) + A_mu
|
||||
BA_disparity = np.square(norm(A_approx - A_orig) / norm(A))
|
||||
assert_allclose(BA_disparity, expected_disparity)
|
||||
|
||||
|
||||
def test_orthogonal_procrustes_skbio_example():
|
||||
# This transformation is also exact.
|
||||
# It uses translation, scaling, and reflection.
|
||||
#
|
||||
# |
|
||||
# | a
|
||||
# | b
|
||||
# | c d
|
||||
# --+---------
|
||||
# |
|
||||
# | w
|
||||
# |
|
||||
# | x
|
||||
# |
|
||||
# | z y
|
||||
# |
|
||||
#
|
||||
A_orig = np.array([[4, -2], [4, -4], [4, -6], [2, -6]], dtype=float)
|
||||
B_orig = np.array([[1, 3], [1, 2], [1, 1], [2, 1]], dtype=float)
|
||||
B_standardized = np.array([
|
||||
[-0.13363062, 0.6681531],
|
||||
[-0.13363062, 0.13363062],
|
||||
[-0.13363062, -0.40089186],
|
||||
[0.40089186, -0.40089186]])
|
||||
A, A_mu = _centered(A_orig)
|
||||
B, B_mu = _centered(B_orig)
|
||||
R, s = orthogonal_procrustes(A, B)
|
||||
scale = s / np.square(norm(A))
|
||||
B_approx = scale * np.dot(A, R) + B_mu
|
||||
assert_allclose(B_approx, B_orig)
|
||||
assert_allclose(B / norm(B), B_standardized)
|
||||
118
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_sketches.py
vendored
Normal file
118
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_sketches.py
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
"""Tests for _sketches.py."""
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_, assert_equal
|
||||
from scipy.linalg import clarkson_woodruff_transform
|
||||
from scipy.linalg._sketches import cwt_matrix
|
||||
from scipy.sparse import issparse, rand
|
||||
from scipy.sparse.linalg import norm
|
||||
|
||||
|
||||
class TestClarksonWoodruffTransform:
|
||||
"""
|
||||
Testing the Clarkson Woodruff Transform
|
||||
"""
|
||||
# set seed for generating test matrices
|
||||
rng = np.random.RandomState(seed=1179103485)
|
||||
|
||||
# Test matrix parameters
|
||||
n_rows = 2000
|
||||
n_cols = 100
|
||||
density = 0.1
|
||||
|
||||
# Sketch matrix dimensions
|
||||
n_sketch_rows = 200
|
||||
|
||||
# Seeds to test with
|
||||
seeds = [1755490010, 934377150, 1391612830, 1752708722, 2008891431,
|
||||
1302443994, 1521083269, 1501189312, 1126232505, 1533465685]
|
||||
|
||||
A_dense = rng.randn(n_rows, n_cols)
|
||||
A_csc = rand(
|
||||
n_rows, n_cols, density=density, format='csc', random_state=rng,
|
||||
)
|
||||
A_csr = rand(
|
||||
n_rows, n_cols, density=density, format='csr', random_state=rng,
|
||||
)
|
||||
A_coo = rand(
|
||||
n_rows, n_cols, density=density, format='coo', random_state=rng,
|
||||
)
|
||||
|
||||
# Collect the test matrices
|
||||
test_matrices = [
|
||||
A_dense, A_csc, A_csr, A_coo,
|
||||
]
|
||||
|
||||
# Test vector with norm ~1
|
||||
x = rng.randn(n_rows, 1) / np.sqrt(n_rows)
|
||||
|
||||
def test_sketch_dimensions(self):
|
||||
for A in self.test_matrices:
|
||||
for seed in self.seeds:
|
||||
sketch = clarkson_woodruff_transform(
|
||||
A, self.n_sketch_rows, seed=seed
|
||||
)
|
||||
assert_(sketch.shape == (self.n_sketch_rows, self.n_cols))
|
||||
|
||||
def test_seed_returns_identical_transform_matrix(self):
|
||||
for A in self.test_matrices:
|
||||
for seed in self.seeds:
|
||||
S1 = cwt_matrix(
|
||||
self.n_sketch_rows, self.n_rows, seed=seed
|
||||
).toarray()
|
||||
S2 = cwt_matrix(
|
||||
self.n_sketch_rows, self.n_rows, seed=seed
|
||||
).toarray()
|
||||
assert_equal(S1, S2)
|
||||
|
||||
def test_seed_returns_identically(self):
|
||||
for A in self.test_matrices:
|
||||
for seed in self.seeds:
|
||||
sketch1 = clarkson_woodruff_transform(
|
||||
A, self.n_sketch_rows, seed=seed
|
||||
)
|
||||
sketch2 = clarkson_woodruff_transform(
|
||||
A, self.n_sketch_rows, seed=seed
|
||||
)
|
||||
if issparse(sketch1):
|
||||
sketch1 = sketch1.toarray()
|
||||
if issparse(sketch2):
|
||||
sketch2 = sketch2.toarray()
|
||||
assert_equal(sketch1, sketch2)
|
||||
|
||||
def test_sketch_preserves_frobenius_norm(self):
|
||||
# Given the probabilistic nature of the sketches
|
||||
# we run the test multiple times and check that
|
||||
# we pass all/almost all the tries.
|
||||
n_errors = 0
|
||||
for A in self.test_matrices:
|
||||
if issparse(A):
|
||||
true_norm = norm(A)
|
||||
else:
|
||||
true_norm = np.linalg.norm(A)
|
||||
for seed in self.seeds:
|
||||
sketch = clarkson_woodruff_transform(
|
||||
A, self.n_sketch_rows, seed=seed,
|
||||
)
|
||||
if issparse(sketch):
|
||||
sketch_norm = norm(sketch)
|
||||
else:
|
||||
sketch_norm = np.linalg.norm(sketch)
|
||||
|
||||
if np.abs(true_norm - sketch_norm) > 0.1 * true_norm:
|
||||
n_errors += 1
|
||||
assert_(n_errors == 0)
|
||||
|
||||
def test_sketch_preserves_vector_norm(self):
|
||||
n_errors = 0
|
||||
n_sketch_rows = int(np.ceil(2. / (0.01 * 0.5**2)))
|
||||
true_norm = np.linalg.norm(self.x)
|
||||
for seed in self.seeds:
|
||||
sketch = clarkson_woodruff_transform(
|
||||
self.x, n_sketch_rows, seed=seed,
|
||||
)
|
||||
sketch_norm = np.linalg.norm(sketch)
|
||||
|
||||
if np.abs(true_norm - sketch_norm) > 0.5 * true_norm:
|
||||
n_errors += 1
|
||||
assert_(n_errors == 0)
|
||||
121
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_solve_toeplitz.py
vendored
Normal file
121
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_solve_toeplitz.py
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
"""Test functions for linalg._solve_toeplitz module
|
||||
"""
|
||||
import numpy as np
|
||||
from scipy.linalg._solve_toeplitz import levinson
|
||||
from scipy.linalg import solve, toeplitz, solve_toeplitz
|
||||
from numpy.testing import assert_equal, assert_allclose
|
||||
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
|
||||
def test_solve_equivalence():
|
||||
# For toeplitz matrices, solve_toeplitz() should be equivalent to solve().
|
||||
random = np.random.RandomState(1234)
|
||||
for n in (1, 2, 3, 10):
|
||||
c = random.randn(n)
|
||||
if random.rand() < 0.5:
|
||||
c = c + 1j * random.randn(n)
|
||||
r = random.randn(n)
|
||||
if random.rand() < 0.5:
|
||||
r = r + 1j * random.randn(n)
|
||||
y = random.randn(n)
|
||||
if random.rand() < 0.5:
|
||||
y = y + 1j * random.randn(n)
|
||||
|
||||
# Check equivalence when both the column and row are provided.
|
||||
actual = solve_toeplitz((c,r), y)
|
||||
desired = solve(toeplitz(c, r=r), y)
|
||||
assert_allclose(actual, desired)
|
||||
|
||||
# Check equivalence when the column is provided but not the row.
|
||||
actual = solve_toeplitz(c, b=y)
|
||||
desired = solve(toeplitz(c), y)
|
||||
assert_allclose(actual, desired)
|
||||
|
||||
|
||||
def test_multiple_rhs():
|
||||
random = np.random.RandomState(1234)
|
||||
c = random.randn(4)
|
||||
r = random.randn(4)
|
||||
for offset in [0, 1j]:
|
||||
for yshape in ((4,), (4, 3), (4, 3, 2)):
|
||||
y = random.randn(*yshape) + offset
|
||||
actual = solve_toeplitz((c,r), b=y)
|
||||
desired = solve(toeplitz(c, r=r), y)
|
||||
assert_equal(actual.shape, yshape)
|
||||
assert_equal(desired.shape, yshape)
|
||||
assert_allclose(actual, desired)
|
||||
|
||||
|
||||
def test_native_list_arguments():
|
||||
c = [1,2,4,7]
|
||||
r = [1,3,9,12]
|
||||
y = [5,1,4,2]
|
||||
actual = solve_toeplitz((c,r), y)
|
||||
desired = solve(toeplitz(c, r=r), y)
|
||||
assert_allclose(actual, desired)
|
||||
|
||||
|
||||
def test_zero_diag_error():
|
||||
# The Levinson-Durbin implementation fails when the diagonal is zero.
|
||||
random = np.random.RandomState(1234)
|
||||
n = 4
|
||||
c = random.randn(n)
|
||||
r = random.randn(n)
|
||||
y = random.randn(n)
|
||||
c[0] = 0
|
||||
assert_raises(np.linalg.LinAlgError,
|
||||
solve_toeplitz, (c, r), b=y)
|
||||
|
||||
|
||||
def test_wikipedia_counterexample():
|
||||
# The Levinson-Durbin implementation also fails in other cases.
|
||||
# This example is from the talk page of the wikipedia article.
|
||||
random = np.random.RandomState(1234)
|
||||
c = [2, 2, 1]
|
||||
y = random.randn(3)
|
||||
assert_raises(np.linalg.LinAlgError, solve_toeplitz, c, b=y)
|
||||
|
||||
|
||||
def test_reflection_coeffs():
|
||||
# check that the partial solutions are given by the reflection
|
||||
# coefficients
|
||||
|
||||
random = np.random.RandomState(1234)
|
||||
y_d = random.randn(10)
|
||||
y_z = random.randn(10) + 1j
|
||||
reflection_coeffs_d = [1]
|
||||
reflection_coeffs_z = [1]
|
||||
for i in range(2, 10):
|
||||
reflection_coeffs_d.append(solve_toeplitz(y_d[:(i-1)], b=y_d[1:i])[-1])
|
||||
reflection_coeffs_z.append(solve_toeplitz(y_z[:(i-1)], b=y_z[1:i])[-1])
|
||||
|
||||
y_d_concat = np.concatenate((y_d[-2:0:-1], y_d[:-1]))
|
||||
y_z_concat = np.concatenate((y_z[-2:0:-1].conj(), y_z[:-1]))
|
||||
_, ref_d = levinson(y_d_concat, b=y_d[1:])
|
||||
_, ref_z = levinson(y_z_concat, b=y_z[1:])
|
||||
|
||||
assert_allclose(reflection_coeffs_d, ref_d[:-1])
|
||||
assert_allclose(reflection_coeffs_z, ref_z[:-1])
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason='Instability of Levinson iteration')
|
||||
def test_unstable():
|
||||
# this is a "Gaussian Toeplitz matrix", as mentioned in Example 2 of
|
||||
# I. Gohbert, T. Kailath and V. Olshevsky "Fast Gaussian Elimination with
|
||||
# Partial Pivoting for Matrices with Displacement Structure"
|
||||
# Mathematics of Computation, 64, 212 (1995), pp 1557-1576
|
||||
# which can be unstable for levinson recursion.
|
||||
|
||||
# other fast toeplitz solvers such as GKO or Burg should be better.
|
||||
random = np.random.RandomState(1234)
|
||||
n = 100
|
||||
c = 0.9 ** (np.arange(n)**2)
|
||||
y = random.randn(n)
|
||||
|
||||
solution1 = solve_toeplitz(c, b=y)
|
||||
solution2 = solve(toeplitz(c), y)
|
||||
|
||||
assert_allclose(solution1, solution2)
|
||||
|
||||
766
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_solvers.py
vendored
Normal file
766
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_solvers.py
vendored
Normal file
@@ -0,0 +1,766 @@
|
||||
import os
|
||||
import numpy as np
|
||||
|
||||
from numpy.testing import assert_array_almost_equal
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from scipy.linalg import solve_sylvester
|
||||
from scipy.linalg import solve_continuous_lyapunov, solve_discrete_lyapunov
|
||||
from scipy.linalg import solve_continuous_are, solve_discrete_are
|
||||
from scipy.linalg import block_diag, solve, LinAlgError
|
||||
from scipy.sparse._sputils import matrix
|
||||
|
||||
|
||||
def _load_data(name):
|
||||
"""
|
||||
Load npz data file under data/
|
||||
Returns a copy of the data, rather than keeping the npz file open.
|
||||
"""
|
||||
filename = os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||
'data', name)
|
||||
with np.load(filename) as f:
|
||||
return dict(f.items())
|
||||
|
||||
|
||||
class TestSolveLyapunov:
|
||||
|
||||
cases = [
|
||||
(np.array([[1, 2], [3, 4]]),
|
||||
np.array([[9, 10], [11, 12]])),
|
||||
# a, q all complex.
|
||||
(np.array([[1.0+1j, 2.0], [3.0-4.0j, 5.0]]),
|
||||
np.array([[2.0-2j, 2.0+2j], [-1.0-1j, 2.0]])),
|
||||
# a real; q complex.
|
||||
(np.array([[1.0, 2.0], [3.0, 5.0]]),
|
||||
np.array([[2.0-2j, 2.0+2j], [-1.0-1j, 2.0]])),
|
||||
# a complex; q real.
|
||||
(np.array([[1.0+1j, 2.0], [3.0-4.0j, 5.0]]),
|
||||
np.array([[2.0, 2.0], [-1.0, 2.0]])),
|
||||
# An example from Kitagawa, 1977
|
||||
(np.array([[3, 9, 5, 1, 4], [1, 2, 3, 8, 4], [4, 6, 6, 6, 3],
|
||||
[1, 5, 2, 0, 7], [5, 3, 3, 1, 5]]),
|
||||
np.array([[2, 4, 1, 0, 1], [4, 1, 0, 2, 0], [1, 0, 3, 0, 3],
|
||||
[0, 2, 0, 1, 0], [1, 0, 3, 0, 4]])),
|
||||
# Companion matrix example. a complex; q real; a.shape[0] = 11
|
||||
(np.array([[0.100+0.j, 0.091+0.j, 0.082+0.j, 0.073+0.j, 0.064+0.j,
|
||||
0.055+0.j, 0.046+0.j, 0.037+0.j, 0.028+0.j, 0.019+0.j,
|
||||
0.010+0.j],
|
||||
[1.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 1.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 1.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 1.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 1.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
1.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 1.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 1.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 1.000+0.j, 0.000+0.j,
|
||||
0.000+0.j],
|
||||
[0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j,
|
||||
0.000+0.j, 0.000+0.j, 0.000+0.j, 0.000+0.j, 1.000+0.j,
|
||||
0.000+0.j]]),
|
||||
np.eye(11)),
|
||||
# https://github.com/scipy/scipy/issues/4176
|
||||
(matrix([[0, 1], [-1/2, -1]]),
|
||||
(matrix([0, 3]).T @ matrix([0, 3]).T.T)),
|
||||
# https://github.com/scipy/scipy/issues/4176
|
||||
(matrix([[0, 1], [-1/2, -1]]),
|
||||
(np.array(matrix([0, 3]).T @ matrix([0, 3]).T.T))),
|
||||
]
|
||||
|
||||
def test_continuous_squareness_and_shape(self):
|
||||
nsq = np.ones((3, 2))
|
||||
sq = np.eye(3)
|
||||
assert_raises(ValueError, solve_continuous_lyapunov, nsq, sq)
|
||||
assert_raises(ValueError, solve_continuous_lyapunov, sq, nsq)
|
||||
assert_raises(ValueError, solve_continuous_lyapunov, sq, np.eye(2))
|
||||
|
||||
def check_continuous_case(self, a, q):
|
||||
x = solve_continuous_lyapunov(a, q)
|
||||
assert_array_almost_equal(
|
||||
np.dot(a, x) + np.dot(x, a.conj().transpose()), q)
|
||||
|
||||
def check_discrete_case(self, a, q, method=None):
|
||||
x = solve_discrete_lyapunov(a, q, method=method)
|
||||
assert_array_almost_equal(
|
||||
np.dot(np.dot(a, x), a.conj().transpose()) - x, -1.0*q)
|
||||
|
||||
def test_cases(self):
|
||||
for case in self.cases:
|
||||
self.check_continuous_case(case[0], case[1])
|
||||
self.check_discrete_case(case[0], case[1])
|
||||
self.check_discrete_case(case[0], case[1], method='direct')
|
||||
self.check_discrete_case(case[0], case[1], method='bilinear')
|
||||
|
||||
|
||||
def test_solve_continuous_are():
|
||||
mat6 = _load_data('carex_6_data.npz')
|
||||
mat15 = _load_data('carex_15_data.npz')
|
||||
mat18 = _load_data('carex_18_data.npz')
|
||||
mat19 = _load_data('carex_19_data.npz')
|
||||
mat20 = _load_data('carex_20_data.npz')
|
||||
cases = [
|
||||
# Carex examples taken from (with default parameters):
|
||||
# [1] P.BENNER, A.J. LAUB, V. MEHRMANN: 'A Collection of Benchmark
|
||||
# Examples for the Numerical Solution of Algebraic Riccati
|
||||
# Equations II: Continuous-Time Case', Tech. Report SPC 95_23,
|
||||
# Fak. f. Mathematik, TU Chemnitz-Zwickau (Germany), 1995.
|
||||
#
|
||||
# The format of the data is (a, b, q, r, knownfailure), where
|
||||
# knownfailure is None if the test passes or a string
|
||||
# indicating the reason for failure.
|
||||
#
|
||||
# Test Case 0: carex #1
|
||||
(np.diag([1.], 1),
|
||||
np.array([[0], [1]]),
|
||||
block_diag(1., 2.),
|
||||
1,
|
||||
None),
|
||||
# Test Case 1: carex #2
|
||||
(np.array([[4, 3], [-4.5, -3.5]]),
|
||||
np.array([[1], [-1]]),
|
||||
np.array([[9, 6], [6, 4.]]),
|
||||
1,
|
||||
None),
|
||||
# Test Case 2: carex #3
|
||||
(np.array([[0, 1, 0, 0],
|
||||
[0, -1.89, 0.39, -5.53],
|
||||
[0, -0.034, -2.98, 2.43],
|
||||
[0.034, -0.0011, -0.99, -0.21]]),
|
||||
np.array([[0, 0], [0.36, -1.6], [-0.95, -0.032], [0.03, 0]]),
|
||||
np.array([[2.313, 2.727, 0.688, 0.023],
|
||||
[2.727, 4.271, 1.148, 0.323],
|
||||
[0.688, 1.148, 0.313, 0.102],
|
||||
[0.023, 0.323, 0.102, 0.083]]),
|
||||
np.eye(2),
|
||||
None),
|
||||
# Test Case 3: carex #4
|
||||
(np.array([[-0.991, 0.529, 0, 0, 0, 0, 0, 0],
|
||||
[0.522, -1.051, 0.596, 0, 0, 0, 0, 0],
|
||||
[0, 0.522, -1.118, 0.596, 0, 0, 0, 0],
|
||||
[0, 0, 0.522, -1.548, 0.718, 0, 0, 0],
|
||||
[0, 0, 0, 0.922, -1.64, 0.799, 0, 0],
|
||||
[0, 0, 0, 0, 0.922, -1.721, 0.901, 0],
|
||||
[0, 0, 0, 0, 0, 0.922, -1.823, 1.021],
|
||||
[0, 0, 0, 0, 0, 0, 0.922, -1.943]]),
|
||||
np.array([[3.84, 4.00, 37.60, 3.08, 2.36, 2.88, 3.08, 3.00],
|
||||
[-2.88, -3.04, -2.80, -2.32, -3.32, -3.82, -4.12, -3.96]]
|
||||
).T * 0.001,
|
||||
np.array([[1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.1],
|
||||
[0.0, 1.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0],
|
||||
[0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 0.0],
|
||||
[0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
|
||||
[0.5, 0.1, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0],
|
||||
[0.0, 0.0, 0.5, 0.0, 0.0, 0.1, 0.0, 0.0],
|
||||
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0],
|
||||
[0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]]),
|
||||
np.eye(2),
|
||||
None),
|
||||
# Test Case 4: carex #5
|
||||
(np.array(
|
||||
[[-4.019, 5.120, 0., 0., -2.082, 0., 0., 0., 0.870],
|
||||
[-0.346, 0.986, 0., 0., -2.340, 0., 0., 0., 0.970],
|
||||
[-7.909, 15.407, -4.069, 0., -6.450, 0., 0., 0., 2.680],
|
||||
[-21.816, 35.606, -0.339, -3.870, -17.800, 0., 0., 0., 7.390],
|
||||
[-60.196, 98.188, -7.907, 0.340, -53.008, 0., 0., 0., 20.400],
|
||||
[0, 0, 0, 0, 94.000, -147.200, 0., 53.200, 0.],
|
||||
[0, 0, 0, 0, 0, 94.000, -147.200, 0, 0],
|
||||
[0, 0, 0, 0, 0, 12.800, 0.000, -31.600, 0],
|
||||
[0, 0, 0, 0, 12.800, 0.000, 0.000, 18.800, -31.600]]),
|
||||
np.array([[0.010, -0.011, -0.151],
|
||||
[0.003, -0.021, 0.000],
|
||||
[0.009, -0.059, 0.000],
|
||||
[0.024, -0.162, 0.000],
|
||||
[0.068, -0.445, 0.000],
|
||||
[0.000, 0.000, 0.000],
|
||||
[0.000, 0.000, 0.000],
|
||||
[0.000, 0.000, 0.000],
|
||||
[0.000, 0.000, 0.000]]),
|
||||
np.eye(9),
|
||||
np.eye(3),
|
||||
None),
|
||||
# Test Case 5: carex #6
|
||||
(mat6['A'], mat6['B'], mat6['Q'], mat6['R'], None),
|
||||
# Test Case 6: carex #7
|
||||
(np.array([[1, 0], [0, -2.]]),
|
||||
np.array([[1e-6], [0]]),
|
||||
np.ones((2, 2)),
|
||||
1.,
|
||||
'Bad residual accuracy'),
|
||||
# Test Case 7: carex #8
|
||||
(block_diag(-0.1, -0.02),
|
||||
np.array([[0.100, 0.000], [0.001, 0.010]]),
|
||||
np.array([[100, 1000], [1000, 10000]]),
|
||||
np.ones((2, 2)) + block_diag(1e-6, 0),
|
||||
None),
|
||||
# Test Case 8: carex #9
|
||||
(np.array([[0, 1e6], [0, 0]]),
|
||||
np.array([[0], [1.]]),
|
||||
np.eye(2),
|
||||
1.,
|
||||
None),
|
||||
# Test Case 9: carex #10
|
||||
(np.array([[1.0000001, 1], [1., 1.0000001]]),
|
||||
np.eye(2),
|
||||
np.eye(2),
|
||||
np.eye(2),
|
||||
None),
|
||||
# Test Case 10: carex #11
|
||||
(np.array([[3, 1.], [4, 2]]),
|
||||
np.array([[1], [1]]),
|
||||
np.array([[-11, -5], [-5, -2.]]),
|
||||
1.,
|
||||
None),
|
||||
# Test Case 11: carex #12
|
||||
(np.array([[7000000., 2000000., -0.],
|
||||
[2000000., 6000000., -2000000.],
|
||||
[0., -2000000., 5000000.]]) / 3,
|
||||
np.eye(3),
|
||||
np.array([[1., -2., -2.], [-2., 1., -2.], [-2., -2., 1.]]).dot(
|
||||
np.diag([1e-6, 1, 1e6])).dot(
|
||||
np.array([[1., -2., -2.], [-2., 1., -2.], [-2., -2., 1.]])) / 9,
|
||||
np.eye(3) * 1e6,
|
||||
'Bad Residual Accuracy'),
|
||||
# Test Case 12: carex #13
|
||||
(np.array([[0, 0.4, 0, 0],
|
||||
[0, 0, 0.345, 0],
|
||||
[0, -0.524e6, -0.465e6, 0.262e6],
|
||||
[0, 0, 0, -1e6]]),
|
||||
np.array([[0, 0, 0, 1e6]]).T,
|
||||
np.diag([1, 0, 1, 0]),
|
||||
1.,
|
||||
None),
|
||||
# Test Case 13: carex #14
|
||||
(np.array([[-1e-6, 1, 0, 0],
|
||||
[-1, -1e-6, 0, 0],
|
||||
[0, 0, 1e-6, 1],
|
||||
[0, 0, -1, 1e-6]]),
|
||||
np.ones((4, 1)),
|
||||
np.ones((4, 4)),
|
||||
1.,
|
||||
None),
|
||||
# Test Case 14: carex #15
|
||||
(mat15['A'], mat15['B'], mat15['Q'], mat15['R'], None),
|
||||
# Test Case 15: carex #16
|
||||
(np.eye(64, 64, k=-1) + np.eye(64, 64)*(-2.) + np.rot90(
|
||||
block_diag(1, np.zeros((62, 62)), 1)) + np.eye(64, 64, k=1),
|
||||
np.eye(64),
|
||||
np.eye(64),
|
||||
np.eye(64),
|
||||
None),
|
||||
# Test Case 16: carex #17
|
||||
(np.diag(np.ones((20, )), 1),
|
||||
np.flipud(np.eye(21, 1)),
|
||||
np.eye(21, 1) * np.eye(21, 1).T,
|
||||
1,
|
||||
'Bad Residual Accuracy'),
|
||||
# Test Case 17: carex #18
|
||||
(mat18['A'], mat18['B'], mat18['Q'], mat18['R'], None),
|
||||
# Test Case 18: carex #19
|
||||
(mat19['A'], mat19['B'], mat19['Q'], mat19['R'],
|
||||
'Bad Residual Accuracy'),
|
||||
# Test Case 19: carex #20
|
||||
(mat20['A'], mat20['B'], mat20['Q'], mat20['R'],
|
||||
'Bad Residual Accuracy')
|
||||
]
|
||||
# Makes the minimum precision requirements customized to the test.
|
||||
# Here numbers represent the number of decimals that agrees with zero
|
||||
# matrix when the solution x is plugged in to the equation.
|
||||
#
|
||||
# res = array([[8e-3,1e-16],[1e-16,1e-20]]) --> min_decimal[k] = 2
|
||||
#
|
||||
# If the test is failing use "None" for that entry.
|
||||
#
|
||||
min_decimal = (14, 12, 13, 14, 11, 6, None, 5, 7, 14, 14,
|
||||
None, 9, 14, 13, 14, None, 12, None, None)
|
||||
|
||||
def _test_factory(case, dec):
|
||||
"""Checks if 0 = XA + A'X - XB(R)^{-1} B'X + Q is true"""
|
||||
a, b, q, r, knownfailure = case
|
||||
if knownfailure:
|
||||
pytest.xfail(reason=knownfailure)
|
||||
|
||||
x = solve_continuous_are(a, b, q, r)
|
||||
res = x.dot(a) + a.conj().T.dot(x) + q
|
||||
out_fact = x.dot(b)
|
||||
res -= out_fact.dot(solve(np.atleast_2d(r), out_fact.conj().T))
|
||||
assert_array_almost_equal(res, np.zeros_like(res), decimal=dec)
|
||||
|
||||
for ind, case in enumerate(cases):
|
||||
_test_factory(case, min_decimal[ind])
|
||||
|
||||
|
||||
def test_solve_discrete_are():
|
||||
|
||||
cases = [
|
||||
# Darex examples taken from (with default parameters):
|
||||
# [1] P.BENNER, A.J. LAUB, V. MEHRMANN: 'A Collection of Benchmark
|
||||
# Examples for the Numerical Solution of Algebraic Riccati
|
||||
# Equations II: Discrete-Time Case', Tech. Report SPC 95_23,
|
||||
# Fak. f. Mathematik, TU Chemnitz-Zwickau (Germany), 1995.
|
||||
# [2] T. GUDMUNDSSON, C. KENNEY, A.J. LAUB: 'Scaling of the
|
||||
# Discrete-Time Algebraic Riccati Equation to Enhance Stability
|
||||
# of the Schur Solution Method', IEEE Trans.Aut.Cont., vol.37(4)
|
||||
#
|
||||
# The format of the data is (a, b, q, r, knownfailure), where
|
||||
# knownfailure is None if the test passes or a string
|
||||
# indicating the reason for failure.
|
||||
#
|
||||
# TEST CASE 0 : Complex a; real b, q, r
|
||||
(np.array([[2, 1-2j], [0, -3j]]),
|
||||
np.array([[0], [1]]),
|
||||
np.array([[1, 0], [0, 2]]),
|
||||
np.array([[1]]),
|
||||
None),
|
||||
# TEST CASE 1 :Real a, q, r; complex b
|
||||
(np.array([[2, 1], [0, -1]]),
|
||||
np.array([[-2j], [1j]]),
|
||||
np.array([[1, 0], [0, 2]]),
|
||||
np.array([[1]]),
|
||||
None),
|
||||
# TEST CASE 2 : Real a, b; complex q, r
|
||||
(np.array([[3, 1], [0, -1]]),
|
||||
np.array([[1, 2], [1, 3]]),
|
||||
np.array([[1, 1+1j], [1-1j, 2]]),
|
||||
np.array([[2, -2j], [2j, 3]]),
|
||||
None),
|
||||
# TEST CASE 3 : User-reported gh-2251 (Trac #1732)
|
||||
(np.array([[0.63399379, 0.54906824, 0.76253406],
|
||||
[0.5404729, 0.53745766, 0.08731853],
|
||||
[0.27524045, 0.84922129, 0.4681622]]),
|
||||
np.array([[0.96861695], [0.05532739], [0.78934047]]),
|
||||
np.eye(3),
|
||||
np.eye(1),
|
||||
None),
|
||||
# TEST CASE 4 : darex #1
|
||||
(np.array([[4, 3], [-4.5, -3.5]]),
|
||||
np.array([[1], [-1]]),
|
||||
np.array([[9, 6], [6, 4]]),
|
||||
np.array([[1]]),
|
||||
None),
|
||||
# TEST CASE 5 : darex #2
|
||||
(np.array([[0.9512, 0], [0, 0.9048]]),
|
||||
np.array([[4.877, 4.877], [-1.1895, 3.569]]),
|
||||
np.array([[0.005, 0], [0, 0.02]]),
|
||||
np.array([[1/3, 0], [0, 3]]),
|
||||
None),
|
||||
# TEST CASE 6 : darex #3
|
||||
(np.array([[2, -1], [1, 0]]),
|
||||
np.array([[1], [0]]),
|
||||
np.array([[0, 0], [0, 1]]),
|
||||
np.array([[0]]),
|
||||
None),
|
||||
# TEST CASE 7 : darex #4 (skipped the gen. Ric. term S)
|
||||
(np.array([[0, 1], [0, -1]]),
|
||||
np.array([[1, 0], [2, 1]]),
|
||||
np.array([[-4, -4], [-4, 7]]) * (1/11),
|
||||
np.array([[9, 3], [3, 1]]),
|
||||
None),
|
||||
# TEST CASE 8 : darex #5
|
||||
(np.array([[0, 1], [0, 0]]),
|
||||
np.array([[0], [1]]),
|
||||
np.array([[1, 2], [2, 4]]),
|
||||
np.array([[1]]),
|
||||
None),
|
||||
# TEST CASE 9 : darex #6
|
||||
(np.array([[0.998, 0.067, 0, 0],
|
||||
[-.067, 0.998, 0, 0],
|
||||
[0, 0, 0.998, 0.153],
|
||||
[0, 0, -.153, 0.998]]),
|
||||
np.array([[0.0033, 0.0200],
|
||||
[0.1000, -.0007],
|
||||
[0.0400, 0.0073],
|
||||
[-.0028, 0.1000]]),
|
||||
np.array([[1.87, 0, 0, -0.244],
|
||||
[0, 0.744, 0.205, 0],
|
||||
[0, 0.205, 0.589, 0],
|
||||
[-0.244, 0, 0, 1.048]]),
|
||||
np.eye(2),
|
||||
None),
|
||||
# TEST CASE 10 : darex #7
|
||||
(np.array([[0.984750, -.079903, 0.0009054, -.0010765],
|
||||
[0.041588, 0.998990, -.0358550, 0.0126840],
|
||||
[-.546620, 0.044916, -.3299100, 0.1931800],
|
||||
[2.662400, -.100450, -.9245500, -.2632500]]),
|
||||
np.array([[0.0037112, 0.0007361],
|
||||
[-.0870510, 9.3411e-6],
|
||||
[-1.198440, -4.1378e-4],
|
||||
[-3.192700, 9.2535e-4]]),
|
||||
np.eye(4)*1e-2,
|
||||
np.eye(2),
|
||||
None),
|
||||
# TEST CASE 11 : darex #8
|
||||
(np.array([[-0.6000000, -2.2000000, -3.6000000, -5.4000180],
|
||||
[1.0000000, 0.6000000, 0.8000000, 3.3999820],
|
||||
[0.0000000, 1.0000000, 1.8000000, 3.7999820],
|
||||
[0.0000000, 0.0000000, 0.0000000, -0.9999820]]),
|
||||
np.array([[1.0, -1.0, -1.0, -1.0],
|
||||
[0.0, 1.0, -1.0, -1.0],
|
||||
[0.0, 0.0, 1.0, -1.0],
|
||||
[0.0, 0.0, 0.0, 1.0]]),
|
||||
np.array([[2, 1, 3, 6],
|
||||
[1, 2, 2, 5],
|
||||
[3, 2, 6, 11],
|
||||
[6, 5, 11, 22]]),
|
||||
np.eye(4),
|
||||
None),
|
||||
# TEST CASE 12 : darex #9
|
||||
(np.array([[95.4070, 1.9643, 0.3597, 0.0673, 0.0190],
|
||||
[40.8490, 41.3170, 16.0840, 4.4679, 1.1971],
|
||||
[12.2170, 26.3260, 36.1490, 15.9300, 12.3830],
|
||||
[4.1118, 12.8580, 27.2090, 21.4420, 40.9760],
|
||||
[0.1305, 0.5808, 1.8750, 3.6162, 94.2800]]) * 0.01,
|
||||
np.array([[0.0434, -0.0122],
|
||||
[2.6606, -1.0453],
|
||||
[3.7530, -5.5100],
|
||||
[3.6076, -6.6000],
|
||||
[0.4617, -0.9148]]) * 0.01,
|
||||
np.eye(5),
|
||||
np.eye(2),
|
||||
None),
|
||||
# TEST CASE 13 : darex #10
|
||||
(np.kron(np.eye(2), np.diag([1, 1], k=1)),
|
||||
np.kron(np.eye(2), np.array([[0], [0], [1]])),
|
||||
np.array([[1, 1, 0, 0, 0, 0],
|
||||
[1, 1, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 1, -1, 0],
|
||||
[0, 0, 0, -1, 1, 0],
|
||||
[0, 0, 0, 0, 0, 0]]),
|
||||
np.array([[3, 0], [0, 1]]),
|
||||
None),
|
||||
# TEST CASE 14 : darex #11
|
||||
(0.001 * np.array(
|
||||
[[870.1, 135.0, 11.59, .5014, -37.22, .3484, 0, 4.242, 7.249],
|
||||
[76.55, 897.4, 12.72, 0.5504, -40.16, .3743, 0, 4.53, 7.499],
|
||||
[-127.2, 357.5, 817, 1.455, -102.8, .987, 0, 11.85, 18.72],
|
||||
[-363.5, 633.9, 74.91, 796.6, -273.5, 2.653, 0, 31.72, 48.82],
|
||||
[-960, 1645.9, -128.9, -5.597, 71.42, 7.108, 0, 84.52, 125.9],
|
||||
[-664.4, 112.96, -88.89, -3.854, 84.47, 13.6, 0, 144.3, 101.6],
|
||||
[-410.2, 693, -54.71, -2.371, 66.49, 12.49, .1063, 99.97, 69.67],
|
||||
[-179.9, 301.7, -23.93, -1.035, 60.59, 22.16, 0, 213.9, 35.54],
|
||||
[-345.1, 580.4, -45.96, -1.989, 105.6, 19.86, 0, 219.1, 215.2]]),
|
||||
np.array([[4.7600, -0.5701, -83.6800],
|
||||
[0.8790, -4.7730, -2.7300],
|
||||
[1.4820, -13.1200, 8.8760],
|
||||
[3.8920, -35.1300, 24.8000],
|
||||
[10.3400, -92.7500, 66.8000],
|
||||
[7.2030, -61.5900, 38.3400],
|
||||
[4.4540, -36.8300, 20.2900],
|
||||
[1.9710, -15.5400, 6.9370],
|
||||
[3.7730, -30.2800, 14.6900]]) * 0.001,
|
||||
np.diag([50, 0, 0, 0, 50, 0, 0, 0, 0]),
|
||||
np.eye(3),
|
||||
None),
|
||||
# TEST CASE 15 : darex #12 - numerically least accurate example
|
||||
(np.array([[0, 1e6], [0, 0]]),
|
||||
np.array([[0], [1]]),
|
||||
np.eye(2),
|
||||
np.array([[1]]),
|
||||
"Presumed issue with OpenBLAS, see gh-16926"),
|
||||
# TEST CASE 16 : darex #13
|
||||
(np.array([[16, 10, -2],
|
||||
[10, 13, -8],
|
||||
[-2, -8, 7]]) * (1/9),
|
||||
np.eye(3),
|
||||
1e6 * np.eye(3),
|
||||
1e6 * np.eye(3),
|
||||
"Issue with OpenBLAS, see gh-16926"),
|
||||
# TEST CASE 17 : darex #14
|
||||
(np.array([[1 - 1/1e8, 0, 0, 0],
|
||||
[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0]]),
|
||||
np.array([[1e-08], [0], [0], [0]]),
|
||||
np.diag([0, 0, 0, 1]),
|
||||
np.array([[0.25]]),
|
||||
None),
|
||||
# TEST CASE 18 : darex #15
|
||||
(np.eye(100, k=1),
|
||||
np.flipud(np.eye(100, 1)),
|
||||
np.eye(100),
|
||||
np.array([[1]]),
|
||||
None)
|
||||
]
|
||||
|
||||
# Makes the minimum precision requirements customized to the test.
|
||||
# Here numbers represent the number of decimals that agrees with zero
|
||||
# matrix when the solution x is plugged in to the equation.
|
||||
#
|
||||
# res = array([[8e-3,1e-16],[1e-16,1e-20]]) --> min_decimal[k] = 2
|
||||
#
|
||||
# If the test is failing use "None" for that entry.
|
||||
#
|
||||
min_decimal = (12, 14, 13, 14, 13, 16, 18, 14, 14, 13,
|
||||
14, 13, 13, 14, 12, 2, 5, 6, 10)
|
||||
|
||||
def _test_factory(case, dec):
|
||||
"""Checks if X = A'XA-(A'XB)(R+B'XB)^-1(B'XA)+Q) is true"""
|
||||
a, b, q, r, knownfailure = case
|
||||
if knownfailure:
|
||||
pytest.xfail(reason=knownfailure)
|
||||
|
||||
x = solve_discrete_are(a, b, q, r)
|
||||
res = a.conj().T.dot(x.dot(a)) - x + q
|
||||
res -= a.conj().T.dot(x.dot(b)).dot(
|
||||
solve(r+b.conj().T.dot(x.dot(b)), b.conj().T).dot(x.dot(a))
|
||||
)
|
||||
assert_array_almost_equal(res, np.zeros_like(res), decimal=dec)
|
||||
|
||||
for ind, case in enumerate(cases):
|
||||
_test_factory(case, min_decimal[ind])
|
||||
|
||||
# An infeasible example taken from https://arxiv.org/abs/1505.04861v1
|
||||
A = np.triu(np.ones((3, 3)))
|
||||
A[0, 1] = -1
|
||||
B = np.array([[1, 1, 0], [0, 0, 1]]).T
|
||||
Q = np.full_like(A, -2) + np.diag([8, -1, -1.9])
|
||||
R = np.diag([-10, 0.1])
|
||||
assert_raises(LinAlgError, solve_continuous_are, A, B, Q, R)
|
||||
|
||||
|
||||
def test_solve_generalized_continuous_are():
|
||||
cases = [
|
||||
# Two random examples differ by s term
|
||||
# in the absence of any literature for demanding examples.
|
||||
(np.array([[2.769230e-01, 8.234578e-01, 9.502220e-01],
|
||||
[4.617139e-02, 6.948286e-01, 3.444608e-02],
|
||||
[9.713178e-02, 3.170995e-01, 4.387444e-01]]),
|
||||
np.array([[3.815585e-01, 1.868726e-01],
|
||||
[7.655168e-01, 4.897644e-01],
|
||||
[7.951999e-01, 4.455862e-01]]),
|
||||
np.eye(3),
|
||||
np.eye(2),
|
||||
np.array([[6.463130e-01, 2.760251e-01, 1.626117e-01],
|
||||
[7.093648e-01, 6.797027e-01, 1.189977e-01],
|
||||
[7.546867e-01, 6.550980e-01, 4.983641e-01]]),
|
||||
np.zeros((3, 2)),
|
||||
None),
|
||||
(np.array([[2.769230e-01, 8.234578e-01, 9.502220e-01],
|
||||
[4.617139e-02, 6.948286e-01, 3.444608e-02],
|
||||
[9.713178e-02, 3.170995e-01, 4.387444e-01]]),
|
||||
np.array([[3.815585e-01, 1.868726e-01],
|
||||
[7.655168e-01, 4.897644e-01],
|
||||
[7.951999e-01, 4.455862e-01]]),
|
||||
np.eye(3),
|
||||
np.eye(2),
|
||||
np.array([[6.463130e-01, 2.760251e-01, 1.626117e-01],
|
||||
[7.093648e-01, 6.797027e-01, 1.189977e-01],
|
||||
[7.546867e-01, 6.550980e-01, 4.983641e-01]]),
|
||||
np.ones((3, 2)),
|
||||
None)
|
||||
]
|
||||
|
||||
min_decimal = (10, 10)
|
||||
|
||||
def _test_factory(case, dec):
|
||||
"""Checks if X = A'XA-(A'XB)(R+B'XB)^-1(B'XA)+Q) is true"""
|
||||
a, b, q, r, e, s, knownfailure = case
|
||||
if knownfailure:
|
||||
pytest.xfail(reason=knownfailure)
|
||||
|
||||
x = solve_continuous_are(a, b, q, r, e, s)
|
||||
res = a.conj().T.dot(x.dot(e)) + e.conj().T.dot(x.dot(a)) + q
|
||||
out_fact = e.conj().T.dot(x).dot(b) + s
|
||||
res -= out_fact.dot(solve(np.atleast_2d(r), out_fact.conj().T))
|
||||
assert_array_almost_equal(res, np.zeros_like(res), decimal=dec)
|
||||
|
||||
for ind, case in enumerate(cases):
|
||||
_test_factory(case, min_decimal[ind])
|
||||
|
||||
|
||||
def test_solve_generalized_discrete_are():
|
||||
mat20170120 = _load_data('gendare_20170120_data.npz')
|
||||
|
||||
cases = [
|
||||
# Two random examples differ by s term
|
||||
# in the absence of any literature for demanding examples.
|
||||
(np.array([[2.769230e-01, 8.234578e-01, 9.502220e-01],
|
||||
[4.617139e-02, 6.948286e-01, 3.444608e-02],
|
||||
[9.713178e-02, 3.170995e-01, 4.387444e-01]]),
|
||||
np.array([[3.815585e-01, 1.868726e-01],
|
||||
[7.655168e-01, 4.897644e-01],
|
||||
[7.951999e-01, 4.455862e-01]]),
|
||||
np.eye(3),
|
||||
np.eye(2),
|
||||
np.array([[6.463130e-01, 2.760251e-01, 1.626117e-01],
|
||||
[7.093648e-01, 6.797027e-01, 1.189977e-01],
|
||||
[7.546867e-01, 6.550980e-01, 4.983641e-01]]),
|
||||
np.zeros((3, 2)),
|
||||
None),
|
||||
(np.array([[2.769230e-01, 8.234578e-01, 9.502220e-01],
|
||||
[4.617139e-02, 6.948286e-01, 3.444608e-02],
|
||||
[9.713178e-02, 3.170995e-01, 4.387444e-01]]),
|
||||
np.array([[3.815585e-01, 1.868726e-01],
|
||||
[7.655168e-01, 4.897644e-01],
|
||||
[7.951999e-01, 4.455862e-01]]),
|
||||
np.eye(3),
|
||||
np.eye(2),
|
||||
np.array([[6.463130e-01, 2.760251e-01, 1.626117e-01],
|
||||
[7.093648e-01, 6.797027e-01, 1.189977e-01],
|
||||
[7.546867e-01, 6.550980e-01, 4.983641e-01]]),
|
||||
np.ones((3, 2)),
|
||||
None),
|
||||
# user-reported (under PR-6616) 20-Jan-2017
|
||||
# tests against the case where E is None but S is provided
|
||||
(mat20170120['A'],
|
||||
mat20170120['B'],
|
||||
mat20170120['Q'],
|
||||
mat20170120['R'],
|
||||
None,
|
||||
mat20170120['S'],
|
||||
None),
|
||||
]
|
||||
|
||||
min_decimal = (11, 11, 16)
|
||||
|
||||
def _test_factory(case, dec):
|
||||
"""Checks if X = A'XA-(A'XB)(R+B'XB)^-1(B'XA)+Q) is true"""
|
||||
a, b, q, r, e, s, knownfailure = case
|
||||
if knownfailure:
|
||||
pytest.xfail(reason=knownfailure)
|
||||
|
||||
x = solve_discrete_are(a, b, q, r, e, s)
|
||||
if e is None:
|
||||
e = np.eye(a.shape[0])
|
||||
if s is None:
|
||||
s = np.zeros_like(b)
|
||||
res = a.conj().T.dot(x.dot(a)) - e.conj().T.dot(x.dot(e)) + q
|
||||
res -= (a.conj().T.dot(x.dot(b)) + s).dot(
|
||||
solve(r+b.conj().T.dot(x.dot(b)),
|
||||
(b.conj().T.dot(x.dot(a)) + s.conj().T)
|
||||
)
|
||||
)
|
||||
assert_array_almost_equal(res, np.zeros_like(res), decimal=dec)
|
||||
|
||||
for ind, case in enumerate(cases):
|
||||
_test_factory(case, min_decimal[ind])
|
||||
|
||||
|
||||
def test_are_validate_args():
|
||||
|
||||
def test_square_shape():
|
||||
nsq = np.ones((3, 2))
|
||||
sq = np.eye(3)
|
||||
for x in (solve_continuous_are, solve_discrete_are):
|
||||
assert_raises(ValueError, x, nsq, 1, 1, 1)
|
||||
assert_raises(ValueError, x, sq, sq, nsq, 1)
|
||||
assert_raises(ValueError, x, sq, sq, sq, nsq)
|
||||
assert_raises(ValueError, x, sq, sq, sq, sq, nsq)
|
||||
|
||||
def test_compatible_sizes():
|
||||
nsq = np.ones((3, 2))
|
||||
sq = np.eye(4)
|
||||
for x in (solve_continuous_are, solve_discrete_are):
|
||||
assert_raises(ValueError, x, sq, nsq, 1, 1)
|
||||
assert_raises(ValueError, x, sq, sq, sq, sq, sq, nsq)
|
||||
assert_raises(ValueError, x, sq, sq, np.eye(3), sq)
|
||||
assert_raises(ValueError, x, sq, sq, sq, np.eye(3))
|
||||
assert_raises(ValueError, x, sq, sq, sq, sq, np.eye(3))
|
||||
|
||||
def test_symmetry():
|
||||
nsym = np.arange(9).reshape(3, 3)
|
||||
sym = np.eye(3)
|
||||
for x in (solve_continuous_are, solve_discrete_are):
|
||||
assert_raises(ValueError, x, sym, sym, nsym, sym)
|
||||
assert_raises(ValueError, x, sym, sym, sym, nsym)
|
||||
|
||||
def test_singularity():
|
||||
sing = np.full((3, 3), 1e12)
|
||||
sing[2, 2] -= 1
|
||||
sq = np.eye(3)
|
||||
for x in (solve_continuous_are, solve_discrete_are):
|
||||
assert_raises(ValueError, x, sq, sq, sq, sq, sing)
|
||||
|
||||
assert_raises(ValueError, solve_continuous_are, sq, sq, sq, sing)
|
||||
|
||||
def test_finiteness():
|
||||
nm = np.full((2, 2), np.nan)
|
||||
sq = np.eye(2)
|
||||
for x in (solve_continuous_are, solve_discrete_are):
|
||||
assert_raises(ValueError, x, nm, sq, sq, sq)
|
||||
assert_raises(ValueError, x, sq, nm, sq, sq)
|
||||
assert_raises(ValueError, x, sq, sq, nm, sq)
|
||||
assert_raises(ValueError, x, sq, sq, sq, nm)
|
||||
assert_raises(ValueError, x, sq, sq, sq, sq, nm)
|
||||
assert_raises(ValueError, x, sq, sq, sq, sq, sq, nm)
|
||||
|
||||
|
||||
class TestSolveSylvester:
|
||||
|
||||
cases = [
|
||||
# a, b, c all real.
|
||||
(np.array([[1, 2], [0, 4]]),
|
||||
np.array([[5, 6], [0, 8]]),
|
||||
np.array([[9, 10], [11, 12]])),
|
||||
# a, b, c all real, 4x4. a and b have non-trival 2x2 blocks in their
|
||||
# quasi-triangular form.
|
||||
(np.array([[1.0, 0, 0, 0],
|
||||
[0, 1.0, 2.0, 0.0],
|
||||
[0, 0, 3.0, -4],
|
||||
[0, 0, 2, 5]]),
|
||||
np.array([[2.0, 0, 0, 1.0],
|
||||
[0, 1.0, 0.0, 0.0],
|
||||
[0, 0, 1.0, -1],
|
||||
[0, 0, 1, 1]]),
|
||||
np.array([[1.0, 0, 0, 0],
|
||||
[0, 1.0, 0, 0],
|
||||
[0, 0, 1.0, 0],
|
||||
[0, 0, 0, 1.0]])),
|
||||
# a, b, c all complex.
|
||||
(np.array([[1.0+1j, 2.0], [3.0-4.0j, 5.0]]),
|
||||
np.array([[-1.0, 2j], [3.0, 4.0]]),
|
||||
np.array([[2.0-2j, 2.0+2j], [-1.0-1j, 2.0]])),
|
||||
# a and b real; c complex.
|
||||
(np.array([[1.0, 2.0], [3.0, 5.0]]),
|
||||
np.array([[-1.0, 0], [3.0, 4.0]]),
|
||||
np.array([[2.0-2j, 2.0+2j], [-1.0-1j, 2.0]])),
|
||||
# a and c complex; b real.
|
||||
(np.array([[1.0+1j, 2.0], [3.0-4.0j, 5.0]]),
|
||||
np.array([[-1.0, 0], [3.0, 4.0]]),
|
||||
np.array([[2.0-2j, 2.0+2j], [-1.0-1j, 2.0]])),
|
||||
# a complex; b and c real.
|
||||
(np.array([[1.0+1j, 2.0], [3.0-4.0j, 5.0]]),
|
||||
np.array([[-1.0, 0], [3.0, 4.0]]),
|
||||
np.array([[2.0, 2.0], [-1.0, 2.0]])),
|
||||
# not square matrices, real
|
||||
(np.array([[8, 1, 6], [3, 5, 7], [4, 9, 2]]),
|
||||
np.array([[2, 3], [4, 5]]),
|
||||
np.array([[1, 2], [3, 4], [5, 6]])),
|
||||
# not square matrices, complex
|
||||
(np.array([[8, 1j, 6+2j], [3, 5, 7], [4, 9, 2]]),
|
||||
np.array([[2, 3], [4, 5-1j]]),
|
||||
np.array([[1, 2j], [3, 4j], [5j, 6+7j]])),
|
||||
]
|
||||
|
||||
def check_case(self, a, b, c):
|
||||
x = solve_sylvester(a, b, c)
|
||||
assert_array_almost_equal(np.dot(a, x) + np.dot(x, b), c)
|
||||
|
||||
def test_cases(self):
|
||||
for case in self.cases:
|
||||
self.check_case(case[0], case[1], case[2])
|
||||
|
||||
def test_trivial(self):
|
||||
a = np.array([[1.0, 0.0], [0.0, 1.0]])
|
||||
b = np.array([[1.0]])
|
||||
c = np.array([2.0, 2.0]).reshape(-1, 1)
|
||||
x = solve_sylvester(a, b, c)
|
||||
assert_array_almost_equal(x, np.array([1.0, 1.0]).reshape(-1, 1))
|
||||
690
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_special_matrices.py
vendored
Normal file
690
.CondaPkg/env/Lib/site-packages/scipy/linalg/tests/test_special_matrices.py
vendored
Normal file
@@ -0,0 +1,690 @@
|
||||
|
||||
import pytest
|
||||
import numpy as np
|
||||
from numpy import arange, add, array, eye, copy, sqrt
|
||||
from numpy.testing import (assert_equal, assert_array_equal,
|
||||
assert_array_almost_equal, assert_allclose)
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from scipy.fft import fft
|
||||
from scipy.special import comb
|
||||
from scipy.linalg import (toeplitz, hankel, circulant, hadamard, leslie, dft,
|
||||
companion, tri, triu, tril, kron, block_diag,
|
||||
helmert, hilbert, invhilbert, pascal, invpascal,
|
||||
fiedler, fiedler_companion, eigvals,
|
||||
convolution_matrix)
|
||||
from numpy.linalg import cond
|
||||
|
||||
|
||||
def get_mat(n):
|
||||
data = arange(n)
|
||||
data = add.outer(data, data)
|
||||
return data
|
||||
|
||||
|
||||
class TestTri:
|
||||
def test_basic(self):
|
||||
assert_equal(tri(4), array([[1, 0, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[1, 1, 1, 0],
|
||||
[1, 1, 1, 1]]))
|
||||
assert_equal(tri(4, dtype='f'), array([[1, 0, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[1, 1, 1, 0],
|
||||
[1, 1, 1, 1]], 'f'))
|
||||
|
||||
def test_diag(self):
|
||||
assert_equal(tri(4, k=1), array([[1, 1, 0, 0],
|
||||
[1, 1, 1, 0],
|
||||
[1, 1, 1, 1],
|
||||
[1, 1, 1, 1]]))
|
||||
assert_equal(tri(4, k=-1), array([[0, 0, 0, 0],
|
||||
[1, 0, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[1, 1, 1, 0]]))
|
||||
|
||||
def test_2d(self):
|
||||
assert_equal(tri(4, 3), array([[1, 0, 0],
|
||||
[1, 1, 0],
|
||||
[1, 1, 1],
|
||||
[1, 1, 1]]))
|
||||
assert_equal(tri(3, 4), array([[1, 0, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[1, 1, 1, 0]]))
|
||||
|
||||
def test_diag2d(self):
|
||||
assert_equal(tri(3, 4, k=2), array([[1, 1, 1, 0],
|
||||
[1, 1, 1, 1],
|
||||
[1, 1, 1, 1]]))
|
||||
assert_equal(tri(4, 3, k=-2), array([[0, 0, 0],
|
||||
[0, 0, 0],
|
||||
[1, 0, 0],
|
||||
[1, 1, 0]]))
|
||||
|
||||
|
||||
class TestTril:
|
||||
def test_basic(self):
|
||||
a = (100*get_mat(5)).astype('l')
|
||||
b = a.copy()
|
||||
for k in range(5):
|
||||
for l in range(k+1, 5):
|
||||
b[k, l] = 0
|
||||
assert_equal(tril(a), b)
|
||||
|
||||
def test_diag(self):
|
||||
a = (100*get_mat(5)).astype('f')
|
||||
b = a.copy()
|
||||
for k in range(5):
|
||||
for l in range(k+3, 5):
|
||||
b[k, l] = 0
|
||||
assert_equal(tril(a, k=2), b)
|
||||
b = a.copy()
|
||||
for k in range(5):
|
||||
for l in range(max((k-1, 0)), 5):
|
||||
b[k, l] = 0
|
||||
assert_equal(tril(a, k=-2), b)
|
||||
|
||||
|
||||
class TestTriu:
|
||||
def test_basic(self):
|
||||
a = (100*get_mat(5)).astype('l')
|
||||
b = a.copy()
|
||||
for k in range(5):
|
||||
for l in range(k+1, 5):
|
||||
b[l, k] = 0
|
||||
assert_equal(triu(a), b)
|
||||
|
||||
def test_diag(self):
|
||||
a = (100*get_mat(5)).astype('f')
|
||||
b = a.copy()
|
||||
for k in range(5):
|
||||
for l in range(max((k-1, 0)), 5):
|
||||
b[l, k] = 0
|
||||
assert_equal(triu(a, k=2), b)
|
||||
b = a.copy()
|
||||
for k in range(5):
|
||||
for l in range(k+3, 5):
|
||||
b[l, k] = 0
|
||||
assert_equal(triu(a, k=-2), b)
|
||||
|
||||
|
||||
class TestToeplitz:
|
||||
|
||||
def test_basic(self):
|
||||
y = toeplitz([1, 2, 3])
|
||||
assert_array_equal(y, [[1, 2, 3], [2, 1, 2], [3, 2, 1]])
|
||||
y = toeplitz([1, 2, 3], [1, 4, 5])
|
||||
assert_array_equal(y, [[1, 4, 5], [2, 1, 4], [3, 2, 1]])
|
||||
|
||||
def test_complex_01(self):
|
||||
data = (1.0 + arange(3.0)) * (1.0 + 1.0j)
|
||||
x = copy(data)
|
||||
t = toeplitz(x)
|
||||
# Calling toeplitz should not change x.
|
||||
assert_array_equal(x, data)
|
||||
# According to the docstring, x should be the first column of t.
|
||||
col0 = t[:, 0]
|
||||
assert_array_equal(col0, data)
|
||||
assert_array_equal(t[0, 1:], data[1:].conj())
|
||||
|
||||
def test_scalar_00(self):
|
||||
"""Scalar arguments still produce a 2D array."""
|
||||
t = toeplitz(10)
|
||||
assert_array_equal(t, [[10]])
|
||||
t = toeplitz(10, 20)
|
||||
assert_array_equal(t, [[10]])
|
||||
|
||||
def test_scalar_01(self):
|
||||
c = array([1, 2, 3])
|
||||
t = toeplitz(c, 1)
|
||||
assert_array_equal(t, [[1], [2], [3]])
|
||||
|
||||
def test_scalar_02(self):
|
||||
c = array([1, 2, 3])
|
||||
t = toeplitz(c, array(1))
|
||||
assert_array_equal(t, [[1], [2], [3]])
|
||||
|
||||
def test_scalar_03(self):
|
||||
c = array([1, 2, 3])
|
||||
t = toeplitz(c, array([1]))
|
||||
assert_array_equal(t, [[1], [2], [3]])
|
||||
|
||||
def test_scalar_04(self):
|
||||
r = array([10, 2, 3])
|
||||
t = toeplitz(1, r)
|
||||
assert_array_equal(t, [[1, 2, 3]])
|
||||
|
||||
|
||||
class TestHankel:
|
||||
def test_basic(self):
|
||||
y = hankel([1, 2, 3])
|
||||
assert_array_equal(y, [[1, 2, 3], [2, 3, 0], [3, 0, 0]])
|
||||
y = hankel([1, 2, 3], [3, 4, 5])
|
||||
assert_array_equal(y, [[1, 2, 3], [2, 3, 4], [3, 4, 5]])
|
||||
|
||||
|
||||
class TestCirculant:
|
||||
def test_basic(self):
|
||||
y = circulant([1, 2, 3])
|
||||
assert_array_equal(y, [[1, 3, 2], [2, 1, 3], [3, 2, 1]])
|
||||
|
||||
|
||||
class TestHadamard:
|
||||
|
||||
def test_basic(self):
|
||||
|
||||
y = hadamard(1)
|
||||
assert_array_equal(y, [[1]])
|
||||
|
||||
y = hadamard(2, dtype=float)
|
||||
assert_array_equal(y, [[1.0, 1.0], [1.0, -1.0]])
|
||||
|
||||
y = hadamard(4)
|
||||
assert_array_equal(y, [[1, 1, 1, 1],
|
||||
[1, -1, 1, -1],
|
||||
[1, 1, -1, -1],
|
||||
[1, -1, -1, 1]])
|
||||
|
||||
assert_raises(ValueError, hadamard, 0)
|
||||
assert_raises(ValueError, hadamard, 5)
|
||||
|
||||
|
||||
class TestLeslie:
|
||||
|
||||
def test_bad_shapes(self):
|
||||
assert_raises(ValueError, leslie, [[1, 1], [2, 2]], [3, 4, 5])
|
||||
assert_raises(ValueError, leslie, [3, 4, 5], [[1, 1], [2, 2]])
|
||||
assert_raises(ValueError, leslie, [1, 2], [1, 2])
|
||||
assert_raises(ValueError, leslie, [1], [])
|
||||
|
||||
def test_basic(self):
|
||||
a = leslie([1, 2, 3], [0.25, 0.5])
|
||||
expected = array([[1.0, 2.0, 3.0],
|
||||
[0.25, 0.0, 0.0],
|
||||
[0.0, 0.5, 0.0]])
|
||||
assert_array_equal(a, expected)
|
||||
|
||||
|
||||
class TestCompanion:
|
||||
|
||||
def test_bad_shapes(self):
|
||||
assert_raises(ValueError, companion, [[1, 1], [2, 2]])
|
||||
assert_raises(ValueError, companion, [0, 4, 5])
|
||||
assert_raises(ValueError, companion, [1])
|
||||
assert_raises(ValueError, companion, [])
|
||||
|
||||
def test_basic(self):
|
||||
c = companion([1, 2, 3])
|
||||
expected = array([
|
||||
[-2.0, -3.0],
|
||||
[1.0, 0.0]])
|
||||
assert_array_equal(c, expected)
|
||||
|
||||
c = companion([2.0, 5.0, -10.0])
|
||||
expected = array([
|
||||
[-2.5, 5.0],
|
||||
[1.0, 0.0]])
|
||||
assert_array_equal(c, expected)
|
||||
|
||||
|
||||
class TestBlockDiag:
|
||||
def test_basic(self):
|
||||
x = block_diag(eye(2), [[1, 2], [3, 4], [5, 6]], [[1, 2, 3]])
|
||||
assert_array_equal(x, [[1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 0, 0],
|
||||
[0, 0, 1, 2, 0, 0, 0],
|
||||
[0, 0, 3, 4, 0, 0, 0],
|
||||
[0, 0, 5, 6, 0, 0, 0],
|
||||
[0, 0, 0, 0, 1, 2, 3]])
|
||||
|
||||
def test_dtype(self):
|
||||
x = block_diag([[1.5]])
|
||||
assert_equal(x.dtype, float)
|
||||
|
||||
x = block_diag([[True]])
|
||||
assert_equal(x.dtype, bool)
|
||||
|
||||
def test_mixed_dtypes(self):
|
||||
actual = block_diag([[1]], [[1j]])
|
||||
desired = np.array([[1, 0], [0, 1j]])
|
||||
assert_array_equal(actual, desired)
|
||||
|
||||
def test_scalar_and_1d_args(self):
|
||||
a = block_diag(1)
|
||||
assert_equal(a.shape, (1, 1))
|
||||
assert_array_equal(a, [[1]])
|
||||
|
||||
a = block_diag([2, 3], 4)
|
||||
assert_array_equal(a, [[2, 3, 0], [0, 0, 4]])
|
||||
|
||||
def test_bad_arg(self):
|
||||
assert_raises(ValueError, block_diag, [[[1]]])
|
||||
|
||||
def test_no_args(self):
|
||||
a = block_diag()
|
||||
assert_equal(a.ndim, 2)
|
||||
assert_equal(a.nbytes, 0)
|
||||
|
||||
def test_empty_matrix_arg(self):
|
||||
# regression test for gh-4596: check the shape of the result
|
||||
# for empty matrix inputs. Empty matrices are no longer ignored
|
||||
# (gh-4908) it is viewed as a shape (1, 0) matrix.
|
||||
a = block_diag([[1, 0], [0, 1]],
|
||||
[],
|
||||
[[2, 3], [4, 5], [6, 7]])
|
||||
assert_array_equal(a, [[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 2, 3],
|
||||
[0, 0, 4, 5],
|
||||
[0, 0, 6, 7]])
|
||||
|
||||
def test_zerosized_matrix_arg(self):
|
||||
# test for gh-4908: check the shape of the result for
|
||||
# zero-sized matrix inputs, i.e. matrices with shape (0,n) or (n,0).
|
||||
# note that [[]] takes shape (1,0)
|
||||
a = block_diag([[1, 0], [0, 1]],
|
||||
[[]],
|
||||
[[2, 3], [4, 5], [6, 7]],
|
||||
np.zeros([0, 2], dtype='int32'))
|
||||
assert_array_equal(a, [[1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 2, 3, 0, 0],
|
||||
[0, 0, 4, 5, 0, 0],
|
||||
[0, 0, 6, 7, 0, 0]])
|
||||
|
||||
|
||||
class TestKron:
|
||||
|
||||
def test_basic(self):
|
||||
|
||||
a = kron(array([[1, 2], [3, 4]]), array([[1, 1, 1]]))
|
||||
assert_array_equal(a, array([[1, 1, 1, 2, 2, 2],
|
||||
[3, 3, 3, 4, 4, 4]]))
|
||||
|
||||
m1 = array([[1, 2], [3, 4]])
|
||||
m2 = array([[10], [11]])
|
||||
a = kron(m1, m2)
|
||||
expected = array([[10, 20],
|
||||
[11, 22],
|
||||
[30, 40],
|
||||
[33, 44]])
|
||||
assert_array_equal(a, expected)
|
||||
|
||||
|
||||
class TestHelmert:
|
||||
|
||||
def test_orthogonality(self):
|
||||
for n in range(1, 7):
|
||||
H = helmert(n, full=True)
|
||||
Id = np.eye(n)
|
||||
assert_allclose(H.dot(H.T), Id, atol=1e-12)
|
||||
assert_allclose(H.T.dot(H), Id, atol=1e-12)
|
||||
|
||||
def test_subspace(self):
|
||||
for n in range(2, 7):
|
||||
H_full = helmert(n, full=True)
|
||||
H_partial = helmert(n)
|
||||
for U in H_full[1:, :].T, H_partial.T:
|
||||
C = np.eye(n) - np.full((n, n), 1 / n)
|
||||
assert_allclose(U.dot(U.T), C)
|
||||
assert_allclose(U.T.dot(U), np.eye(n-1), atol=1e-12)
|
||||
|
||||
|
||||
class TestHilbert:
|
||||
|
||||
def test_basic(self):
|
||||
h3 = array([[1.0, 1/2., 1/3.],
|
||||
[1/2., 1/3., 1/4.],
|
||||
[1/3., 1/4., 1/5.]])
|
||||
assert_array_almost_equal(hilbert(3), h3)
|
||||
|
||||
assert_array_equal(hilbert(1), [[1.0]])
|
||||
|
||||
h0 = hilbert(0)
|
||||
assert_equal(h0.shape, (0, 0))
|
||||
|
||||
|
||||
class TestInvHilbert:
|
||||
|
||||
def test_basic(self):
|
||||
invh1 = array([[1]])
|
||||
assert_array_equal(invhilbert(1, exact=True), invh1)
|
||||
assert_array_equal(invhilbert(1), invh1)
|
||||
|
||||
invh2 = array([[4, -6],
|
||||
[-6, 12]])
|
||||
assert_array_equal(invhilbert(2, exact=True), invh2)
|
||||
assert_array_almost_equal(invhilbert(2), invh2)
|
||||
|
||||
invh3 = array([[9, -36, 30],
|
||||
[-36, 192, -180],
|
||||
[30, -180, 180]])
|
||||
assert_array_equal(invhilbert(3, exact=True), invh3)
|
||||
assert_array_almost_equal(invhilbert(3), invh3)
|
||||
|
||||
invh4 = array([[16, -120, 240, -140],
|
||||
[-120, 1200, -2700, 1680],
|
||||
[240, -2700, 6480, -4200],
|
||||
[-140, 1680, -4200, 2800]])
|
||||
assert_array_equal(invhilbert(4, exact=True), invh4)
|
||||
assert_array_almost_equal(invhilbert(4), invh4)
|
||||
|
||||
invh5 = array([[25, -300, 1050, -1400, 630],
|
||||
[-300, 4800, -18900, 26880, -12600],
|
||||
[1050, -18900, 79380, -117600, 56700],
|
||||
[-1400, 26880, -117600, 179200, -88200],
|
||||
[630, -12600, 56700, -88200, 44100]])
|
||||
assert_array_equal(invhilbert(5, exact=True), invh5)
|
||||
assert_array_almost_equal(invhilbert(5), invh5)
|
||||
|
||||
invh17 = array([
|
||||
[289, -41616, 1976760, -46124400, 629598060, -5540462928,
|
||||
33374693352, -143034400080, 446982500250, -1033026222800,
|
||||
1774926873720, -2258997839280, 2099709530100, -1384423866000,
|
||||
613101997800, -163493866080, 19835652870],
|
||||
[-41616, 7990272, -426980160, 10627061760, -151103534400,
|
||||
1367702848512, -8410422724704, 36616806420480, -115857864064800,
|
||||
270465047424000, -468580694662080, 600545887119360,
|
||||
-561522320049600, 372133135180800, -165537539406000,
|
||||
44316454993920, -5395297580640],
|
||||
[1976760, -426980160, 24337869120, -630981792000, 9228108708000,
|
||||
-85267724461920, 532660105897920, -2348052711713280,
|
||||
7504429831470000, -17664748409880000, 30818191841236800,
|
||||
-39732544853164800, 37341234283298400, -24857330514030000,
|
||||
11100752642520000, -2982128117299200, 364182586693200],
|
||||
[-46124400, 10627061760, -630981792000, 16826181120000,
|
||||
-251209625940000, 2358021022156800, -14914482965141760,
|
||||
66409571644416000, -214015221119700000, 507295338950400000,
|
||||
-890303319857952000, 1153715376477081600, -1089119333262870000,
|
||||
727848632044800000, -326170262829600000, 87894302404608000,
|
||||
-10763618673376800],
|
||||
[629598060, -151103534400, 9228108708000,
|
||||
-251209625940000, 3810012660090000, -36210360321495360,
|
||||
231343968720664800, -1038687206500944000, 3370739732635275000,
|
||||
-8037460526495400000, 14178080368737885600, -18454939322943942000,
|
||||
17489975175339030000, -11728977435138600000, 5272370630081100000,
|
||||
-1424711708039692800, 174908803442373000],
|
||||
[-5540462928, 1367702848512, -85267724461920, 2358021022156800,
|
||||
-36210360321495360, 347619459086355456, -2239409617216035264,
|
||||
10124803292907663360, -33052510749726468000,
|
||||
79217210949138662400, -140362995650505067440,
|
||||
183420385176741672960, -174433352415381259200,
|
||||
117339159519533952000, -52892422160973595200,
|
||||
14328529177999196160, -1763080738699119840],
|
||||
[33374693352, -8410422724704, 532660105897920,
|
||||
-14914482965141760, 231343968720664800, -2239409617216035264,
|
||||
14527452132196331328, -66072377044391477760,
|
||||
216799987176909536400, -521925895055522958000,
|
||||
928414062734059661760, -1217424500995626443520,
|
||||
1161358898976091015200, -783401860847777371200,
|
||||
354015418167362952000, -96120549902411274240,
|
||||
11851820521255194480],
|
||||
[-143034400080, 36616806420480, -2348052711713280,
|
||||
66409571644416000, -1038687206500944000, 10124803292907663360,
|
||||
-66072377044391477760, 302045152202932469760,
|
||||
-995510145200094810000, 2405996923185123840000,
|
||||
-4294704507885446054400, 5649058909023744614400,
|
||||
-5403874060541811254400, 3654352703663101440000,
|
||||
-1655137020003255360000, 450325202737117593600,
|
||||
-55630994283442749600],
|
||||
[446982500250, -115857864064800, 7504429831470000,
|
||||
-214015221119700000, 3370739732635275000, -33052510749726468000,
|
||||
216799987176909536400, -995510145200094810000,
|
||||
3293967392206196062500, -7988661659013106500000,
|
||||
14303908928401362270000, -18866974090684772052000,
|
||||
18093328327706957325000, -12263364009096700500000,
|
||||
5565847995255512250000, -1517208935002984080000,
|
||||
187754605706619279900],
|
||||
[-1033026222800, 270465047424000, -17664748409880000,
|
||||
507295338950400000, -8037460526495400000, 79217210949138662400,
|
||||
-521925895055522958000, 2405996923185123840000,
|
||||
-7988661659013106500000, 19434404971634224000000,
|
||||
-34894474126569249192000, 46141453390504792320000,
|
||||
-44349976506971935800000, 30121928988527376000000,
|
||||
-13697025107665828500000, 3740200989399948902400,
|
||||
-463591619028689580000],
|
||||
[1774926873720, -468580694662080,
|
||||
30818191841236800, -890303319857952000, 14178080368737885600,
|
||||
-140362995650505067440, 928414062734059661760,
|
||||
-4294704507885446054400, 14303908928401362270000,
|
||||
-34894474126569249192000, 62810053427824648545600,
|
||||
-83243376594051600326400, 80177044485212743068000,
|
||||
-54558343880470209780000, 24851882355348879230400,
|
||||
-6797096028813368678400, 843736746632215035600],
|
||||
[-2258997839280, 600545887119360, -39732544853164800,
|
||||
1153715376477081600, -18454939322943942000, 183420385176741672960,
|
||||
-1217424500995626443520, 5649058909023744614400,
|
||||
-18866974090684772052000, 46141453390504792320000,
|
||||
-83243376594051600326400, 110552468520163390156800,
|
||||
-106681852579497947388000, 72720410752415168870400,
|
||||
-33177973900974346080000, 9087761081682520473600,
|
||||
-1129631016152221783200],
|
||||
[2099709530100, -561522320049600, 37341234283298400,
|
||||
-1089119333262870000, 17489975175339030000,
|
||||
-174433352415381259200, 1161358898976091015200,
|
||||
-5403874060541811254400, 18093328327706957325000,
|
||||
-44349976506971935800000, 80177044485212743068000,
|
||||
-106681852579497947388000, 103125790826848015808400,
|
||||
-70409051543137015800000, 32171029219823375700000,
|
||||
-8824053728865840192000, 1098252376814660067000],
|
||||
[-1384423866000, 372133135180800,
|
||||
-24857330514030000, 727848632044800000, -11728977435138600000,
|
||||
117339159519533952000, -783401860847777371200,
|
||||
3654352703663101440000, -12263364009096700500000,
|
||||
30121928988527376000000, -54558343880470209780000,
|
||||
72720410752415168870400, -70409051543137015800000,
|
||||
48142941226076592000000, -22027500987368499000000,
|
||||
6049545098753157120000, -753830033789944188000],
|
||||
[613101997800, -165537539406000,
|
||||
11100752642520000, -326170262829600000, 5272370630081100000,
|
||||
-52892422160973595200, 354015418167362952000,
|
||||
-1655137020003255360000, 5565847995255512250000,
|
||||
-13697025107665828500000, 24851882355348879230400,
|
||||
-33177973900974346080000, 32171029219823375700000,
|
||||
-22027500987368499000000, 10091416708498869000000,
|
||||
-2774765838662800128000, 346146444087219270000],
|
||||
[-163493866080, 44316454993920, -2982128117299200,
|
||||
87894302404608000, -1424711708039692800,
|
||||
14328529177999196160, -96120549902411274240,
|
||||
450325202737117593600, -1517208935002984080000,
|
||||
3740200989399948902400, -6797096028813368678400,
|
||||
9087761081682520473600, -8824053728865840192000,
|
||||
6049545098753157120000, -2774765838662800128000,
|
||||
763806510427609497600, -95382575704033754400],
|
||||
[19835652870, -5395297580640, 364182586693200, -10763618673376800,
|
||||
174908803442373000, -1763080738699119840, 11851820521255194480,
|
||||
-55630994283442749600, 187754605706619279900,
|
||||
-463591619028689580000, 843736746632215035600,
|
||||
-1129631016152221783200, 1098252376814660067000,
|
||||
-753830033789944188000, 346146444087219270000,
|
||||
-95382575704033754400, 11922821963004219300]
|
||||
])
|
||||
assert_array_equal(invhilbert(17, exact=True), invh17)
|
||||
assert_allclose(invhilbert(17), invh17.astype(float), rtol=1e-12)
|
||||
|
||||
def test_inverse(self):
|
||||
for n in range(1, 10):
|
||||
a = hilbert(n)
|
||||
b = invhilbert(n)
|
||||
# The Hilbert matrix is increasingly badly conditioned,
|
||||
# so take that into account in the test
|
||||
c = cond(a)
|
||||
assert_allclose(a.dot(b), eye(n), atol=1e-15*c, rtol=1e-15*c)
|
||||
|
||||
|
||||
class TestPascal:
|
||||
|
||||
cases = [
|
||||
(1, array([[1]]), array([[1]])),
|
||||
(2, array([[1, 1],
|
||||
[1, 2]]),
|
||||
array([[1, 0],
|
||||
[1, 1]])),
|
||||
(3, array([[1, 1, 1],
|
||||
[1, 2, 3],
|
||||
[1, 3, 6]]),
|
||||
array([[1, 0, 0],
|
||||
[1, 1, 0],
|
||||
[1, 2, 1]])),
|
||||
(4, array([[1, 1, 1, 1],
|
||||
[1, 2, 3, 4],
|
||||
[1, 3, 6, 10],
|
||||
[1, 4, 10, 20]]),
|
||||
array([[1, 0, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[1, 2, 1, 0],
|
||||
[1, 3, 3, 1]])),
|
||||
]
|
||||
|
||||
def check_case(self, n, sym, low):
|
||||
assert_array_equal(pascal(n), sym)
|
||||
assert_array_equal(pascal(n, kind='lower'), low)
|
||||
assert_array_equal(pascal(n, kind='upper'), low.T)
|
||||
assert_array_almost_equal(pascal(n, exact=False), sym)
|
||||
assert_array_almost_equal(pascal(n, exact=False, kind='lower'), low)
|
||||
assert_array_almost_equal(pascal(n, exact=False, kind='upper'), low.T)
|
||||
|
||||
def test_cases(self):
|
||||
for n, sym, low in self.cases:
|
||||
self.check_case(n, sym, low)
|
||||
|
||||
def test_big(self):
|
||||
p = pascal(50)
|
||||
assert p[-1, -1] == comb(98, 49, exact=True)
|
||||
|
||||
def test_threshold(self):
|
||||
# Regression test. An early version of `pascal` returned an
|
||||
# array of type np.uint64 for n=35, but that data type is too small
|
||||
# to hold p[-1, -1]. The second assert_equal below would fail
|
||||
# because p[-1, -1] overflowed.
|
||||
p = pascal(34)
|
||||
assert_equal(2*p.item(-1, -2), p.item(-1, -1), err_msg="n = 34")
|
||||
p = pascal(35)
|
||||
assert_equal(2.*p.item(-1, -2), 1.*p.item(-1, -1), err_msg="n = 35")
|
||||
|
||||
|
||||
def test_invpascal():
|
||||
|
||||
def check_invpascal(n, kind, exact):
|
||||
ip = invpascal(n, kind=kind, exact=exact)
|
||||
p = pascal(n, kind=kind, exact=exact)
|
||||
# Matrix-multiply ip and p, and check that we get the identity matrix.
|
||||
# We can't use the simple expression e = ip.dot(p), because when
|
||||
# n < 35 and exact is True, p.dtype is np.uint64 and ip.dtype is
|
||||
# np.int64. The product of those dtypes is np.float64, which loses
|
||||
# precision when n is greater than 18. Instead we'll cast both to
|
||||
# object arrays, and then multiply.
|
||||
e = ip.astype(object).dot(p.astype(object))
|
||||
assert_array_equal(e, eye(n), err_msg="n=%d kind=%r exact=%r" %
|
||||
(n, kind, exact))
|
||||
|
||||
kinds = ['symmetric', 'lower', 'upper']
|
||||
|
||||
ns = [1, 2, 5, 18]
|
||||
for n in ns:
|
||||
for kind in kinds:
|
||||
for exact in [True, False]:
|
||||
check_invpascal(n, kind, exact)
|
||||
|
||||
ns = [19, 34, 35, 50]
|
||||
for n in ns:
|
||||
for kind in kinds:
|
||||
check_invpascal(n, kind, True)
|
||||
|
||||
|
||||
def test_dft():
|
||||
m = dft(2)
|
||||
expected = array([[1.0, 1.0], [1.0, -1.0]])
|
||||
assert_array_almost_equal(m, expected)
|
||||
m = dft(2, scale='n')
|
||||
assert_array_almost_equal(m, expected/2.0)
|
||||
m = dft(2, scale='sqrtn')
|
||||
assert_array_almost_equal(m, expected/sqrt(2.0))
|
||||
|
||||
x = array([0, 1, 2, 3, 4, 5, 0, 1])
|
||||
m = dft(8)
|
||||
mx = m.dot(x)
|
||||
fx = fft(x)
|
||||
assert_array_almost_equal(mx, fx)
|
||||
|
||||
|
||||
def test_fiedler():
|
||||
f = fiedler([])
|
||||
assert_equal(f.size, 0)
|
||||
f = fiedler([123.])
|
||||
assert_array_equal(f, np.array([[0.]]))
|
||||
f = fiedler(np.arange(1, 7))
|
||||
des = np.array([[0, 1, 2, 3, 4, 5],
|
||||
[1, 0, 1, 2, 3, 4],
|
||||
[2, 1, 0, 1, 2, 3],
|
||||
[3, 2, 1, 0, 1, 2],
|
||||
[4, 3, 2, 1, 0, 1],
|
||||
[5, 4, 3, 2, 1, 0]])
|
||||
assert_array_equal(f, des)
|
||||
|
||||
|
||||
def test_fiedler_companion():
|
||||
fc = fiedler_companion([])
|
||||
assert_equal(fc.size, 0)
|
||||
fc = fiedler_companion([1.])
|
||||
assert_equal(fc.size, 0)
|
||||
fc = fiedler_companion([1., 2.])
|
||||
assert_array_equal(fc, np.array([[-2.]]))
|
||||
fc = fiedler_companion([1e-12, 2., 3.])
|
||||
assert_array_almost_equal(fc, companion([1e-12, 2., 3.]))
|
||||
with assert_raises(ValueError):
|
||||
fiedler_companion([0, 1, 2])
|
||||
fc = fiedler_companion([1., -16., 86., -176., 105.])
|
||||
assert_array_almost_equal(eigvals(fc),
|
||||
np.array([7., 5., 3., 1.]))
|
||||
|
||||
|
||||
class TestConvolutionMatrix:
|
||||
"""
|
||||
Test convolution_matrix vs. numpy.convolve for various parameters.
|
||||
"""
|
||||
|
||||
def create_vector(self, n, cpx):
|
||||
"""Make a complex or real test vector of length n."""
|
||||
x = np.linspace(-2.5, 2.2, n)
|
||||
if cpx:
|
||||
x = x + 1j*np.linspace(-1.5, 3.1, n)
|
||||
return x
|
||||
|
||||
def test_bad_n(self):
|
||||
# n must be a positive integer
|
||||
with pytest.raises(ValueError, match='n must be a positive integer'):
|
||||
convolution_matrix([1, 2, 3], 0)
|
||||
|
||||
def test_bad_first_arg(self):
|
||||
# first arg must be a 1d array, otherwise ValueError
|
||||
with pytest.raises(ValueError, match='one-dimensional'):
|
||||
convolution_matrix(1, 4)
|
||||
|
||||
def test_empty_first_arg(self):
|
||||
# first arg must have at least one value
|
||||
with pytest.raises(ValueError, match=r'len\(a\)'):
|
||||
convolution_matrix([], 4)
|
||||
|
||||
def test_bad_mode(self):
|
||||
# mode must be in ('full', 'valid', 'same')
|
||||
with pytest.raises(ValueError, match='mode.*must be one of'):
|
||||
convolution_matrix((1, 1), 4, mode='invalid argument')
|
||||
|
||||
@pytest.mark.parametrize('cpx', [False, True])
|
||||
@pytest.mark.parametrize('na', [1, 2, 9])
|
||||
@pytest.mark.parametrize('nv', [1, 2, 9])
|
||||
@pytest.mark.parametrize('mode', [None, 'full', 'valid', 'same'])
|
||||
def test_against_numpy_convolve(self, cpx, na, nv, mode):
|
||||
a = self.create_vector(na, cpx)
|
||||
v = self.create_vector(nv, cpx)
|
||||
if mode is None:
|
||||
y1 = np.convolve(v, a)
|
||||
A = convolution_matrix(a, nv)
|
||||
else:
|
||||
y1 = np.convolve(v, a, mode)
|
||||
A = convolution_matrix(a, nv, mode)
|
||||
y2 = A @ v
|
||||
assert_array_almost_equal(y1, y2)
|
||||
Reference in New Issue
Block a user