187 lines
8.6 KiB
Python
187 lines
8.6 KiB
Python
|
# pylint: disable=missing-docstring
|
||
|
import numpy as np
|
||
|
from numpy import array
|
||
|
from numpy.testing import (assert_allclose, assert_array_equal,
|
||
|
assert_almost_equal)
|
||
|
import pytest
|
||
|
from pytest import raises
|
||
|
|
||
|
import scipy.signal._bsplines as bsp
|
||
|
from scipy import signal
|
||
|
|
||
|
|
||
|
class TestBSplines:
|
||
|
"""Test behaviors of B-splines. Some of the values tested against were
|
||
|
returned as of SciPy 1.1.0 and are included for regression testing
|
||
|
purposes. Others (at integer points) are compared to theoretical
|
||
|
expressions (cf. Unser, Aldroubi, Eden, IEEE TSP 1993, Table 1)."""
|
||
|
|
||
|
def test_spline_filter(self):
|
||
|
np.random.seed(12457)
|
||
|
# Test the type-error branch
|
||
|
raises(TypeError, bsp.spline_filter, array([0]), 0)
|
||
|
# Test the real branch
|
||
|
np.random.seed(12457)
|
||
|
data_array_real = np.random.rand(12, 12)
|
||
|
# make the magnitude exceed 1, and make some negative
|
||
|
data_array_real = 10*(1-2*data_array_real)
|
||
|
result_array_real = array(
|
||
|
[[-.463312621, 8.33391222, .697290949, 5.28390836,
|
||
|
5.92066474, 6.59452137, 9.84406950, -8.78324188,
|
||
|
7.20675750, -8.17222994, -4.38633345, 9.89917069],
|
||
|
[2.67755154, 6.24192170, -3.15730578, 9.87658581,
|
||
|
-9.96930425, 3.17194115, -4.50919947, 5.75423446,
|
||
|
9.65979824, -8.29066885, .971416087, -2.38331897],
|
||
|
[-7.08868346, 4.89887705, -1.37062289, 7.70705838,
|
||
|
2.51526461, 3.65885497, 5.16786604, -8.77715342e-03,
|
||
|
4.10533325, 9.04761993, -.577960351, 9.86382519],
|
||
|
[-4.71444301, -1.68038985, 2.84695116, 1.14315938,
|
||
|
-3.17127091, 1.91830461, 7.13779687, -5.35737482,
|
||
|
-9.66586425, -9.87717456, 9.93160672, 4.71948144],
|
||
|
[9.49551194, -1.92958436, 6.25427993, -9.05582911,
|
||
|
3.97562282, 7.68232426, -1.04514824, -5.86021443,
|
||
|
-8.43007451, 5.47528997, 2.06330736, -8.65968112],
|
||
|
[-8.91720100, 8.87065356, 3.76879937, 2.56222894,
|
||
|
-.828387146, 8.72288903, 6.42474741, -6.84576083,
|
||
|
9.94724115, 6.90665380, -6.61084494, -9.44907391],
|
||
|
[9.25196790, -.774032030, 7.05371046, -2.73505725,
|
||
|
2.53953305, -1.82889155, 2.95454824, -1.66362046,
|
||
|
5.72478916, -3.10287679, 1.54017123, -7.87759020],
|
||
|
[-3.98464539, -2.44316992, -1.12708657, 1.01725672,
|
||
|
-8.89294671, -5.42145629, -6.16370321, 2.91775492,
|
||
|
9.64132208, .702499998, -2.02622392, 1.56308431],
|
||
|
[-2.22050773, 7.89951554, 5.98970713, -7.35861835,
|
||
|
5.45459283, -7.76427957, 3.67280490, -4.05521315,
|
||
|
4.51967507, -3.22738749, -3.65080177, 3.05630155],
|
||
|
[-6.21240584, -.296796126, -8.34800163, 9.21564563,
|
||
|
-3.61958784, -4.77120006, -3.99454057, 1.05021988e-03,
|
||
|
-6.95982829, 6.04380797, 8.43181250, -2.71653339],
|
||
|
[1.19638037, 6.99718842e-02, 6.72020394, -2.13963198,
|
||
|
3.75309875, -5.70076744, 5.92143551, -7.22150575,
|
||
|
-3.77114594, -1.11903194, -5.39151466, 3.06620093],
|
||
|
[9.86326886, 1.05134482, -7.75950607, -3.64429655,
|
||
|
7.81848957, -9.02270373, 3.73399754, -4.71962549,
|
||
|
-7.71144306, 3.78263161, 6.46034818, -4.43444731]])
|
||
|
assert_allclose(bsp.spline_filter(data_array_real, 0),
|
||
|
result_array_real)
|
||
|
|
||
|
def test_gauss_spline(self):
|
||
|
np.random.seed(12459)
|
||
|
assert_almost_equal(bsp.gauss_spline(0, 0), 1.381976597885342)
|
||
|
assert_allclose(bsp.gauss_spline(array([1.]), 1), array([0.04865217]))
|
||
|
|
||
|
def test_gauss_spline_list(self):
|
||
|
# regression test for gh-12152 (accept array_like)
|
||
|
knots = [-1.0, 0.0, -1.0]
|
||
|
assert_almost_equal(bsp.gauss_spline(knots, 3),
|
||
|
array([0.15418033, 0.6909883, 0.15418033]))
|
||
|
|
||
|
def test_cspline1d(self):
|
||
|
np.random.seed(12462)
|
||
|
assert_array_equal(bsp.cspline1d(array([0])), [0.])
|
||
|
c1d = array([1.21037185, 1.86293902, 2.98834059, 4.11660378,
|
||
|
4.78893826])
|
||
|
# test lamda != 0
|
||
|
assert_allclose(bsp.cspline1d(array([1., 2, 3, 4, 5]), 1), c1d)
|
||
|
c1d0 = array([0.78683946, 2.05333735, 2.99981113, 3.94741812,
|
||
|
5.21051638])
|
||
|
assert_allclose(bsp.cspline1d(array([1., 2, 3, 4, 5])), c1d0)
|
||
|
|
||
|
def test_qspline1d(self):
|
||
|
np.random.seed(12463)
|
||
|
assert_array_equal(bsp.qspline1d(array([0])), [0.])
|
||
|
# test lamda != 0
|
||
|
raises(ValueError, bsp.qspline1d, array([1., 2, 3, 4, 5]), 1.)
|
||
|
raises(ValueError, bsp.qspline1d, array([1., 2, 3, 4, 5]), -1.)
|
||
|
q1d0 = array([0.85350007, 2.02441743, 2.99999534, 3.97561055,
|
||
|
5.14634135])
|
||
|
assert_allclose(bsp.qspline1d(array([1., 2, 3, 4, 5])), q1d0)
|
||
|
|
||
|
def test_cspline1d_eval(self):
|
||
|
np.random.seed(12464)
|
||
|
assert_allclose(bsp.cspline1d_eval(array([0., 0]), [0.]), array([0.]))
|
||
|
assert_array_equal(bsp.cspline1d_eval(array([1., 0, 1]), []),
|
||
|
array([]))
|
||
|
x = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
|
||
|
dx = x[1]-x[0]
|
||
|
newx = [-6., -5.5, -5., -4.5, -4., -3.5, -3., -2.5, -2., -1.5, -1.,
|
||
|
-0.5, 0., 0.5, 1., 1.5, 2., 2.5, 3., 3.5, 4., 4.5, 5., 5.5, 6.,
|
||
|
6.5, 7., 7.5, 8., 8.5, 9., 9.5, 10., 10.5, 11., 11.5, 12.,
|
||
|
12.5]
|
||
|
y = array([4.216, 6.864, 3.514, 6.203, 6.759, 7.433, 7.874, 5.879,
|
||
|
1.396, 4.094])
|
||
|
cj = bsp.cspline1d(y)
|
||
|
newy = array([6.203, 4.41570658, 3.514, 5.16924703, 6.864, 6.04643068,
|
||
|
4.21600281, 6.04643068, 6.864, 5.16924703, 3.514,
|
||
|
4.41570658, 6.203, 6.80717667, 6.759, 6.98971173, 7.433,
|
||
|
7.79560142, 7.874, 7.41525761, 5.879, 3.18686814, 1.396,
|
||
|
2.24889482, 4.094, 2.24889482, 1.396, 3.18686814, 5.879,
|
||
|
7.41525761, 7.874, 7.79560142, 7.433, 6.98971173, 6.759,
|
||
|
6.80717667, 6.203, 4.41570658])
|
||
|
assert_allclose(bsp.cspline1d_eval(cj, newx, dx=dx, x0=x[0]), newy)
|
||
|
|
||
|
def test_qspline1d_eval(self):
|
||
|
np.random.seed(12465)
|
||
|
assert_allclose(bsp.qspline1d_eval(array([0., 0]), [0.]), array([0.]))
|
||
|
assert_array_equal(bsp.qspline1d_eval(array([1., 0, 1]), []),
|
||
|
array([]))
|
||
|
x = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
|
||
|
dx = x[1]-x[0]
|
||
|
newx = [-6., -5.5, -5., -4.5, -4., -3.5, -3., -2.5, -2., -1.5, -1.,
|
||
|
-0.5, 0., 0.5, 1., 1.5, 2., 2.5, 3., 3.5, 4., 4.5, 5., 5.5, 6.,
|
||
|
6.5, 7., 7.5, 8., 8.5, 9., 9.5, 10., 10.5, 11., 11.5, 12.,
|
||
|
12.5]
|
||
|
y = array([4.216, 6.864, 3.514, 6.203, 6.759, 7.433, 7.874, 5.879,
|
||
|
1.396, 4.094])
|
||
|
cj = bsp.qspline1d(y)
|
||
|
newy = array([6.203, 4.49418159, 3.514, 5.18390821, 6.864, 5.91436915,
|
||
|
4.21600002, 5.91436915, 6.864, 5.18390821, 3.514,
|
||
|
4.49418159, 6.203, 6.71900226, 6.759, 7.03980488, 7.433,
|
||
|
7.81016848, 7.874, 7.32718426, 5.879, 3.23872593, 1.396,
|
||
|
2.34046013, 4.094, 2.34046013, 1.396, 3.23872593, 5.879,
|
||
|
7.32718426, 7.874, 7.81016848, 7.433, 7.03980488, 6.759,
|
||
|
6.71900226, 6.203, 4.49418159])
|
||
|
assert_allclose(bsp.qspline1d_eval(cj, newx, dx=dx, x0=x[0]), newy)
|
||
|
|
||
|
|
||
|
def test_sepfir2d_invalid_filter():
|
||
|
filt = np.array([1.0, 2.0, 4.0, 2.0, 1.0])
|
||
|
image = np.random.rand(7, 9)
|
||
|
# No error for odd lengths
|
||
|
signal.sepfir2d(image, filt, filt[2:])
|
||
|
|
||
|
# Row or column filter must be odd
|
||
|
with pytest.raises(ValueError, match="odd length"):
|
||
|
signal.sepfir2d(image, filt, filt[1:])
|
||
|
with pytest.raises(ValueError, match="odd length"):
|
||
|
signal.sepfir2d(image, filt[1:], filt)
|
||
|
|
||
|
# Filters must be 1-dimensional
|
||
|
with pytest.raises(ValueError, match="object too deep"):
|
||
|
signal.sepfir2d(image, filt.reshape(1, -1), filt)
|
||
|
with pytest.raises(ValueError, match="object too deep"):
|
||
|
signal.sepfir2d(image, filt, filt.reshape(1, -1))
|
||
|
|
||
|
def test_sepfir2d_invalid_image():
|
||
|
filt = np.array([1.0, 2.0, 4.0, 2.0, 1.0])
|
||
|
image = np.random.rand(8, 8)
|
||
|
|
||
|
# Image must be 2 dimensional
|
||
|
with pytest.raises(ValueError, match="object too deep"):
|
||
|
signal.sepfir2d(image.reshape(4, 4, 4), filt, filt)
|
||
|
|
||
|
with pytest.raises(ValueError, match="object of too small depth"):
|
||
|
signal.sepfir2d(image[0], filt, filt)
|
||
|
|
||
|
|
||
|
def test_cspline2d():
|
||
|
np.random.seed(181819142)
|
||
|
image = np.random.rand(71, 73)
|
||
|
signal.cspline2d(image, 8.0)
|
||
|
|
||
|
|
||
|
def test_qspline2d():
|
||
|
np.random.seed(181819143)
|
||
|
image = np.random.rand(71, 73)
|
||
|
signal.qspline2d(image)
|