Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
13
venv/Lib/site-packages/scipy/fftpack/tests/Makefile
Normal file
13
venv/Lib/site-packages/scipy/fftpack/tests/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
CC = gcc
|
||||
LD = gcc
|
||||
|
||||
fftw_single: fftw_dct.c
|
||||
$(CC) -W -Wall -DDCT_TEST_USE_SINGLE $< -o $@ -lfftw3f
|
||||
|
||||
fftw_double: fftw_dct.c
|
||||
$(CC) -W -Wall $< -o $@ -lfftw3
|
||||
|
||||
clean:
|
||||
rm -f fftw_single
|
||||
rm -f fftw_double
|
||||
rm -f *.o
|
0
venv/Lib/site-packages/scipy/fftpack/tests/__init__.py
Normal file
0
venv/Lib/site-packages/scipy/fftpack/tests/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
150
venv/Lib/site-packages/scipy/fftpack/tests/fftw_dct.c
Normal file
150
venv/Lib/site-packages/scipy/fftpack/tests/fftw_dct.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
#if DCT_TEST_PRECISION == 1
|
||||
typedef float float_prec;
|
||||
#define PF "%.7f"
|
||||
#define FFTW_PLAN fftwf_plan
|
||||
#define FFTW_MALLOC fftwf_malloc
|
||||
#define FFTW_FREE fftwf_free
|
||||
#define FFTW_PLAN_CREATE fftwf_plan_r2r_1d
|
||||
#define FFTW_EXECUTE fftwf_execute
|
||||
#define FFTW_DESTROY_PLAN fftwf_destroy_plan
|
||||
#define FFTW_CLEANUP fftwf_cleanup
|
||||
#elif DCT_TEST_PRECISION == 2
|
||||
typedef double float_prec;
|
||||
#define PF "%.18f"
|
||||
#define FFTW_PLAN fftw_plan
|
||||
#define FFTW_MALLOC fftw_malloc
|
||||
#define FFTW_FREE fftw_free
|
||||
#define FFTW_PLAN_CREATE fftw_plan_r2r_1d
|
||||
#define FFTW_EXECUTE fftw_execute
|
||||
#define FFTW_DESTROY_PLAN fftw_destroy_plan
|
||||
#define FFTW_CLEANUP fftw_cleanup
|
||||
#elif DCT_TEST_PRECISION == 3
|
||||
typedef long double float_prec;
|
||||
#define PF "%.18Lf"
|
||||
#define FFTW_PLAN fftwl_plan
|
||||
#define FFTW_MALLOC fftwl_malloc
|
||||
#define FFTW_FREE fftwl_free
|
||||
#define FFTW_PLAN_CREATE fftwl_plan_r2r_1d
|
||||
#define FFTW_EXECUTE fftwl_execute
|
||||
#define FFTW_DESTROY_PLAN fftwl_destroy_plan
|
||||
#define FFTW_CLEANUP fftwl_cleanup
|
||||
#else
|
||||
#error DCT_TEST_PRECISION must be a number 1-3
|
||||
#endif
|
||||
|
||||
|
||||
enum type {
|
||||
DCT_I = 1,
|
||||
DCT_II = 2,
|
||||
DCT_III = 3,
|
||||
DCT_IV = 4,
|
||||
DST_I = 5,
|
||||
DST_II = 6,
|
||||
DST_III = 7,
|
||||
DST_IV = 8,
|
||||
};
|
||||
|
||||
int gen(int type, int sz)
|
||||
{
|
||||
float_prec *a, *b;
|
||||
FFTW_PLAN p;
|
||||
int i, tp;
|
||||
|
||||
a = FFTW_MALLOC(sizeof(*a) * sz);
|
||||
if (a == NULL) {
|
||||
fprintf(stderr, "failure\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
b = FFTW_MALLOC(sizeof(*b) * sz);
|
||||
if (b == NULL) {
|
||||
fprintf(stderr, "failure\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case DCT_I:
|
||||
tp = FFTW_REDFT00;
|
||||
break;
|
||||
case DCT_II:
|
||||
tp = FFTW_REDFT10;
|
||||
break;
|
||||
case DCT_III:
|
||||
tp = FFTW_REDFT01;
|
||||
break;
|
||||
case DCT_IV:
|
||||
tp = FFTW_REDFT11;
|
||||
break;
|
||||
case DST_I:
|
||||
tp = FFTW_RODFT00;
|
||||
break;
|
||||
case DST_II:
|
||||
tp = FFTW_RODFT10;
|
||||
break;
|
||||
case DST_III:
|
||||
tp = FFTW_RODFT01;
|
||||
break;
|
||||
case DST_IV:
|
||||
tp = FFTW_RODFT11;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case DCT_I:
|
||||
case DCT_II:
|
||||
case DCT_III:
|
||||
case DCT_IV:
|
||||
for(i=0; i < sz; ++i) {
|
||||
a[i] = i;
|
||||
}
|
||||
break;
|
||||
case DST_I:
|
||||
case DST_II:
|
||||
case DST_III:
|
||||
case DST_IV:
|
||||
/* TODO: what should we do for dst's?*/
|
||||
for(i=0; i < sz; ++i) {
|
||||
a[i] = i;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown type\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
p = FFTW_PLAN_CREATE(sz, a, b, tp, FFTW_ESTIMATE);
|
||||
FFTW_EXECUTE(p);
|
||||
FFTW_DESTROY_PLAN(p);
|
||||
|
||||
for(i=0; i < sz; ++i) {
|
||||
printf(PF"\n", b[i]);
|
||||
}
|
||||
FFTW_FREE(b);
|
||||
FFTW_FREE(a);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int n, tp;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "missing argument: program type n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tp = atoi(argv[1]);
|
||||
n = atoi(argv[2]);
|
||||
|
||||
gen(tp, n);
|
||||
FFTW_CLEANUP();
|
||||
|
||||
return 0;
|
||||
}
|
BIN
venv/Lib/site-packages/scipy/fftpack/tests/fftw_double_ref.npz
Normal file
BIN
venv/Lib/site-packages/scipy/fftpack/tests/fftw_double_ref.npz
Normal file
Binary file not shown.
Binary file not shown.
BIN
venv/Lib/site-packages/scipy/fftpack/tests/fftw_single_ref.npz
Normal file
BIN
venv/Lib/site-packages/scipy/fftpack/tests/fftw_single_ref.npz
Normal file
Binary file not shown.
74
venv/Lib/site-packages/scipy/fftpack/tests/gen_fftw_ref.py
Normal file
74
venv/Lib/site-packages/scipy/fftpack/tests/gen_fftw_ref.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import numpy as np
|
||||
|
||||
SZ = [2, 3, 4, 8, 12, 15, 16, 17, 32, 64, 128, 256, 512, 1024]
|
||||
|
||||
|
||||
def gen_data(dt):
|
||||
arrays = {}
|
||||
|
||||
if dt == np.float128:
|
||||
pg = './fftw_longdouble'
|
||||
elif dt == np.double:
|
||||
pg = './fftw_double'
|
||||
elif dt == np.float32:
|
||||
pg = './fftw_single'
|
||||
else:
|
||||
raise ValueError("unknown: %s" % dt)
|
||||
# Generate test data using FFTW for reference
|
||||
for type in [1, 2, 3, 4, 5, 6, 7, 8]:
|
||||
arrays[type] = {}
|
||||
for sz in SZ:
|
||||
a = Popen([pg, str(type), str(sz)], stdout=PIPE, stderr=STDOUT)
|
||||
st = [i.decode('ascii').strip() for i in a.stdout.readlines()]
|
||||
arrays[type][sz] = np.fromstring(",".join(st), sep=',', dtype=dt)
|
||||
|
||||
return arrays
|
||||
|
||||
|
||||
# generate single precision data
|
||||
data = gen_data(np.float32)
|
||||
filename = 'fftw_single_ref'
|
||||
# Save ref data into npz format
|
||||
d = {'sizes': SZ}
|
||||
for type in [1, 2, 3, 4]:
|
||||
for sz in SZ:
|
||||
d['dct_%d_%d' % (type, sz)] = data[type][sz]
|
||||
|
||||
d['sizes'] = SZ
|
||||
for type in [5, 6, 7, 8]:
|
||||
for sz in SZ:
|
||||
d['dst_%d_%d' % (type-4, sz)] = data[type][sz]
|
||||
np.savez(filename, **d)
|
||||
|
||||
|
||||
# generate double precision data
|
||||
data = gen_data(np.float64)
|
||||
filename = 'fftw_double_ref'
|
||||
# Save ref data into npz format
|
||||
d = {'sizes': SZ}
|
||||
for type in [1, 2, 3, 4]:
|
||||
for sz in SZ:
|
||||
d['dct_%d_%d' % (type, sz)] = data[type][sz]
|
||||
|
||||
d['sizes'] = SZ
|
||||
for type in [5, 6, 7, 8]:
|
||||
for sz in SZ:
|
||||
d['dst_%d_%d' % (type-4, sz)] = data[type][sz]
|
||||
np.savez(filename, **d)
|
||||
|
||||
# generate long double precision data
|
||||
data = gen_data(np.float128)
|
||||
filename = 'fftw_longdouble_ref'
|
||||
# Save ref data into npz format
|
||||
d = {'sizes': SZ}
|
||||
for type in [1, 2, 3, 4]:
|
||||
for sz in SZ:
|
||||
d['dct_%d_%d' % (type, sz)] = data[type][sz]
|
||||
|
||||
d['sizes'] = SZ
|
||||
for type in [5, 6, 7, 8]:
|
||||
for sz in SZ:
|
||||
d['dst_%d_%d' % (type-4, sz)] = data[type][sz]
|
||||
np.savez(filename, **d)
|
21
venv/Lib/site-packages/scipy/fftpack/tests/gendata.m
Normal file
21
venv/Lib/site-packages/scipy/fftpack/tests/gendata.m
Normal file
|
@ -0,0 +1,21 @@
|
|||
x0 = linspace(0, 10, 11);
|
||||
x1 = linspace(0, 10, 15);
|
||||
x2 = linspace(0, 10, 16);
|
||||
x3 = linspace(0, 10, 17);
|
||||
|
||||
x4 = randn(32, 1);
|
||||
x5 = randn(64, 1);
|
||||
x6 = randn(128, 1);
|
||||
x7 = randn(256, 1);
|
||||
|
||||
y0 = dct(x0);
|
||||
y1 = dct(x1);
|
||||
y2 = dct(x2);
|
||||
y3 = dct(x3);
|
||||
y4 = dct(x4);
|
||||
y5 = dct(x5);
|
||||
y6 = dct(x6);
|
||||
y7 = dct(x7);
|
||||
|
||||
save('test.mat', 'x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', ...
|
||||
'y0', 'y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'y7');
|
6
venv/Lib/site-packages/scipy/fftpack/tests/gendata.py
Normal file
6
venv/Lib/site-packages/scipy/fftpack/tests/gendata.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import numpy as np
|
||||
from scipy.io import loadmat
|
||||
|
||||
m = loadmat('test.mat', squeeze_me=True, struct_as_record=True,
|
||||
mat_dtype=True)
|
||||
np.savez('test.npz', **m)
|
BIN
venv/Lib/site-packages/scipy/fftpack/tests/test.npz
Normal file
BIN
venv/Lib/site-packages/scipy/fftpack/tests/test.npz
Normal file
Binary file not shown.
858
venv/Lib/site-packages/scipy/fftpack/tests/test_basic.py
Normal file
858
venv/Lib/site-packages/scipy/fftpack/tests/test_basic.py
Normal file
|
@ -0,0 +1,858 @@
|
|||
# Created by Pearu Peterson, September 2002
|
||||
|
||||
from numpy.testing import (assert_, assert_equal, assert_array_almost_equal,
|
||||
assert_array_almost_equal_nulp, assert_array_less)
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
from scipy.fftpack import ifft, fft, fftn, ifftn, rfft, irfft, fft2
|
||||
|
||||
from numpy import (arange, add, array, asarray, zeros, dot, exp, pi,
|
||||
swapaxes, double, cdouble)
|
||||
import numpy as np
|
||||
import numpy.fft
|
||||
from numpy.random import rand
|
||||
|
||||
# "large" composite numbers supported by FFTPACK
|
||||
LARGE_COMPOSITE_SIZES = [
|
||||
2**13,
|
||||
2**5 * 3**5,
|
||||
2**3 * 3**3 * 5**2,
|
||||
]
|
||||
SMALL_COMPOSITE_SIZES = [
|
||||
2,
|
||||
2*3*5,
|
||||
2*2*3*3,
|
||||
]
|
||||
# prime
|
||||
LARGE_PRIME_SIZES = [
|
||||
2011
|
||||
]
|
||||
SMALL_PRIME_SIZES = [
|
||||
29
|
||||
]
|
||||
|
||||
|
||||
def _assert_close_in_norm(x, y, rtol, size, rdt):
|
||||
# helper function for testing
|
||||
err_msg = "size: %s rdt: %s" % (size, rdt)
|
||||
assert_array_less(np.linalg.norm(x - y), rtol*np.linalg.norm(x), err_msg)
|
||||
|
||||
|
||||
def random(size):
|
||||
return rand(*size)
|
||||
|
||||
|
||||
def get_mat(n):
|
||||
data = arange(n)
|
||||
data = add.outer(data, data)
|
||||
return data
|
||||
|
||||
|
||||
def direct_dft(x):
|
||||
x = asarray(x)
|
||||
n = len(x)
|
||||
y = zeros(n, dtype=cdouble)
|
||||
w = -arange(n)*(2j*pi/n)
|
||||
for i in range(n):
|
||||
y[i] = dot(exp(i*w), x)
|
||||
return y
|
||||
|
||||
|
||||
def direct_idft(x):
|
||||
x = asarray(x)
|
||||
n = len(x)
|
||||
y = zeros(n, dtype=cdouble)
|
||||
w = arange(n)*(2j*pi/n)
|
||||
for i in range(n):
|
||||
y[i] = dot(exp(i*w), x)/n
|
||||
return y
|
||||
|
||||
|
||||
def direct_dftn(x):
|
||||
x = asarray(x)
|
||||
for axis in range(len(x.shape)):
|
||||
x = fft(x, axis=axis)
|
||||
return x
|
||||
|
||||
|
||||
def direct_idftn(x):
|
||||
x = asarray(x)
|
||||
for axis in range(len(x.shape)):
|
||||
x = ifft(x, axis=axis)
|
||||
return x
|
||||
|
||||
|
||||
def direct_rdft(x):
|
||||
x = asarray(x)
|
||||
n = len(x)
|
||||
w = -arange(n)*(2j*pi/n)
|
||||
r = zeros(n, dtype=double)
|
||||
for i in range(n//2+1):
|
||||
y = dot(exp(i*w), x)
|
||||
if i:
|
||||
r[2*i-1] = y.real
|
||||
if 2*i < n:
|
||||
r[2*i] = y.imag
|
||||
else:
|
||||
r[0] = y.real
|
||||
return r
|
||||
|
||||
|
||||
def direct_irdft(x):
|
||||
x = asarray(x)
|
||||
n = len(x)
|
||||
x1 = zeros(n, dtype=cdouble)
|
||||
for i in range(n//2+1):
|
||||
if i:
|
||||
if 2*i < n:
|
||||
x1[i] = x[2*i-1] + 1j*x[2*i]
|
||||
x1[n-i] = x[2*i-1] - 1j*x[2*i]
|
||||
else:
|
||||
x1[i] = x[2*i-1]
|
||||
else:
|
||||
x1[0] = x[0]
|
||||
return direct_idft(x1).real
|
||||
|
||||
|
||||
class _TestFFTBase(object):
|
||||
def setup_method(self):
|
||||
self.cdt = None
|
||||
self.rdt = None
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_definition(self):
|
||||
x = np.array([1,2,3,4+1j,1,2,3,4+2j], dtype=self.cdt)
|
||||
y = fft(x)
|
||||
assert_equal(y.dtype, self.cdt)
|
||||
y1 = direct_dft(x)
|
||||
assert_array_almost_equal(y,y1)
|
||||
x = np.array([1,2,3,4+0j,5], dtype=self.cdt)
|
||||
assert_array_almost_equal(fft(x),direct_dft(x))
|
||||
|
||||
def test_n_argument_real(self):
|
||||
x1 = np.array([1,2,3,4], dtype=self.rdt)
|
||||
x2 = np.array([1,2,3,4], dtype=self.rdt)
|
||||
y = fft([x1,x2],n=4)
|
||||
assert_equal(y.dtype, self.cdt)
|
||||
assert_equal(y.shape,(2,4))
|
||||
assert_array_almost_equal(y[0],direct_dft(x1))
|
||||
assert_array_almost_equal(y[1],direct_dft(x2))
|
||||
|
||||
def _test_n_argument_complex(self):
|
||||
x1 = np.array([1,2,3,4+1j], dtype=self.cdt)
|
||||
x2 = np.array([1,2,3,4+1j], dtype=self.cdt)
|
||||
y = fft([x1,x2],n=4)
|
||||
assert_equal(y.dtype, self.cdt)
|
||||
assert_equal(y.shape,(2,4))
|
||||
assert_array_almost_equal(y[0],direct_dft(x1))
|
||||
assert_array_almost_equal(y[1],direct_dft(x2))
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
assert_raises(ValueError, fft, [])
|
||||
assert_raises(ValueError, fft, [[1,1],[2,2]], -5)
|
||||
|
||||
|
||||
class TestDoubleFFT(_TestFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.cdouble
|
||||
self.rdt = np.double
|
||||
|
||||
|
||||
class TestSingleFFT(_TestFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.complex64
|
||||
self.rdt = np.float32
|
||||
|
||||
@pytest.mark.xfail(run=False, reason="single-precision FFT implementation is partially disabled, until accuracy issues with large prime powers are resolved")
|
||||
def test_notice(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestFloat16FFT(object):
|
||||
|
||||
def test_1_argument_real(self):
|
||||
x1 = np.array([1, 2, 3, 4], dtype=np.float16)
|
||||
y = fft(x1, n=4)
|
||||
assert_equal(y.dtype, np.complex64)
|
||||
assert_equal(y.shape, (4, ))
|
||||
assert_array_almost_equal(y, direct_dft(x1.astype(np.float32)))
|
||||
|
||||
def test_n_argument_real(self):
|
||||
x1 = np.array([1, 2, 3, 4], dtype=np.float16)
|
||||
x2 = np.array([1, 2, 3, 4], dtype=np.float16)
|
||||
y = fft([x1, x2], n=4)
|
||||
assert_equal(y.dtype, np.complex64)
|
||||
assert_equal(y.shape, (2, 4))
|
||||
assert_array_almost_equal(y[0], direct_dft(x1.astype(np.float32)))
|
||||
assert_array_almost_equal(y[1], direct_dft(x2.astype(np.float32)))
|
||||
|
||||
|
||||
class _TestIFFTBase(object):
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_definition(self):
|
||||
x = np.array([1,2,3,4+1j,1,2,3,4+2j], self.cdt)
|
||||
y = ifft(x)
|
||||
y1 = direct_idft(x)
|
||||
assert_equal(y.dtype, self.cdt)
|
||||
assert_array_almost_equal(y,y1)
|
||||
|
||||
x = np.array([1,2,3,4+0j,5], self.cdt)
|
||||
assert_array_almost_equal(ifft(x),direct_idft(x))
|
||||
|
||||
def test_definition_real(self):
|
||||
x = np.array([1,2,3,4,1,2,3,4], self.rdt)
|
||||
y = ifft(x)
|
||||
assert_equal(y.dtype, self.cdt)
|
||||
y1 = direct_idft(x)
|
||||
assert_array_almost_equal(y,y1)
|
||||
|
||||
x = np.array([1,2,3,4,5], dtype=self.rdt)
|
||||
assert_equal(y.dtype, self.cdt)
|
||||
assert_array_almost_equal(ifft(x),direct_idft(x))
|
||||
|
||||
def test_random_complex(self):
|
||||
for size in [1,51,111,100,200,64,128,256,1024]:
|
||||
x = random([size]).astype(self.cdt)
|
||||
x = random([size]).astype(self.cdt) + 1j*x
|
||||
y1 = ifft(fft(x))
|
||||
y2 = fft(ifft(x))
|
||||
assert_equal(y1.dtype, self.cdt)
|
||||
assert_equal(y2.dtype, self.cdt)
|
||||
assert_array_almost_equal(y1, x)
|
||||
assert_array_almost_equal(y2, x)
|
||||
|
||||
def test_random_real(self):
|
||||
for size in [1,51,111,100,200,64,128,256,1024]:
|
||||
x = random([size]).astype(self.rdt)
|
||||
y1 = ifft(fft(x))
|
||||
y2 = fft(ifft(x))
|
||||
assert_equal(y1.dtype, self.cdt)
|
||||
assert_equal(y2.dtype, self.cdt)
|
||||
assert_array_almost_equal(y1, x)
|
||||
assert_array_almost_equal(y2, x)
|
||||
|
||||
def test_size_accuracy(self):
|
||||
# Sanity check for the accuracy for prime and non-prime sized inputs
|
||||
if self.rdt == np.float32:
|
||||
rtol = 1e-5
|
||||
elif self.rdt == np.float64:
|
||||
rtol = 1e-10
|
||||
|
||||
for size in LARGE_COMPOSITE_SIZES + LARGE_PRIME_SIZES:
|
||||
np.random.seed(1234)
|
||||
x = np.random.rand(size).astype(self.rdt)
|
||||
y = ifft(fft(x))
|
||||
_assert_close_in_norm(x, y, rtol, size, self.rdt)
|
||||
y = fft(ifft(x))
|
||||
_assert_close_in_norm(x, y, rtol, size, self.rdt)
|
||||
|
||||
x = (x + 1j*np.random.rand(size)).astype(self.cdt)
|
||||
y = ifft(fft(x))
|
||||
_assert_close_in_norm(x, y, rtol, size, self.rdt)
|
||||
y = fft(ifft(x))
|
||||
_assert_close_in_norm(x, y, rtol, size, self.rdt)
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
assert_raises(ValueError, ifft, [])
|
||||
assert_raises(ValueError, ifft, [[1,1],[2,2]], -5)
|
||||
|
||||
|
||||
class TestDoubleIFFT(_TestIFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.cdouble
|
||||
self.rdt = np.double
|
||||
|
||||
|
||||
class TestSingleIFFT(_TestIFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.complex64
|
||||
self.rdt = np.float32
|
||||
|
||||
|
||||
class _TestRFFTBase(object):
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_definition(self):
|
||||
for t in [[1, 2, 3, 4, 1, 2, 3, 4], [1, 2, 3, 4, 1, 2, 3, 4, 5]]:
|
||||
x = np.array(t, dtype=self.rdt)
|
||||
y = rfft(x)
|
||||
y1 = direct_rdft(x)
|
||||
assert_array_almost_equal(y,y1)
|
||||
assert_equal(y.dtype, self.rdt)
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
assert_raises(ValueError, rfft, [])
|
||||
assert_raises(ValueError, rfft, [[1,1],[2,2]], -5)
|
||||
|
||||
# See gh-5790
|
||||
class MockSeries(object):
|
||||
def __init__(self, data):
|
||||
self.data = np.asarray(data)
|
||||
|
||||
def __getattr__(self, item):
|
||||
try:
|
||||
return getattr(self.data, item)
|
||||
except AttributeError:
|
||||
raise AttributeError(("'MockSeries' object "
|
||||
"has no attribute '{attr}'".
|
||||
format(attr=item)))
|
||||
|
||||
def test_non_ndarray_with_dtype(self):
|
||||
x = np.array([1., 2., 3., 4., 5.])
|
||||
xs = _TestRFFTBase.MockSeries(x)
|
||||
|
||||
expected = [1, 2, 3, 4, 5]
|
||||
rfft(xs)
|
||||
|
||||
# Data should not have been overwritten
|
||||
assert_equal(x, expected)
|
||||
assert_equal(xs.data, expected)
|
||||
|
||||
def test_complex_input(self):
|
||||
assert_raises(TypeError, rfft, np.arange(4, dtype=np.complex64))
|
||||
|
||||
|
||||
class TestRFFTDouble(_TestRFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.cdouble
|
||||
self.rdt = np.double
|
||||
|
||||
|
||||
class TestRFFTSingle(_TestRFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.complex64
|
||||
self.rdt = np.float32
|
||||
|
||||
|
||||
class _TestIRFFTBase(object):
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_definition(self):
|
||||
x1 = [1,2,3,4,1,2,3,4]
|
||||
x1_1 = [1,2+3j,4+1j,2+3j,4,2-3j,4-1j,2-3j]
|
||||
x2 = [1,2,3,4,1,2,3,4,5]
|
||||
x2_1 = [1,2+3j,4+1j,2+3j,4+5j,4-5j,2-3j,4-1j,2-3j]
|
||||
|
||||
def _test(x, xr):
|
||||
y = irfft(np.array(x, dtype=self.rdt))
|
||||
y1 = direct_irdft(x)
|
||||
assert_equal(y.dtype, self.rdt)
|
||||
assert_array_almost_equal(y,y1, decimal=self.ndec)
|
||||
assert_array_almost_equal(y,ifft(xr), decimal=self.ndec)
|
||||
|
||||
_test(x1, x1_1)
|
||||
_test(x2, x2_1)
|
||||
|
||||
def test_random_real(self):
|
||||
for size in [1,51,111,100,200,64,128,256,1024]:
|
||||
x = random([size]).astype(self.rdt)
|
||||
y1 = irfft(rfft(x))
|
||||
y2 = rfft(irfft(x))
|
||||
assert_equal(y1.dtype, self.rdt)
|
||||
assert_equal(y2.dtype, self.rdt)
|
||||
assert_array_almost_equal(y1, x, decimal=self.ndec,
|
||||
err_msg="size=%d" % size)
|
||||
assert_array_almost_equal(y2, x, decimal=self.ndec,
|
||||
err_msg="size=%d" % size)
|
||||
|
||||
def test_size_accuracy(self):
|
||||
# Sanity check for the accuracy for prime and non-prime sized inputs
|
||||
if self.rdt == np.float32:
|
||||
rtol = 1e-5
|
||||
elif self.rdt == np.float64:
|
||||
rtol = 1e-10
|
||||
|
||||
for size in LARGE_COMPOSITE_SIZES + LARGE_PRIME_SIZES:
|
||||
np.random.seed(1234)
|
||||
x = np.random.rand(size).astype(self.rdt)
|
||||
y = irfft(rfft(x))
|
||||
_assert_close_in_norm(x, y, rtol, size, self.rdt)
|
||||
y = rfft(irfft(x))
|
||||
_assert_close_in_norm(x, y, rtol, size, self.rdt)
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
assert_raises(ValueError, irfft, [])
|
||||
assert_raises(ValueError, irfft, [[1,1],[2,2]], -5)
|
||||
|
||||
def test_complex_input(self):
|
||||
assert_raises(TypeError, irfft, np.arange(4, dtype=np.complex64))
|
||||
|
||||
|
||||
# self.ndec is bogus; we should have a assert_array_approx_equal for number of
|
||||
# significant digits
|
||||
|
||||
class TestIRFFTDouble(_TestIRFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.cdouble
|
||||
self.rdt = np.double
|
||||
self.ndec = 14
|
||||
|
||||
|
||||
class TestIRFFTSingle(_TestIRFFTBase):
|
||||
def setup_method(self):
|
||||
self.cdt = np.complex64
|
||||
self.rdt = np.float32
|
||||
self.ndec = 5
|
||||
|
||||
|
||||
class Testfft2(object):
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_regression_244(self):
|
||||
"""FFT returns wrong result with axes parameter."""
|
||||
# fftn (and hence fft2) used to break when both axes and shape were
|
||||
# used
|
||||
x = numpy.ones((4, 4, 2))
|
||||
y = fft2(x, shape=(8, 8), axes=(-3, -2))
|
||||
y_r = numpy.fft.fftn(x, s=(8, 8), axes=(-3, -2))
|
||||
assert_array_almost_equal(y, y_r)
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
assert_raises(ValueError, fft2, [[]])
|
||||
assert_raises(ValueError, fft2, [[1, 1], [2, 2]], (4, -3))
|
||||
|
||||
|
||||
class TestFftnSingle(object):
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_definition(self):
|
||||
x = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]]
|
||||
y = fftn(np.array(x, np.float32))
|
||||
assert_(y.dtype == np.complex64,
|
||||
msg="double precision output with single precision")
|
||||
|
||||
y_r = np.array(fftn(x), np.complex64)
|
||||
assert_array_almost_equal_nulp(y, y_r)
|
||||
|
||||
@pytest.mark.parametrize('size', SMALL_COMPOSITE_SIZES + SMALL_PRIME_SIZES)
|
||||
def test_size_accuracy_small(self, size):
|
||||
x = np.random.rand(size, size) + 1j*np.random.rand(size, size)
|
||||
y1 = fftn(x.real.astype(np.float32))
|
||||
y2 = fftn(x.real.astype(np.float64)).astype(np.complex64)
|
||||
|
||||
assert_equal(y1.dtype, np.complex64)
|
||||
assert_array_almost_equal_nulp(y1, y2, 2000)
|
||||
|
||||
@pytest.mark.parametrize('size', LARGE_COMPOSITE_SIZES + LARGE_PRIME_SIZES)
|
||||
def test_size_accuracy_large(self, size):
|
||||
x = np.random.rand(size, 3) + 1j*np.random.rand(size, 3)
|
||||
y1 = fftn(x.real.astype(np.float32))
|
||||
y2 = fftn(x.real.astype(np.float64)).astype(np.complex64)
|
||||
|
||||
assert_equal(y1.dtype, np.complex64)
|
||||
assert_array_almost_equal_nulp(y1, y2, 2000)
|
||||
|
||||
def test_definition_float16(self):
|
||||
x = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]]
|
||||
y = fftn(np.array(x, np.float16))
|
||||
assert_equal(y.dtype, np.complex64)
|
||||
y_r = np.array(fftn(x), np.complex64)
|
||||
assert_array_almost_equal_nulp(y, y_r)
|
||||
|
||||
@pytest.mark.parametrize('size', SMALL_COMPOSITE_SIZES + SMALL_PRIME_SIZES)
|
||||
def test_float16_input_small(self, size):
|
||||
x = np.random.rand(size, size) + 1j*np.random.rand(size, size)
|
||||
y1 = fftn(x.real.astype(np.float16))
|
||||
y2 = fftn(x.real.astype(np.float64)).astype(np.complex64)
|
||||
|
||||
assert_equal(y1.dtype, np.complex64)
|
||||
assert_array_almost_equal_nulp(y1, y2, 5e5)
|
||||
|
||||
@pytest.mark.parametrize('size', LARGE_COMPOSITE_SIZES + LARGE_PRIME_SIZES)
|
||||
def test_float16_input_large(self, size):
|
||||
x = np.random.rand(size, 3) + 1j*np.random.rand(size, 3)
|
||||
y1 = fftn(x.real.astype(np.float16))
|
||||
y2 = fftn(x.real.astype(np.float64)).astype(np.complex64)
|
||||
|
||||
assert_equal(y1.dtype, np.complex64)
|
||||
assert_array_almost_equal_nulp(y1, y2, 2e6)
|
||||
|
||||
|
||||
class TestFftn(object):
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
def test_definition(self):
|
||||
x = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]]
|
||||
y = fftn(x)
|
||||
assert_array_almost_equal(y, direct_dftn(x))
|
||||
|
||||
x = random((20, 26))
|
||||
assert_array_almost_equal(fftn(x), direct_dftn(x))
|
||||
|
||||
x = random((5, 4, 3, 20))
|
||||
assert_array_almost_equal(fftn(x), direct_dftn(x))
|
||||
|
||||
def test_axes_argument(self):
|
||||
# plane == ji_plane, x== kji_space
|
||||
plane1 = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]]
|
||||
plane2 = [[10, 11, 12],
|
||||
[13, 14, 15],
|
||||
[16, 17, 18]]
|
||||
plane3 = [[19, 20, 21],
|
||||
[22, 23, 24],
|
||||
[25, 26, 27]]
|
||||
ki_plane1 = [[1, 2, 3],
|
||||
[10, 11, 12],
|
||||
[19, 20, 21]]
|
||||
ki_plane2 = [[4, 5, 6],
|
||||
[13, 14, 15],
|
||||
[22, 23, 24]]
|
||||
ki_plane3 = [[7, 8, 9],
|
||||
[16, 17, 18],
|
||||
[25, 26, 27]]
|
||||
jk_plane1 = [[1, 10, 19],
|
||||
[4, 13, 22],
|
||||
[7, 16, 25]]
|
||||
jk_plane2 = [[2, 11, 20],
|
||||
[5, 14, 23],
|
||||
[8, 17, 26]]
|
||||
jk_plane3 = [[3, 12, 21],
|
||||
[6, 15, 24],
|
||||
[9, 18, 27]]
|
||||
kj_plane1 = [[1, 4, 7],
|
||||
[10, 13, 16], [19, 22, 25]]
|
||||
kj_plane2 = [[2, 5, 8],
|
||||
[11, 14, 17], [20, 23, 26]]
|
||||
kj_plane3 = [[3, 6, 9],
|
||||
[12, 15, 18], [21, 24, 27]]
|
||||
ij_plane1 = [[1, 4, 7],
|
||||
[2, 5, 8],
|
||||
[3, 6, 9]]
|
||||
ij_plane2 = [[10, 13, 16],
|
||||
[11, 14, 17],
|
||||
[12, 15, 18]]
|
||||
ij_plane3 = [[19, 22, 25],
|
||||
[20, 23, 26],
|
||||
[21, 24, 27]]
|
||||
ik_plane1 = [[1, 10, 19],
|
||||
[2, 11, 20],
|
||||
[3, 12, 21]]
|
||||
ik_plane2 = [[4, 13, 22],
|
||||
[5, 14, 23],
|
||||
[6, 15, 24]]
|
||||
ik_plane3 = [[7, 16, 25],
|
||||
[8, 17, 26],
|
||||
[9, 18, 27]]
|
||||
ijk_space = [jk_plane1, jk_plane2, jk_plane3]
|
||||
ikj_space = [kj_plane1, kj_plane2, kj_plane3]
|
||||
jik_space = [ik_plane1, ik_plane2, ik_plane3]
|
||||
jki_space = [ki_plane1, ki_plane2, ki_plane3]
|
||||
kij_space = [ij_plane1, ij_plane2, ij_plane3]
|
||||
x = array([plane1, plane2, plane3])
|
||||
|
||||
assert_array_almost_equal(fftn(x),
|
||||
fftn(x, axes=(-3, -2, -1))) # kji_space
|
||||
assert_array_almost_equal(fftn(x), fftn(x, axes=(0, 1, 2)))
|
||||
assert_array_almost_equal(fftn(x, axes=(0, 2)), fftn(x, axes=(0, -1)))
|
||||
y = fftn(x, axes=(2, 1, 0)) # ijk_space
|
||||
assert_array_almost_equal(swapaxes(y, -1, -3), fftn(ijk_space))
|
||||
y = fftn(x, axes=(2, 0, 1)) # ikj_space
|
||||
assert_array_almost_equal(swapaxes(swapaxes(y, -1, -3), -1, -2),
|
||||
fftn(ikj_space))
|
||||
y = fftn(x, axes=(1, 2, 0)) # jik_space
|
||||
assert_array_almost_equal(swapaxes(swapaxes(y, -1, -3), -3, -2),
|
||||
fftn(jik_space))
|
||||
y = fftn(x, axes=(1, 0, 2)) # jki_space
|
||||
assert_array_almost_equal(swapaxes(y, -2, -3), fftn(jki_space))
|
||||
y = fftn(x, axes=(0, 2, 1)) # kij_space
|
||||
assert_array_almost_equal(swapaxes(y, -2, -1), fftn(kij_space))
|
||||
|
||||
y = fftn(x, axes=(-2, -1)) # ji_plane
|
||||
assert_array_almost_equal(fftn(plane1), y[0])
|
||||
assert_array_almost_equal(fftn(plane2), y[1])
|
||||
assert_array_almost_equal(fftn(plane3), y[2])
|
||||
|
||||
y = fftn(x, axes=(1, 2)) # ji_plane
|
||||
assert_array_almost_equal(fftn(plane1), y[0])
|
||||
assert_array_almost_equal(fftn(plane2), y[1])
|
||||
assert_array_almost_equal(fftn(plane3), y[2])
|
||||
|
||||
y = fftn(x, axes=(-3, -2)) # kj_plane
|
||||
assert_array_almost_equal(fftn(x[:, :, 0]), y[:, :, 0])
|
||||
assert_array_almost_equal(fftn(x[:, :, 1]), y[:, :, 1])
|
||||
assert_array_almost_equal(fftn(x[:, :, 2]), y[:, :, 2])
|
||||
|
||||
y = fftn(x, axes=(-3, -1)) # ki_plane
|
||||
assert_array_almost_equal(fftn(x[:, 0, :]), y[:, 0, :])
|
||||
assert_array_almost_equal(fftn(x[:, 1, :]), y[:, 1, :])
|
||||
assert_array_almost_equal(fftn(x[:, 2, :]), y[:, 2, :])
|
||||
|
||||
y = fftn(x, axes=(-1, -2)) # ij_plane
|
||||
assert_array_almost_equal(fftn(ij_plane1), swapaxes(y[0], -2, -1))
|
||||
assert_array_almost_equal(fftn(ij_plane2), swapaxes(y[1], -2, -1))
|
||||
assert_array_almost_equal(fftn(ij_plane3), swapaxes(y[2], -2, -1))
|
||||
|
||||
y = fftn(x, axes=(-1, -3)) # ik_plane
|
||||
assert_array_almost_equal(fftn(ik_plane1),
|
||||
swapaxes(y[:, 0, :], -1, -2))
|
||||
assert_array_almost_equal(fftn(ik_plane2),
|
||||
swapaxes(y[:, 1, :], -1, -2))
|
||||
assert_array_almost_equal(fftn(ik_plane3),
|
||||
swapaxes(y[:, 2, :], -1, -2))
|
||||
|
||||
y = fftn(x, axes=(-2, -3)) # jk_plane
|
||||
assert_array_almost_equal(fftn(jk_plane1),
|
||||
swapaxes(y[:, :, 0], -1, -2))
|
||||
assert_array_almost_equal(fftn(jk_plane2),
|
||||
swapaxes(y[:, :, 1], -1, -2))
|
||||
assert_array_almost_equal(fftn(jk_plane3),
|
||||
swapaxes(y[:, :, 2], -1, -2))
|
||||
|
||||
y = fftn(x, axes=(-1,)) # i_line
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
assert_array_almost_equal(fft(x[i, j, :]), y[i, j, :])
|
||||
y = fftn(x, axes=(-2,)) # j_line
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
assert_array_almost_equal(fft(x[i, :, j]), y[i, :, j])
|
||||
y = fftn(x, axes=(0,)) # k_line
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
assert_array_almost_equal(fft(x[:, i, j]), y[:, i, j])
|
||||
|
||||
y = fftn(x, axes=()) # point
|
||||
assert_array_almost_equal(y, x)
|
||||
|
||||
def test_shape_argument(self):
|
||||
small_x = [[1, 2, 3],
|
||||
[4, 5, 6]]
|
||||
large_x1 = [[1, 2, 3, 0],
|
||||
[4, 5, 6, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0]]
|
||||
|
||||
y = fftn(small_x, shape=(4, 4))
|
||||
assert_array_almost_equal(y, fftn(large_x1))
|
||||
|
||||
y = fftn(small_x, shape=(3, 4))
|
||||
assert_array_almost_equal(y, fftn(large_x1[:-1]))
|
||||
|
||||
def test_shape_axes_argument(self):
|
||||
small_x = [[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]]
|
||||
large_x1 = array([[1, 2, 3, 0],
|
||||
[4, 5, 6, 0],
|
||||
[7, 8, 9, 0],
|
||||
[0, 0, 0, 0]])
|
||||
y = fftn(small_x, shape=(4, 4), axes=(-2, -1))
|
||||
assert_array_almost_equal(y, fftn(large_x1))
|
||||
y = fftn(small_x, shape=(4, 4), axes=(-1, -2))
|
||||
|
||||
assert_array_almost_equal(y, swapaxes(
|
||||
fftn(swapaxes(large_x1, -1, -2)), -1, -2))
|
||||
|
||||
def test_shape_axes_argument2(self):
|
||||
# Change shape of the last axis
|
||||
x = numpy.random.random((10, 5, 3, 7))
|
||||
y = fftn(x, axes=(-1,), shape=(8,))
|
||||
assert_array_almost_equal(y, fft(x, axis=-1, n=8))
|
||||
|
||||
# Change shape of an arbitrary axis which is not the last one
|
||||
x = numpy.random.random((10, 5, 3, 7))
|
||||
y = fftn(x, axes=(-2,), shape=(8,))
|
||||
assert_array_almost_equal(y, fft(x, axis=-2, n=8))
|
||||
|
||||
# Change shape of axes: cf #244, where shape and axes were mixed up
|
||||
x = numpy.random.random((4, 4, 2))
|
||||
y = fftn(x, axes=(-3, -2), shape=(8, 8))
|
||||
assert_array_almost_equal(y,
|
||||
numpy.fft.fftn(x, axes=(-3, -2), s=(8, 8)))
|
||||
|
||||
def test_shape_argument_more(self):
|
||||
x = zeros((4, 4, 2))
|
||||
with assert_raises(ValueError,
|
||||
match="when given, axes and shape arguments"
|
||||
" have to be of the same length"):
|
||||
fftn(x, shape=(8, 8, 2, 1))
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
with assert_raises(ValueError,
|
||||
match="invalid number of data points"
|
||||
r" \(\[1, 0\]\) specified"):
|
||||
fftn([[]])
|
||||
|
||||
with assert_raises(ValueError,
|
||||
match="invalid number of data points"
|
||||
r" \(\[4, -3\]\) specified"):
|
||||
fftn([[1, 1], [2, 2]], (4, -3))
|
||||
|
||||
|
||||
class TestIfftn(object):
|
||||
dtype = None
|
||||
cdtype = None
|
||||
|
||||
def setup_method(self):
|
||||
np.random.seed(1234)
|
||||
|
||||
@pytest.mark.parametrize('dtype,cdtype,maxnlp',
|
||||
[(np.float64, np.complex128, 2000),
|
||||
(np.float32, np.complex64, 3500)])
|
||||
def test_definition(self, dtype, cdtype, maxnlp):
|
||||
x = np.array([[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]], dtype=dtype)
|
||||
y = ifftn(x)
|
||||
assert_equal(y.dtype, cdtype)
|
||||
assert_array_almost_equal_nulp(y, direct_idftn(x), maxnlp)
|
||||
|
||||
x = random((20, 26))
|
||||
assert_array_almost_equal_nulp(ifftn(x), direct_idftn(x), maxnlp)
|
||||
|
||||
x = random((5, 4, 3, 20))
|
||||
assert_array_almost_equal_nulp(ifftn(x), direct_idftn(x), maxnlp)
|
||||
|
||||
@pytest.mark.parametrize('maxnlp', [2000, 3500])
|
||||
@pytest.mark.parametrize('size', [1, 2, 51, 32, 64, 92])
|
||||
def test_random_complex(self, maxnlp, size):
|
||||
x = random([size, size]) + 1j*random([size, size])
|
||||
assert_array_almost_equal_nulp(ifftn(fftn(x)), x, maxnlp)
|
||||
assert_array_almost_equal_nulp(fftn(ifftn(x)), x, maxnlp)
|
||||
|
||||
def test_invalid_sizes(self):
|
||||
with assert_raises(ValueError,
|
||||
match="invalid number of data points"
|
||||
r" \(\[1, 0\]\) specified"):
|
||||
ifftn([[]])
|
||||
|
||||
with assert_raises(ValueError,
|
||||
match="invalid number of data points"
|
||||
r" \(\[4, -3\]\) specified"):
|
||||
ifftn([[1, 1], [2, 2]], (4, -3))
|
||||
|
||||
|
||||
class FakeArray(object):
|
||||
def __init__(self, data):
|
||||
self._data = data
|
||||
self.__array_interface__ = data.__array_interface__
|
||||
|
||||
|
||||
class FakeArray2(object):
|
||||
def __init__(self, data):
|
||||
self._data = data
|
||||
|
||||
def __array__(self):
|
||||
return self._data
|
||||
|
||||
|
||||
class TestOverwrite(object):
|
||||
"""Check input overwrite behavior of the FFT functions."""
|
||||
|
||||
real_dtypes = (np.float32, np.float64)
|
||||
dtypes = real_dtypes + (np.complex64, np.complex128)
|
||||
fftsizes = [8, 16, 32]
|
||||
|
||||
def _check(self, x, routine, fftsize, axis, overwrite_x):
|
||||
x2 = x.copy()
|
||||
for fake in [lambda x: x, FakeArray, FakeArray2]:
|
||||
routine(fake(x2), fftsize, axis, overwrite_x=overwrite_x)
|
||||
|
||||
sig = "%s(%s%r, %r, axis=%r, overwrite_x=%r)" % (
|
||||
routine.__name__, x.dtype, x.shape, fftsize, axis, overwrite_x)
|
||||
if not overwrite_x:
|
||||
assert_equal(x2, x, err_msg="spurious overwrite in %s" % sig)
|
||||
|
||||
def _check_1d(self, routine, dtype, shape, axis, overwritable_dtypes,
|
||||
fftsize, overwrite_x):
|
||||
np.random.seed(1234)
|
||||
if np.issubdtype(dtype, np.complexfloating):
|
||||
data = np.random.randn(*shape) + 1j*np.random.randn(*shape)
|
||||
else:
|
||||
data = np.random.randn(*shape)
|
||||
data = data.astype(dtype)
|
||||
|
||||
self._check(data, routine, fftsize, axis,
|
||||
overwrite_x=overwrite_x)
|
||||
|
||||
@pytest.mark.parametrize('dtype', dtypes)
|
||||
@pytest.mark.parametrize('fftsize', fftsizes)
|
||||
@pytest.mark.parametrize('overwrite_x', [True, False])
|
||||
@pytest.mark.parametrize('shape,axes', [((16,), -1),
|
||||
((16, 2), 0),
|
||||
((2, 16), 1)])
|
||||
def test_fft_ifft(self, dtype, fftsize, overwrite_x, shape, axes):
|
||||
overwritable = (np.complex128, np.complex64)
|
||||
self._check_1d(fft, dtype, shape, axes, overwritable,
|
||||
fftsize, overwrite_x)
|
||||
self._check_1d(ifft, dtype, shape, axes, overwritable,
|
||||
fftsize, overwrite_x)
|
||||
|
||||
@pytest.mark.parametrize('dtype', real_dtypes)
|
||||
@pytest.mark.parametrize('fftsize', fftsizes)
|
||||
@pytest.mark.parametrize('overwrite_x', [True, False])
|
||||
@pytest.mark.parametrize('shape,axes', [((16,), -1),
|
||||
((16, 2), 0),
|
||||
((2, 16), 1)])
|
||||
def test_rfft_irfft(self, dtype, fftsize, overwrite_x, shape, axes):
|
||||
overwritable = self.real_dtypes
|
||||
self._check_1d(irfft, dtype, shape, axes, overwritable,
|
||||
fftsize, overwrite_x)
|
||||
self._check_1d(rfft, dtype, shape, axes, overwritable,
|
||||
fftsize, overwrite_x)
|
||||
|
||||
def _check_nd_one(self, routine, dtype, shape, axes, overwritable_dtypes,
|
||||
overwrite_x):
|
||||
np.random.seed(1234)
|
||||
if np.issubdtype(dtype, np.complexfloating):
|
||||
data = np.random.randn(*shape) + 1j*np.random.randn(*shape)
|
||||
else:
|
||||
data = np.random.randn(*shape)
|
||||
data = data.astype(dtype)
|
||||
|
||||
def fftshape_iter(shp):
|
||||
if len(shp) <= 0:
|
||||
yield ()
|
||||
else:
|
||||
for j in (shp[0]//2, shp[0], shp[0]*2):
|
||||
for rest in fftshape_iter(shp[1:]):
|
||||
yield (j,) + rest
|
||||
|
||||
if axes is None:
|
||||
part_shape = shape
|
||||
else:
|
||||
part_shape = tuple(np.take(shape, axes))
|
||||
|
||||
for fftshape in fftshape_iter(part_shape):
|
||||
self._check(data, routine, fftshape, axes,
|
||||
overwrite_x=overwrite_x)
|
||||
if data.ndim > 1:
|
||||
self._check(data.T, routine, fftshape, axes,
|
||||
overwrite_x=overwrite_x)
|
||||
|
||||
@pytest.mark.parametrize('dtype', dtypes)
|
||||
@pytest.mark.parametrize('overwrite_x', [True, False])
|
||||
@pytest.mark.parametrize('shape,axes', [((16,), None),
|
||||
((16,), (0,)),
|
||||
((16, 2), (0,)),
|
||||
((2, 16), (1,)),
|
||||
((8, 16), None),
|
||||
((8, 16), (0, 1)),
|
||||
((8, 16, 2), (0, 1)),
|
||||
((8, 16, 2), (1, 2)),
|
||||
((8, 16, 2), (0,)),
|
||||
((8, 16, 2), (1,)),
|
||||
((8, 16, 2), (2,)),
|
||||
((8, 16, 2), None),
|
||||
((8, 16, 2), (0, 1, 2))])
|
||||
def test_fftn_ifftn(self, dtype, overwrite_x, shape, axes):
|
||||
overwritable = (np.complex128, np.complex64)
|
||||
self._check_nd_one(fftn, dtype, shape, axes, overwritable,
|
||||
overwrite_x)
|
||||
self._check_nd_one(ifftn, dtype, shape, axes, overwritable,
|
||||
overwrite_x)
|
54
venv/Lib/site-packages/scipy/fftpack/tests/test_helper.py
Normal file
54
venv/Lib/site-packages/scipy/fftpack/tests/test_helper.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Created by Pearu Peterson, September 2002
|
||||
|
||||
__usage__ = """
|
||||
Build fftpack:
|
||||
python setup_fftpack.py build
|
||||
Run tests if scipy is installed:
|
||||
python -c 'import scipy;scipy.fftpack.test(<level>)'
|
||||
Run tests if fftpack is not installed:
|
||||
python tests/test_helper.py [<level>]
|
||||
"""
|
||||
|
||||
from numpy.testing import assert_array_almost_equal
|
||||
from scipy.fftpack import fftshift, ifftshift, fftfreq, rfftfreq
|
||||
|
||||
from numpy import pi, random
|
||||
|
||||
class TestFFTShift(object):
|
||||
|
||||
def test_definition(self):
|
||||
x = [0,1,2,3,4,-4,-3,-2,-1]
|
||||
y = [-4,-3,-2,-1,0,1,2,3,4]
|
||||
assert_array_almost_equal(fftshift(x),y)
|
||||
assert_array_almost_equal(ifftshift(y),x)
|
||||
x = [0,1,2,3,4,-5,-4,-3,-2,-1]
|
||||
y = [-5,-4,-3,-2,-1,0,1,2,3,4]
|
||||
assert_array_almost_equal(fftshift(x),y)
|
||||
assert_array_almost_equal(ifftshift(y),x)
|
||||
|
||||
def test_inverse(self):
|
||||
for n in [1,4,9,100,211]:
|
||||
x = random.random((n,))
|
||||
assert_array_almost_equal(ifftshift(fftshift(x)),x)
|
||||
|
||||
|
||||
class TestFFTFreq(object):
|
||||
|
||||
def test_definition(self):
|
||||
x = [0,1,2,3,4,-4,-3,-2,-1]
|
||||
assert_array_almost_equal(9*fftfreq(9),x)
|
||||
assert_array_almost_equal(9*pi*fftfreq(9,pi),x)
|
||||
x = [0,1,2,3,4,-5,-4,-3,-2,-1]
|
||||
assert_array_almost_equal(10*fftfreq(10),x)
|
||||
assert_array_almost_equal(10*pi*fftfreq(10,pi),x)
|
||||
|
||||
|
||||
class TestRFFTFreq(object):
|
||||
|
||||
def test_definition(self):
|
||||
x = [0,1,1,2,2,3,3,4,4]
|
||||
assert_array_almost_equal(9*rfftfreq(9),x)
|
||||
assert_array_almost_equal(9*pi*rfftfreq(9,pi),x)
|
||||
x = [0,1,1,2,2,3,3,4,4,5]
|
||||
assert_array_almost_equal(10*rfftfreq(10),x)
|
||||
assert_array_almost_equal(10*pi*rfftfreq(10,pi),x)
|
31
venv/Lib/site-packages/scipy/fftpack/tests/test_import.py
Normal file
31
venv/Lib/site-packages/scipy/fftpack/tests/test_import.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
"""Test possibility of patching fftpack with pyfftw.
|
||||
|
||||
No module source outside of scipy.fftpack should contain an import of
|
||||
the form `from scipy.fftpack import ...`, so that a simple replacement
|
||||
of scipy.fftpack by the corresponding fftw interface completely swaps
|
||||
the two FFT implementations.
|
||||
|
||||
Because this simply inspects source files, we only need to run the test
|
||||
on one version of Python.
|
||||
"""
|
||||
|
||||
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tokenize
|
||||
from numpy.testing import assert_
|
||||
import scipy
|
||||
|
||||
class TestFFTPackImport(object):
|
||||
def test_fftpack_import(self):
|
||||
base = Path(scipy.__file__).parent
|
||||
regexp = r"\s*from.+\.fftpack import .*\n"
|
||||
for path in base.rglob("*.py"):
|
||||
if base / "fftpack" in path.parents:
|
||||
continue
|
||||
# use tokenize to auto-detect encoding on systems where no
|
||||
# default encoding is defined (e.g., LANG='C')
|
||||
with tokenize.open(str(path)) as file:
|
||||
assert_(all(not re.fullmatch(regexp, line)
|
||||
for line in file),
|
||||
"{0} contains an import from fftpack".format(path))
|
380
venv/Lib/site-packages/scipy/fftpack/tests/test_pseudo_diffs.py
Normal file
380
venv/Lib/site-packages/scipy/fftpack/tests/test_pseudo_diffs.py
Normal file
|
@ -0,0 +1,380 @@
|
|||
# Created by Pearu Peterson, September 2002
|
||||
|
||||
__usage__ = """
|
||||
Build fftpack:
|
||||
python setup_fftpack.py build
|
||||
Run tests if scipy is installed:
|
||||
python -c 'import scipy;scipy.fftpack.test(<level>)'
|
||||
Run tests if fftpack is not installed:
|
||||
python tests/test_pseudo_diffs.py [<level>]
|
||||
"""
|
||||
|
||||
from numpy.testing import (assert_equal, assert_almost_equal,
|
||||
assert_array_almost_equal)
|
||||
from scipy.fftpack import (diff, fft, ifft, tilbert, itilbert, hilbert,
|
||||
ihilbert, shift, fftfreq, cs_diff, sc_diff,
|
||||
ss_diff, cc_diff)
|
||||
|
||||
import numpy as np
|
||||
from numpy import arange, sin, cos, pi, exp, tanh, sum, sign
|
||||
from numpy.random import random
|
||||
|
||||
|
||||
def direct_diff(x,k=1,period=None):
|
||||
fx = fft(x)
|
||||
n = len(fx)
|
||||
if period is None:
|
||||
period = 2*pi
|
||||
w = fftfreq(n)*2j*pi/period*n
|
||||
if k < 0:
|
||||
w = 1 / w**k
|
||||
w[0] = 0.0
|
||||
else:
|
||||
w = w**k
|
||||
if n > 2000:
|
||||
w[250:n-250] = 0.0
|
||||
return ifft(w*fx).real
|
||||
|
||||
|
||||
def direct_tilbert(x,h=1,period=None):
|
||||
fx = fft(x)
|
||||
n = len(fx)
|
||||
if period is None:
|
||||
period = 2*pi
|
||||
w = fftfreq(n)*h*2*pi/period*n
|
||||
w[0] = 1
|
||||
w = 1j/tanh(w)
|
||||
w[0] = 0j
|
||||
return ifft(w*fx)
|
||||
|
||||
|
||||
def direct_itilbert(x,h=1,period=None):
|
||||
fx = fft(x)
|
||||
n = len(fx)
|
||||
if period is None:
|
||||
period = 2*pi
|
||||
w = fftfreq(n)*h*2*pi/period*n
|
||||
w = -1j*tanh(w)
|
||||
return ifft(w*fx)
|
||||
|
||||
|
||||
def direct_hilbert(x):
|
||||
fx = fft(x)
|
||||
n = len(fx)
|
||||
w = fftfreq(n)*n
|
||||
w = 1j*sign(w)
|
||||
return ifft(w*fx)
|
||||
|
||||
|
||||
def direct_ihilbert(x):
|
||||
return -direct_hilbert(x)
|
||||
|
||||
|
||||
def direct_shift(x,a,period=None):
|
||||
n = len(x)
|
||||
if period is None:
|
||||
k = fftfreq(n)*1j*n
|
||||
else:
|
||||
k = fftfreq(n)*2j*pi/period*n
|
||||
return ifft(fft(x)*exp(k*a)).real
|
||||
|
||||
|
||||
class TestDiff(object):
|
||||
|
||||
def test_definition(self):
|
||||
for n in [16,17,64,127,32]:
|
||||
x = arange(n)*2*pi/n
|
||||
assert_array_almost_equal(diff(sin(x)),direct_diff(sin(x)))
|
||||
assert_array_almost_equal(diff(sin(x),2),direct_diff(sin(x),2))
|
||||
assert_array_almost_equal(diff(sin(x),3),direct_diff(sin(x),3))
|
||||
assert_array_almost_equal(diff(sin(x),4),direct_diff(sin(x),4))
|
||||
assert_array_almost_equal(diff(sin(x),5),direct_diff(sin(x),5))
|
||||
assert_array_almost_equal(diff(sin(2*x),3),direct_diff(sin(2*x),3))
|
||||
assert_array_almost_equal(diff(sin(2*x),4),direct_diff(sin(2*x),4))
|
||||
assert_array_almost_equal(diff(cos(x)),direct_diff(cos(x)))
|
||||
assert_array_almost_equal(diff(cos(x),2),direct_diff(cos(x),2))
|
||||
assert_array_almost_equal(diff(cos(x),3),direct_diff(cos(x),3))
|
||||
assert_array_almost_equal(diff(cos(x),4),direct_diff(cos(x),4))
|
||||
assert_array_almost_equal(diff(cos(2*x)),direct_diff(cos(2*x)))
|
||||
assert_array_almost_equal(diff(sin(x*n/8)),direct_diff(sin(x*n/8)))
|
||||
assert_array_almost_equal(diff(cos(x*n/8)),direct_diff(cos(x*n/8)))
|
||||
for k in range(5):
|
||||
assert_array_almost_equal(diff(sin(4*x),k),direct_diff(sin(4*x),k))
|
||||
assert_array_almost_equal(diff(cos(4*x),k),direct_diff(cos(4*x),k))
|
||||
|
||||
def test_period(self):
|
||||
for n in [17,64]:
|
||||
x = arange(n)/float(n)
|
||||
assert_array_almost_equal(diff(sin(2*pi*x),period=1),
|
||||
2*pi*cos(2*pi*x))
|
||||
assert_array_almost_equal(diff(sin(2*pi*x),3,period=1),
|
||||
-(2*pi)**3*cos(2*pi*x))
|
||||
|
||||
def test_sin(self):
|
||||
for n in [32,64,77]:
|
||||
x = arange(n)*2*pi/n
|
||||
assert_array_almost_equal(diff(sin(x)),cos(x))
|
||||
assert_array_almost_equal(diff(cos(x)),-sin(x))
|
||||
assert_array_almost_equal(diff(sin(x),2),-sin(x))
|
||||
assert_array_almost_equal(diff(sin(x),4),sin(x))
|
||||
assert_array_almost_equal(diff(sin(4*x)),4*cos(4*x))
|
||||
assert_array_almost_equal(diff(sin(sin(x))),cos(x)*cos(sin(x)))
|
||||
|
||||
def test_expr(self):
|
||||
for n in [64,77,100,128,256,512,1024,2048,4096,8192][:5]:
|
||||
x = arange(n)*2*pi/n
|
||||
f = sin(x)*cos(4*x)+exp(sin(3*x))
|
||||
df = cos(x)*cos(4*x)-4*sin(x)*sin(4*x)+3*cos(3*x)*exp(sin(3*x))
|
||||
ddf = -17*sin(x)*cos(4*x)-8*cos(x)*sin(4*x)\
|
||||
- 9*sin(3*x)*exp(sin(3*x))+9*cos(3*x)**2*exp(sin(3*x))
|
||||
d1 = diff(f)
|
||||
assert_array_almost_equal(d1,df)
|
||||
assert_array_almost_equal(diff(df),ddf)
|
||||
assert_array_almost_equal(diff(f,2),ddf)
|
||||
assert_array_almost_equal(diff(ddf,-1),df)
|
||||
|
||||
def test_expr_large(self):
|
||||
for n in [2048,4096]:
|
||||
x = arange(n)*2*pi/n
|
||||
f = sin(x)*cos(4*x)+exp(sin(3*x))
|
||||
df = cos(x)*cos(4*x)-4*sin(x)*sin(4*x)+3*cos(3*x)*exp(sin(3*x))
|
||||
ddf = -17*sin(x)*cos(4*x)-8*cos(x)*sin(4*x)\
|
||||
- 9*sin(3*x)*exp(sin(3*x))+9*cos(3*x)**2*exp(sin(3*x))
|
||||
assert_array_almost_equal(diff(f),df)
|
||||
assert_array_almost_equal(diff(df),ddf)
|
||||
assert_array_almost_equal(diff(ddf,-1),df)
|
||||
assert_array_almost_equal(diff(f,2),ddf)
|
||||
|
||||
def test_int(self):
|
||||
n = 64
|
||||
x = arange(n)*2*pi/n
|
||||
assert_array_almost_equal(diff(sin(x),-1),-cos(x))
|
||||
assert_array_almost_equal(diff(sin(x),-2),-sin(x))
|
||||
assert_array_almost_equal(diff(sin(x),-4),sin(x))
|
||||
assert_array_almost_equal(diff(2*cos(2*x),-1),sin(2*x))
|
||||
|
||||
def test_random_even(self):
|
||||
for k in [0,2,4,6]:
|
||||
for n in [60,32,64,56,55]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
# zeroing Nyquist mode:
|
||||
f = diff(diff(f,1),-1)
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(diff(diff(f,k),-k),f)
|
||||
assert_array_almost_equal(diff(diff(f,-k),k),f)
|
||||
|
||||
def test_random_odd(self):
|
||||
for k in [0,1,2,3,4,5,6]:
|
||||
for n in [33,65,55]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(diff(diff(f,k),-k),f)
|
||||
assert_array_almost_equal(diff(diff(f,-k),k),f)
|
||||
|
||||
def test_zero_nyquist(self):
|
||||
for k in [0,1,2,3,4,5,6]:
|
||||
for n in [32,33,64,56,55]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
# zeroing Nyquist mode:
|
||||
f = diff(diff(f,1),-1)
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(diff(diff(f,k),-k),f)
|
||||
assert_array_almost_equal(diff(diff(f,-k),k),f)
|
||||
|
||||
|
||||
class TestTilbert(object):
|
||||
|
||||
def test_definition(self):
|
||||
for h in [0.1,0.5,1,5.5,10]:
|
||||
for n in [16,17,64,127]:
|
||||
x = arange(n)*2*pi/n
|
||||
y = tilbert(sin(x),h)
|
||||
y1 = direct_tilbert(sin(x),h)
|
||||
assert_array_almost_equal(y,y1)
|
||||
assert_array_almost_equal(tilbert(sin(x),h),
|
||||
direct_tilbert(sin(x),h))
|
||||
assert_array_almost_equal(tilbert(sin(2*x),h),
|
||||
direct_tilbert(sin(2*x),h))
|
||||
|
||||
def test_random_even(self):
|
||||
for h in [0.1,0.5,1,5.5,10]:
|
||||
for n in [32,64,56]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(direct_tilbert(direct_itilbert(f,h),h),f)
|
||||
|
||||
def test_random_odd(self):
|
||||
for h in [0.1,0.5,1,5.5,10]:
|
||||
for n in [33,65,55]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(itilbert(tilbert(f,h),h),f)
|
||||
assert_array_almost_equal(tilbert(itilbert(f,h),h),f)
|
||||
|
||||
|
||||
class TestITilbert(object):
|
||||
|
||||
def test_definition(self):
|
||||
for h in [0.1,0.5,1,5.5,10]:
|
||||
for n in [16,17,64,127]:
|
||||
x = arange(n)*2*pi/n
|
||||
y = itilbert(sin(x),h)
|
||||
y1 = direct_itilbert(sin(x),h)
|
||||
assert_array_almost_equal(y,y1)
|
||||
assert_array_almost_equal(itilbert(sin(x),h),
|
||||
direct_itilbert(sin(x),h))
|
||||
assert_array_almost_equal(itilbert(sin(2*x),h),
|
||||
direct_itilbert(sin(2*x),h))
|
||||
|
||||
|
||||
class TestHilbert(object):
|
||||
|
||||
def test_definition(self):
|
||||
for n in [16,17,64,127]:
|
||||
x = arange(n)*2*pi/n
|
||||
y = hilbert(sin(x))
|
||||
y1 = direct_hilbert(sin(x))
|
||||
assert_array_almost_equal(y,y1)
|
||||
assert_array_almost_equal(hilbert(sin(2*x)),
|
||||
direct_hilbert(sin(2*x)))
|
||||
|
||||
def test_tilbert_relation(self):
|
||||
for n in [16,17,64,127]:
|
||||
x = arange(n)*2*pi/n
|
||||
f = sin(x)+cos(2*x)*sin(x)
|
||||
y = hilbert(f)
|
||||
y1 = direct_hilbert(f)
|
||||
assert_array_almost_equal(y,y1)
|
||||
y2 = tilbert(f,h=10)
|
||||
assert_array_almost_equal(y,y2)
|
||||
|
||||
def test_random_odd(self):
|
||||
for n in [33,65,55]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(ihilbert(hilbert(f)),f)
|
||||
assert_array_almost_equal(hilbert(ihilbert(f)),f)
|
||||
|
||||
def test_random_even(self):
|
||||
for n in [32,64,56]:
|
||||
f = random((n,))
|
||||
af = sum(f,axis=0)/n
|
||||
f = f-af
|
||||
# zeroing Nyquist mode:
|
||||
f = diff(diff(f,1),-1)
|
||||
assert_almost_equal(sum(f,axis=0),0.0)
|
||||
assert_array_almost_equal(direct_hilbert(direct_ihilbert(f)),f)
|
||||
assert_array_almost_equal(hilbert(ihilbert(f)),f)
|
||||
|
||||
|
||||
class TestIHilbert(object):
|
||||
|
||||
def test_definition(self):
|
||||
for n in [16,17,64,127]:
|
||||
x = arange(n)*2*pi/n
|
||||
y = ihilbert(sin(x))
|
||||
y1 = direct_ihilbert(sin(x))
|
||||
assert_array_almost_equal(y,y1)
|
||||
assert_array_almost_equal(ihilbert(sin(2*x)),
|
||||
direct_ihilbert(sin(2*x)))
|
||||
|
||||
def test_itilbert_relation(self):
|
||||
for n in [16,17,64,127]:
|
||||
x = arange(n)*2*pi/n
|
||||
f = sin(x)+cos(2*x)*sin(x)
|
||||
y = ihilbert(f)
|
||||
y1 = direct_ihilbert(f)
|
||||
assert_array_almost_equal(y,y1)
|
||||
y2 = itilbert(f,h=10)
|
||||
assert_array_almost_equal(y,y2)
|
||||
|
||||
|
||||
class TestShift(object):
|
||||
|
||||
def test_definition(self):
|
||||
for n in [18,17,64,127,32,2048,256]:
|
||||
x = arange(n)*2*pi/n
|
||||
for a in [0.1,3]:
|
||||
assert_array_almost_equal(shift(sin(x),a),direct_shift(sin(x),a))
|
||||
assert_array_almost_equal(shift(sin(x),a),sin(x+a))
|
||||
assert_array_almost_equal(shift(cos(x),a),cos(x+a))
|
||||
assert_array_almost_equal(shift(cos(2*x)+sin(x),a),
|
||||
cos(2*(x+a))+sin(x+a))
|
||||
assert_array_almost_equal(shift(exp(sin(x)),a),exp(sin(x+a)))
|
||||
assert_array_almost_equal(shift(sin(x),2*pi),sin(x))
|
||||
assert_array_almost_equal(shift(sin(x),pi),-sin(x))
|
||||
assert_array_almost_equal(shift(sin(x),pi/2),cos(x))
|
||||
|
||||
|
||||
class TestOverwrite(object):
|
||||
"""Check input overwrite behavior """
|
||||
|
||||
real_dtypes = (np.float32, np.float64)
|
||||
dtypes = real_dtypes + (np.complex64, np.complex128)
|
||||
|
||||
def _check(self, x, routine, *args, **kwargs):
|
||||
x2 = x.copy()
|
||||
routine(x2, *args, **kwargs)
|
||||
sig = routine.__name__
|
||||
if args:
|
||||
sig += repr(args)
|
||||
if kwargs:
|
||||
sig += repr(kwargs)
|
||||
assert_equal(x2, x, err_msg="spurious overwrite in %s" % sig)
|
||||
|
||||
def _check_1d(self, routine, dtype, shape, *args, **kwargs):
|
||||
np.random.seed(1234)
|
||||
if np.issubdtype(dtype, np.complexfloating):
|
||||
data = np.random.randn(*shape) + 1j*np.random.randn(*shape)
|
||||
else:
|
||||
data = np.random.randn(*shape)
|
||||
data = data.astype(dtype)
|
||||
self._check(data, routine, *args, **kwargs)
|
||||
|
||||
def test_diff(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(diff, dtype, (16,))
|
||||
|
||||
def test_tilbert(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(tilbert, dtype, (16,), 1.6)
|
||||
|
||||
def test_itilbert(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(itilbert, dtype, (16,), 1.6)
|
||||
|
||||
def test_hilbert(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(hilbert, dtype, (16,))
|
||||
|
||||
def test_cs_diff(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(cs_diff, dtype, (16,), 1.0, 4.0)
|
||||
|
||||
def test_sc_diff(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(sc_diff, dtype, (16,), 1.0, 4.0)
|
||||
|
||||
def test_ss_diff(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(ss_diff, dtype, (16,), 1.0, 4.0)
|
||||
|
||||
def test_cc_diff(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(cc_diff, dtype, (16,), 1.0, 4.0)
|
||||
|
||||
def test_shift(self):
|
||||
for dtype in self.dtypes:
|
||||
self._check_1d(shift, dtype, (16,), 1.0)
|
|
@ -0,0 +1,817 @@
|
|||
from os.path import join, dirname
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_array_almost_equal, assert_equal
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from scipy.fftpack.realtransforms import (
|
||||
dct, idct, dst, idst, dctn, idctn, dstn, idstn)
|
||||
|
||||
# Matlab reference data
|
||||
MDATA = np.load(join(dirname(__file__), 'test.npz'))
|
||||
X = [MDATA['x%d' % i] for i in range(8)]
|
||||
Y = [MDATA['y%d' % i] for i in range(8)]
|
||||
|
||||
# FFTW reference data: the data are organized as follows:
|
||||
# * SIZES is an array containing all available sizes
|
||||
# * for every type (1, 2, 3, 4) and every size, the array dct_type_size
|
||||
# contains the output of the DCT applied to the input np.linspace(0, size-1,
|
||||
# size)
|
||||
FFTWDATA_DOUBLE = np.load(join(dirname(__file__), 'fftw_double_ref.npz'))
|
||||
FFTWDATA_SINGLE = np.load(join(dirname(__file__), 'fftw_single_ref.npz'))
|
||||
FFTWDATA_SIZES = FFTWDATA_DOUBLE['sizes']
|
||||
|
||||
|
||||
def fftw_dct_ref(type, size, dt):
|
||||
x = np.linspace(0, size-1, size).astype(dt)
|
||||
dt = np.result_type(np.float32, dt)
|
||||
if dt == np.double:
|
||||
data = FFTWDATA_DOUBLE
|
||||
elif dt == np.float32:
|
||||
data = FFTWDATA_SINGLE
|
||||
else:
|
||||
raise ValueError()
|
||||
y = (data['dct_%d_%d' % (type, size)]).astype(dt)
|
||||
return x, y, dt
|
||||
|
||||
|
||||
def fftw_dst_ref(type, size, dt):
|
||||
x = np.linspace(0, size-1, size).astype(dt)
|
||||
dt = np.result_type(np.float32, dt)
|
||||
if dt == np.double:
|
||||
data = FFTWDATA_DOUBLE
|
||||
elif dt == np.float32:
|
||||
data = FFTWDATA_SINGLE
|
||||
else:
|
||||
raise ValueError()
|
||||
y = (data['dst_%d_%d' % (type, size)]).astype(dt)
|
||||
return x, y, dt
|
||||
|
||||
|
||||
def dct_2d_ref(x, **kwargs):
|
||||
"""Calculate reference values for testing dct2."""
|
||||
x = np.array(x, copy=True)
|
||||
for row in range(x.shape[0]):
|
||||
x[row, :] = dct(x[row, :], **kwargs)
|
||||
for col in range(x.shape[1]):
|
||||
x[:, col] = dct(x[:, col], **kwargs)
|
||||
return x
|
||||
|
||||
|
||||
def idct_2d_ref(x, **kwargs):
|
||||
"""Calculate reference values for testing idct2."""
|
||||
x = np.array(x, copy=True)
|
||||
for row in range(x.shape[0]):
|
||||
x[row, :] = idct(x[row, :], **kwargs)
|
||||
for col in range(x.shape[1]):
|
||||
x[:, col] = idct(x[:, col], **kwargs)
|
||||
return x
|
||||
|
||||
|
||||
def dst_2d_ref(x, **kwargs):
|
||||
"""Calculate reference values for testing dst2."""
|
||||
x = np.array(x, copy=True)
|
||||
for row in range(x.shape[0]):
|
||||
x[row, :] = dst(x[row, :], **kwargs)
|
||||
for col in range(x.shape[1]):
|
||||
x[:, col] = dst(x[:, col], **kwargs)
|
||||
return x
|
||||
|
||||
|
||||
def idst_2d_ref(x, **kwargs):
|
||||
"""Calculate reference values for testing idst2."""
|
||||
x = np.array(x, copy=True)
|
||||
for row in range(x.shape[0]):
|
||||
x[row, :] = idst(x[row, :], **kwargs)
|
||||
for col in range(x.shape[1]):
|
||||
x[:, col] = idst(x[:, col], **kwargs)
|
||||
return x
|
||||
|
||||
|
||||
def naive_dct1(x, norm=None):
|
||||
"""Calculate textbook definition version of DCT-I."""
|
||||
x = np.array(x, copy=True)
|
||||
N = len(x)
|
||||
M = N-1
|
||||
y = np.zeros(N)
|
||||
m0, m = 1, 2
|
||||
if norm == 'ortho':
|
||||
m0 = np.sqrt(1.0/M)
|
||||
m = np.sqrt(2.0/M)
|
||||
for k in range(N):
|
||||
for n in range(1, N-1):
|
||||
y[k] += m*x[n]*np.cos(np.pi*n*k/M)
|
||||
y[k] += m0 * x[0]
|
||||
y[k] += m0 * x[N-1] * (1 if k % 2 == 0 else -1)
|
||||
if norm == 'ortho':
|
||||
y[0] *= 1/np.sqrt(2)
|
||||
y[N-1] *= 1/np.sqrt(2)
|
||||
return y
|
||||
|
||||
|
||||
def naive_dst1(x, norm=None):
|
||||
"""Calculate textbook definition version of DST-I."""
|
||||
x = np.array(x, copy=True)
|
||||
N = len(x)
|
||||
M = N+1
|
||||
y = np.zeros(N)
|
||||
for k in range(N):
|
||||
for n in range(N):
|
||||
y[k] += 2*x[n]*np.sin(np.pi*(n+1.0)*(k+1.0)/M)
|
||||
if norm == 'ortho':
|
||||
y *= np.sqrt(0.5/M)
|
||||
return y
|
||||
|
||||
|
||||
def naive_dct4(x, norm=None):
|
||||
"""Calculate textbook definition version of DCT-IV."""
|
||||
x = np.array(x, copy=True)
|
||||
N = len(x)
|
||||
y = np.zeros(N)
|
||||
for k in range(N):
|
||||
for n in range(N):
|
||||
y[k] += x[n]*np.cos(np.pi*(n+0.5)*(k+0.5)/(N))
|
||||
if norm == 'ortho':
|
||||
y *= np.sqrt(2.0/N)
|
||||
else:
|
||||
y *= 2
|
||||
return y
|
||||
|
||||
|
||||
def naive_dst4(x, norm=None):
|
||||
"""Calculate textbook definition version of DST-IV."""
|
||||
x = np.array(x, copy=True)
|
||||
N = len(x)
|
||||
y = np.zeros(N)
|
||||
for k in range(N):
|
||||
for n in range(N):
|
||||
y[k] += x[n]*np.sin(np.pi*(n+0.5)*(k+0.5)/(N))
|
||||
if norm == 'ortho':
|
||||
y *= np.sqrt(2.0/N)
|
||||
else:
|
||||
y *= 2
|
||||
return y
|
||||
|
||||
|
||||
class TestComplex(object):
|
||||
def test_dct_complex64(self):
|
||||
y = dct(1j*np.arange(5, dtype=np.complex64))
|
||||
x = 1j*dct(np.arange(5))
|
||||
assert_array_almost_equal(x, y)
|
||||
|
||||
def test_dct_complex(self):
|
||||
y = dct(np.arange(5)*1j)
|
||||
x = 1j*dct(np.arange(5))
|
||||
assert_array_almost_equal(x, y)
|
||||
|
||||
def test_idct_complex(self):
|
||||
y = idct(np.arange(5)*1j)
|
||||
x = 1j*idct(np.arange(5))
|
||||
assert_array_almost_equal(x, y)
|
||||
|
||||
def test_dst_complex64(self):
|
||||
y = dst(np.arange(5, dtype=np.complex64)*1j)
|
||||
x = 1j*dst(np.arange(5))
|
||||
assert_array_almost_equal(x, y)
|
||||
|
||||
def test_dst_complex(self):
|
||||
y = dst(np.arange(5)*1j)
|
||||
x = 1j*dst(np.arange(5))
|
||||
assert_array_almost_equal(x, y)
|
||||
|
||||
def test_idst_complex(self):
|
||||
y = idst(np.arange(5)*1j)
|
||||
x = 1j*idst(np.arange(5))
|
||||
assert_array_almost_equal(x, y)
|
||||
|
||||
|
||||
class _TestDCTBase(object):
|
||||
def setup_method(self):
|
||||
self.rdt = None
|
||||
self.dec = 14
|
||||
self.type = None
|
||||
|
||||
def test_definition(self):
|
||||
for i in FFTWDATA_SIZES:
|
||||
x, yr, dt = fftw_dct_ref(self.type, i, self.rdt)
|
||||
y = dct(x, type=self.type)
|
||||
assert_equal(y.dtype, dt)
|
||||
# XXX: we divide by np.max(y) because the tests fail otherwise. We
|
||||
# should really use something like assert_array_approx_equal. The
|
||||
# difference is due to fftw using a better algorithm w.r.t error
|
||||
# propagation compared to the ones from fftpack.
|
||||
assert_array_almost_equal(y / np.max(y), yr / np.max(y), decimal=self.dec,
|
||||
err_msg="Size %d failed" % i)
|
||||
|
||||
def test_axis(self):
|
||||
nt = 2
|
||||
for i in [7, 8, 9, 16, 32, 64]:
|
||||
x = np.random.randn(nt, i)
|
||||
y = dct(x, type=self.type)
|
||||
for j in range(nt):
|
||||
assert_array_almost_equal(y[j], dct(x[j], type=self.type),
|
||||
decimal=self.dec)
|
||||
|
||||
x = x.T
|
||||
y = dct(x, axis=0, type=self.type)
|
||||
for j in range(nt):
|
||||
assert_array_almost_equal(y[:,j], dct(x[:,j], type=self.type),
|
||||
decimal=self.dec)
|
||||
|
||||
|
||||
class _TestDCTIBase(_TestDCTBase):
|
||||
def test_definition_ortho(self):
|
||||
# Test orthornomal mode.
|
||||
for i in range(len(X)):
|
||||
x = np.array(X[i], dtype=self.rdt)
|
||||
dt = np.result_type(np.float32, self.rdt)
|
||||
y = dct(x, norm='ortho', type=1)
|
||||
y2 = naive_dct1(x, norm='ortho')
|
||||
assert_equal(y.dtype, dt)
|
||||
assert_array_almost_equal(y / np.max(y), y2 / np.max(y), decimal=self.dec)
|
||||
|
||||
class _TestDCTIIBase(_TestDCTBase):
|
||||
def test_definition_matlab(self):
|
||||
# Test correspondence with MATLAB (orthornomal mode).
|
||||
for i in range(len(X)):
|
||||
dt = np.result_type(np.float32, self.rdt)
|
||||
x = np.array(X[i], dtype=dt)
|
||||
|
||||
yr = Y[i]
|
||||
y = dct(x, norm="ortho", type=2)
|
||||
assert_equal(y.dtype, dt)
|
||||
assert_array_almost_equal(y, yr, decimal=self.dec)
|
||||
|
||||
|
||||
class _TestDCTIIIBase(_TestDCTBase):
|
||||
def test_definition_ortho(self):
|
||||
# Test orthornomal mode.
|
||||
for i in range(len(X)):
|
||||
x = np.array(X[i], dtype=self.rdt)
|
||||
dt = np.result_type(np.float32, self.rdt)
|
||||
y = dct(x, norm='ortho', type=2)
|
||||
xi = dct(y, norm="ortho", type=3)
|
||||
assert_equal(xi.dtype, dt)
|
||||
assert_array_almost_equal(xi, x, decimal=self.dec)
|
||||
|
||||
class _TestDCTIVBase(_TestDCTBase):
|
||||
def test_definition_ortho(self):
|
||||
# Test orthornomal mode.
|
||||
for i in range(len(X)):
|
||||
x = np.array(X[i], dtype=self.rdt)
|
||||
dt = np.result_type(np.float32, self.rdt)
|
||||
y = dct(x, norm='ortho', type=4)
|
||||
y2 = naive_dct4(x, norm='ortho')
|
||||
assert_equal(y.dtype, dt)
|
||||
assert_array_almost_equal(y / np.max(y), y2 / np.max(y), decimal=self.dec)
|
||||
|
||||
|
||||
class TestDCTIDouble(_TestDCTIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 10
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestDCTIFloat(_TestDCTIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 4
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestDCTIInt(_TestDCTIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestDCTIIDouble(_TestDCTIIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 10
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestDCTIIFloat(_TestDCTIIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 5
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestDCTIIInt(_TestDCTIIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestDCTIIIDouble(_TestDCTIIIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 14
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDCTIIIFloat(_TestDCTIIIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 5
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDCTIIIInt(_TestDCTIIIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDCTIVDouble(_TestDCTIVBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 12
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDCTIVFloat(_TestDCTIVBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 5
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDCTIVInt(_TestDCTIVBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 3
|
||||
|
||||
|
||||
class _TestIDCTBase(object):
|
||||
def setup_method(self):
|
||||
self.rdt = None
|
||||
self.dec = 14
|
||||
self.type = None
|
||||
|
||||
def test_definition(self):
|
||||
for i in FFTWDATA_SIZES:
|
||||
xr, yr, dt = fftw_dct_ref(self.type, i, self.rdt)
|
||||
x = idct(yr, type=self.type)
|
||||
if self.type == 1:
|
||||
x /= 2 * (i-1)
|
||||
else:
|
||||
x /= 2 * i
|
||||
assert_equal(x.dtype, dt)
|
||||
# XXX: we divide by np.max(y) because the tests fail otherwise. We
|
||||
# should really use something like assert_array_approx_equal. The
|
||||
# difference is due to fftw using a better algorithm w.r.t error
|
||||
# propagation compared to the ones from fftpack.
|
||||
assert_array_almost_equal(x / np.max(x), xr / np.max(x), decimal=self.dec,
|
||||
err_msg="Size %d failed" % i)
|
||||
|
||||
|
||||
class TestIDCTIDouble(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 10
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestIDCTIFloat(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 4
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestIDCTIInt(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 4
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestIDCTIIDouble(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 10
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestIDCTIIFloat(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 5
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestIDCTIIInt(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestIDCTIIIDouble(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 14
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestIDCTIIIFloat(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 5
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestIDCTIIIInt(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 3
|
||||
|
||||
class TestIDCTIVDouble(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 12
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestIDCTIVFloat(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 5
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestIDCTIVInt(_TestIDCTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 4
|
||||
|
||||
class _TestDSTBase(object):
|
||||
def setup_method(self):
|
||||
self.rdt = None # dtype
|
||||
self.dec = None # number of decimals to match
|
||||
self.type = None # dst type
|
||||
|
||||
def test_definition(self):
|
||||
for i in FFTWDATA_SIZES:
|
||||
xr, yr, dt = fftw_dst_ref(self.type, i, self.rdt)
|
||||
y = dst(xr, type=self.type)
|
||||
assert_equal(y.dtype, dt)
|
||||
# XXX: we divide by np.max(y) because the tests fail otherwise. We
|
||||
# should really use something like assert_array_approx_equal. The
|
||||
# difference is due to fftw using a better algorithm w.r.t error
|
||||
# propagation compared to the ones from fftpack.
|
||||
assert_array_almost_equal(y / np.max(y), yr / np.max(y), decimal=self.dec,
|
||||
err_msg="Size %d failed" % i)
|
||||
|
||||
|
||||
class _TestDSTIBase(_TestDSTBase):
|
||||
def test_definition_ortho(self):
|
||||
# Test orthornomal mode.
|
||||
for i in range(len(X)):
|
||||
x = np.array(X[i], dtype=self.rdt)
|
||||
dt = np.result_type(np.float32, self.rdt)
|
||||
y = dst(x, norm='ortho', type=1)
|
||||
y2 = naive_dst1(x, norm='ortho')
|
||||
assert_equal(y.dtype, dt)
|
||||
assert_array_almost_equal(y / np.max(y), y2 / np.max(y), decimal=self.dec)
|
||||
|
||||
class _TestDSTIVBase(_TestDSTBase):
|
||||
def test_definition_ortho(self):
|
||||
# Test orthornomal mode.
|
||||
for i in range(len(X)):
|
||||
x = np.array(X[i], dtype=self.rdt)
|
||||
dt = np.result_type(np.float32, self.rdt)
|
||||
y = dst(x, norm='ortho', type=4)
|
||||
y2 = naive_dst4(x, norm='ortho')
|
||||
assert_equal(y.dtype, dt)
|
||||
assert_array_almost_equal(y, y2, decimal=self.dec)
|
||||
|
||||
class TestDSTIDouble(_TestDSTIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 12
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestDSTIFloat(_TestDSTIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 4
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestDSTIInt(_TestDSTIBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestDSTIIDouble(_TestDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 14
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestDSTIIFloat(_TestDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 6
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestDSTIIInt(_TestDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 6
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestDSTIIIDouble(_TestDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 14
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDSTIIIFloat(_TestDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 7
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDSTIIIInt(_TestDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 7
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestDSTIVDouble(_TestDSTIVBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 12
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestDSTIVFloat(_TestDSTIVBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 4
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestDSTIVInt(_TestDSTIVBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 5
|
||||
self.type = 4
|
||||
|
||||
|
||||
class _TestIDSTBase(object):
|
||||
def setup_method(self):
|
||||
self.rdt = None
|
||||
self.dec = None
|
||||
self.type = None
|
||||
|
||||
def test_definition(self):
|
||||
for i in FFTWDATA_SIZES:
|
||||
xr, yr, dt = fftw_dst_ref(self.type, i, self.rdt)
|
||||
x = idst(yr, type=self.type)
|
||||
if self.type == 1:
|
||||
x /= 2 * (i+1)
|
||||
else:
|
||||
x /= 2 * i
|
||||
assert_equal(x.dtype, dt)
|
||||
# XXX: we divide by np.max(x) because the tests fail otherwise. We
|
||||
# should really use something like assert_array_approx_equal. The
|
||||
# difference is due to fftw using a better algorithm w.r.t error
|
||||
# propagation compared to the ones from fftpack.
|
||||
assert_array_almost_equal(x / np.max(x), xr / np.max(x), decimal=self.dec,
|
||||
err_msg="Size %d failed" % i)
|
||||
|
||||
|
||||
class TestIDSTIDouble(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 12
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestIDSTIFloat(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 4
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestIDSTIInt(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 4
|
||||
self.type = 1
|
||||
|
||||
|
||||
class TestIDSTIIDouble(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 14
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestIDSTIIFloat(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 6
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestIDSTIIInt(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 6
|
||||
self.type = 2
|
||||
|
||||
|
||||
class TestIDSTIIIDouble(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 14
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestIDSTIIIFloat(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 6
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestIDSTIIIInt(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 6
|
||||
self.type = 3
|
||||
|
||||
|
||||
class TestIDSTIVDouble(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.double
|
||||
self.dec = 12
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestIDSTIVFloat(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = np.float32
|
||||
self.dec = 6
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestIDSTIVnt(_TestIDSTBase):
|
||||
def setup_method(self):
|
||||
self.rdt = int
|
||||
self.dec = 6
|
||||
self.type = 4
|
||||
|
||||
|
||||
class TestOverwrite(object):
|
||||
"""Check input overwrite behavior."""
|
||||
|
||||
real_dtypes = [np.float32, np.float64]
|
||||
|
||||
def _check(self, x, routine, type, fftsize, axis, norm, overwrite_x, **kw):
|
||||
x2 = x.copy()
|
||||
routine(x2, type, fftsize, axis, norm, overwrite_x=overwrite_x)
|
||||
|
||||
sig = "%s(%s%r, %r, axis=%r, overwrite_x=%r)" % (
|
||||
routine.__name__, x.dtype, x.shape, fftsize, axis, overwrite_x)
|
||||
if not overwrite_x:
|
||||
assert_equal(x2, x, err_msg="spurious overwrite in %s" % sig)
|
||||
|
||||
def _check_1d(self, routine, dtype, shape, axis):
|
||||
np.random.seed(1234)
|
||||
if np.issubdtype(dtype, np.complexfloating):
|
||||
data = np.random.randn(*shape) + 1j*np.random.randn(*shape)
|
||||
else:
|
||||
data = np.random.randn(*shape)
|
||||
data = data.astype(dtype)
|
||||
|
||||
for type in [1, 2, 3, 4]:
|
||||
for overwrite_x in [True, False]:
|
||||
for norm in [None, 'ortho']:
|
||||
self._check(data, routine, type, None, axis, norm,
|
||||
overwrite_x)
|
||||
|
||||
def test_dct(self):
|
||||
for dtype in self.real_dtypes:
|
||||
self._check_1d(dct, dtype, (16,), -1)
|
||||
self._check_1d(dct, dtype, (16, 2), 0)
|
||||
self._check_1d(dct, dtype, (2, 16), 1)
|
||||
|
||||
def test_idct(self):
|
||||
for dtype in self.real_dtypes:
|
||||
self._check_1d(idct, dtype, (16,), -1)
|
||||
self._check_1d(idct, dtype, (16, 2), 0)
|
||||
self._check_1d(idct, dtype, (2, 16), 1)
|
||||
|
||||
def test_dst(self):
|
||||
for dtype in self.real_dtypes:
|
||||
self._check_1d(dst, dtype, (16,), -1)
|
||||
self._check_1d(dst, dtype, (16, 2), 0)
|
||||
self._check_1d(dst, dtype, (2, 16), 1)
|
||||
|
||||
def test_idst(self):
|
||||
for dtype in self.real_dtypes:
|
||||
self._check_1d(idst, dtype, (16,), -1)
|
||||
self._check_1d(idst, dtype, (16, 2), 0)
|
||||
self._check_1d(idst, dtype, (2, 16), 1)
|
||||
|
||||
|
||||
class Test_DCTN_IDCTN(object):
|
||||
dec = 14
|
||||
dct_type = [1, 2, 3, 4]
|
||||
norms = [None, 'ortho']
|
||||
rstate = np.random.RandomState(1234)
|
||||
shape = (32, 16)
|
||||
data = rstate.randn(*shape)
|
||||
|
||||
@pytest.mark.parametrize('fforward,finverse', [(dctn, idctn),
|
||||
(dstn, idstn)])
|
||||
@pytest.mark.parametrize('axes', [None,
|
||||
1, (1,), [1],
|
||||
0, (0,), [0],
|
||||
(0, 1), [0, 1],
|
||||
(-2, -1), [-2, -1]])
|
||||
@pytest.mark.parametrize('dct_type', dct_type)
|
||||
@pytest.mark.parametrize('norm', ['ortho'])
|
||||
def test_axes_round_trip(self, fforward, finverse, axes, dct_type, norm):
|
||||
tmp = fforward(self.data, type=dct_type, axes=axes, norm=norm)
|
||||
tmp = finverse(tmp, type=dct_type, axes=axes, norm=norm)
|
||||
assert_array_almost_equal(self.data, tmp, decimal=12)
|
||||
|
||||
@pytest.mark.parametrize('fforward,fforward_ref', [(dctn, dct_2d_ref),
|
||||
(dstn, dst_2d_ref)])
|
||||
@pytest.mark.parametrize('dct_type', dct_type)
|
||||
@pytest.mark.parametrize('norm', norms)
|
||||
def test_dctn_vs_2d_reference(self, fforward, fforward_ref,
|
||||
dct_type, norm):
|
||||
y1 = fforward(self.data, type=dct_type, axes=None, norm=norm)
|
||||
y2 = fforward_ref(self.data, type=dct_type, norm=norm)
|
||||
assert_array_almost_equal(y1, y2, decimal=11)
|
||||
|
||||
@pytest.mark.parametrize('finverse,finverse_ref', [(idctn, idct_2d_ref),
|
||||
(idstn, idst_2d_ref)])
|
||||
@pytest.mark.parametrize('dct_type', dct_type)
|
||||
@pytest.mark.parametrize('norm', [None, 'ortho'])
|
||||
def test_idctn_vs_2d_reference(self, finverse, finverse_ref,
|
||||
dct_type, norm):
|
||||
fdata = dctn(self.data, type=dct_type, norm=norm)
|
||||
y1 = finverse(fdata, type=dct_type, norm=norm)
|
||||
y2 = finverse_ref(fdata, type=dct_type, norm=norm)
|
||||
assert_array_almost_equal(y1, y2, decimal=11)
|
||||
|
||||
@pytest.mark.parametrize('fforward,finverse', [(dctn, idctn),
|
||||
(dstn, idstn)])
|
||||
def test_axes_and_shape(self, fforward, finverse):
|
||||
with assert_raises(ValueError,
|
||||
match="when given, axes and shape arguments"
|
||||
" have to be of the same length"):
|
||||
fforward(self.data, shape=self.data.shape[0], axes=(0, 1))
|
||||
|
||||
with assert_raises(ValueError,
|
||||
match="when given, axes and shape arguments"
|
||||
" have to be of the same length"):
|
||||
fforward(self.data, shape=self.data.shape[0], axes=None)
|
||||
|
||||
with assert_raises(ValueError,
|
||||
match="when given, axes and shape arguments"
|
||||
" have to be of the same length"):
|
||||
fforward(self.data, shape=self.data.shape, axes=0)
|
||||
|
||||
@pytest.mark.parametrize('fforward', [dctn, dstn])
|
||||
def test_shape(self, fforward):
|
||||
tmp = fforward(self.data, shape=(128, 128), axes=None)
|
||||
assert_equal(tmp.shape, (128, 128))
|
||||
|
||||
@pytest.mark.parametrize('fforward,finverse', [(dctn, idctn),
|
||||
(dstn, idstn)])
|
||||
@pytest.mark.parametrize('axes', [1, (1,), [1],
|
||||
0, (0,), [0]])
|
||||
def test_shape_is_none_with_axes(self, fforward, finverse, axes):
|
||||
tmp = fforward(self.data, shape=None, axes=axes, norm='ortho')
|
||||
tmp = finverse(tmp, shape=None, axes=axes, norm='ortho')
|
||||
assert_array_almost_equal(self.data, tmp, decimal=self.dec)
|
Loading…
Add table
Add a link
Reference in a new issue