Vehicle-Anti-Theft-Face-Rec.../venv/Lib/site-packages/pywt/data/_wavelab_signals.py

259 lines
9.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding:utf-8 -*-
from __future__ import division
import numpy as np
__all__ = ['demo_signal']
_implemented_signals = [
'Blocks',
'Bumps',
'HeaviSine',
'Doppler',
'Ramp',
'HiSine',
'LoSine',
'LinChirp',
'TwoChirp',
'QuadChirp',
'MishMash',
'WernerSorrows',
'HypChirps',
'LinChirps',
'Chirps',
'Gabor',
'sineoneoverx',
'Piece-Regular',
'Piece-Polynomial',
'Riemann']
def demo_signal(name='Bumps', n=None):
"""Simple 1D wavelet test functions.
This function can generate a number of common 1D test signals used in
papers by David Donoho and colleagues (e.g. [1]_) as well as the wavelet
book by Stéphane Mallat [2]_.
Parameters
----------
name : {'Blocks', 'Bumps', 'HeaviSine', 'Doppler', ...}
The type of test signal to generate (`name` is case-insensitive). If
`name` is set to `'list'`, a list of the avialable test functions is
returned.
n : int or None
The length of the test signal. This should be provided for all test
signals except `'Gabor'` and `'sineoneoverx'` which have a fixed
length.
Returns
-------
f : np.ndarray
Array of length ``n`` corresponding to the specified test signal type.
References
----------
.. [1] D.L. Donoho and I.M. Johnstone. Ideal spatial adaptation by
wavelet shrinkage. Biometrika, vol. 81, pp. 425455, 1994.
.. [2] S. Mallat. A Wavelet Tour of Signal Processing: The Sparse Way.
Academic Press. 2009.
Notes
-----
This function is a partial reimplementation of the `MakeSignal` function
from the [Wavelab](https://statweb.stanford.edu/~wavelab/) toolbox. These
test signals are provided with permission of Dr. Donoho to encourage
reproducible research.
"""
if name.lower() == 'list':
return _implemented_signals
if n is not None:
if n < 1 or (n % 1) != 0:
raise ValueError("n must be an integer >= 1")
t = np.arange(1/n, 1 + 1/n, 1/n)
# The following function types don't allow user-specified `n`.
n_hard_coded = ['gabor', 'sineoneoverx']
name = name.lower()
if name in n_hard_coded and n is not None:
raise ValueError(
"Parameter n must be set to None when name is {}".format(name))
elif n is None and name not in n_hard_coded:
raise ValueError(
"Parameter n must be provided when name is {}".format(name))
if name == 'blocks':
t0s = [.1, .13, .15, .23, .25, .4, .44, .65, .76, .78, .81]
hs = [4, -5, 3, -4, 5, -4.2, 2.1, 4.3, -3.1, 2.1, -4.2]
f = 0
for (t0, h) in zip(t0s, hs):
f += h * (1 + np.sign(t - t0)) / 2
elif name == 'bumps':
t0s = [.1, .13, .15, .23, .25, .4, .44, .65, .76, .78, .81]
hs = [4, 5, 3, 4, 5, 4.2, 2.1, 4.3, 3.1, 5.1, 4.2]
ws = [.005, .005, .006, .01, .01, .03, .01, .01, .005, .008, .005]
f = 0
for (t0, h, w) in zip(t0s, hs, ws):
f += h / (1 + np.abs((t - t0) / w))**4
elif name == 'heavisine':
f = 4 * np.sin(4 * np.pi * t) - np.sign(t - 0.3) - np.sign(0.72 - t)
elif name == 'doppler':
f = np.sqrt(t * (1 - t)) * np.sin(2 * np.pi * 1.05 / (t + 0.05))
elif name == 'ramp':
f = t - (t >= .37)
elif name == 'hisine':
f = np.sin(np.pi * (n * .6902) * t)
elif name == 'losine':
f = np.sin(np.pi * (n * .3333) * t)
elif name == 'linchirp':
f = np.sin(np.pi * t * ((n * .500) * t))
elif name == 'twochirp':
f = np.sin(np.pi * t * (n * t)) + np.sin((np.pi / 3) * t * (n * t))
elif name == 'quadchirp':
f = np.sin((np.pi / 3) * t * (n * t**2))
elif name == 'mishmash': # QuadChirp + LinChirp + HiSine
f = np.sin((np.pi / 3) * t * (n * t**2))
f += np.sin(np.pi * (n * .6902) * t)
f += np.sin(np.pi * t * (n * .125 * t))
elif name == 'wernersorrows':
f = np.sin(np.pi * t * (n / 2 * t**2))
f = f + np.sin(np.pi * (n * .6902) * t)
f = f + np.sin(np.pi * t * (n * t))
pos = [.1, .13, .15, .23, .25, .40, .44, .65, .76, .78, .81]
hgt = [4, 5, 3, 4, 5, 4.2, 2.1, 4.3, 3.1, 5.1, 4.2]
wth = [.005, .005, .006, .01, .01, .03, .01, .01, .005, .008, .005]
for p, h, w in zip(pos, hgt, wth):
f += h / (1 + np.abs((t - p) / w))**4
elif name == 'hypchirps': # Hyperbolic Chirps of Mallat's book
alpha = 15 * n * np.pi / 1024
beta = 5 * n * np.pi / 1024
t = np.arange(1.001, n + .001 + 1) / n
f1 = np.zeros(n)
f2 = np.zeros(n)
f1 = np.sin(alpha / (.8 - t)) * (0.1 < t) * (t < 0.68)
f2 = np.sin(beta / (.8 - t)) * (0.1 < t) * (t < 0.75)
m = int(np.round(0.65 * n))
p = m // 4
envelope = np.ones(m) # the rinp.sing cutoff function
tmp = np.arange(1, p + 1)-np.ones(p)
envelope[:p] = (1 + np.sin(-np.pi / 2 + tmp / (p - 1) * np.pi)) / 2
envelope[m-p:m] = envelope[:p][::-1]
env = np.zeros(n)
env[int(np.ceil(n / 10)) - 1:m + int(np.ceil(n / 10)) - 1] = \
envelope[:m]
f = (f1 + f2) * env
elif name == 'linchirps': # Linear Chirps of Mallat's book
b = 100 * n * np.pi / 1024
a = 250 * n * np.pi / 1024
t = np.arange(1, n + 1) / n
A1 = np.sqrt((t - 1 / n) * (1 - t))
f = A1 * (np.cos(a * t**2) + np.cos(b * t + a * t**2))
elif name == 'chirps': # Mixture of Chirps of Mallat's book
t = np.arange(1, n + 1)/n * 10 * np.pi
f1 = np.cos(t**2 * n / 1024)
a = 30 * n / 1024
t = np.arange(1, n + 1)/n * np.pi
f2 = np.cos(a * (t**3))
f2 = f2[::-1]
ix = np.arange(-n, n + 1) / n * 20
g = np.exp(-ix**2 * 4 * n / 1024)
i1 = slice(n // 2, n // 2 + n)
i2 = slice(n // 8, n // 8 + n)
j = np.arange(1, n + 1) / n
f3 = g[i1] * np.cos(50 * np.pi * j * n / 1024)
f4 = g[i2] * np.cos(350 * np.pi * j * n / 1024)
f = f1 + f2 + f3 + f4
envelope = np.ones(n) # the rinp.sing cutoff function
tmp = np.arange(1, n // 8 + 1) - np.ones(n // 8)
envelope[:n // 8] = (
1 + np.sin(-np.pi / 2 + tmp / (n / 8 - 1) * np.pi)) / 2
envelope[7 * n // 8:n] = envelope[:n // 8][::-1]
f = f*envelope
elif name == 'gabor': # two modulated Gabor functions in Mallat's book
n = 512
t = np.arange(-n, n + 1)*5 / n
j = np.arange(1, n + 1) / n
g = np.exp(-t**2 * 20)
i1 = slice(2*n // 4, 2 * n // 4 + n)
i2 = slice(n // 4, n // 4 + n)
f1 = 3 * g[i1] * np.exp(1j * (n // 16) * np.pi * j)
f2 = 3 * g[i2] * np.exp(1j * (n // 4) * np.pi * j)
f = f1 + f2
elif name == 'sineoneoverx': # np.sin(1/x) in Mallat's book
n = 1024
i1 = np.arange(-n + 1, n + 1, dtype=float)
i1[i1 == 0] = 1 / 100
i1 = i1 / (n - 1)
f = np.sin(1.5 / i1)
f = f[512:1536]
elif name == 'piece-regular':
f = np.zeros(n)
n_12 = int(np.fix(n / 12))
n_7 = int(np.fix(n / 7))
n_5 = int(np.fix(n / 5))
n_3 = int(np.fix(n / 3))
n_2 = int(np.fix(n / 2))
n_20 = int(np.fix(n / 20))
f1 = -15 * demo_signal('bumps', n)
t = np.arange(1, n_12 + 1) / n_12
f2 = -np.exp(4 * t)
t = np.arange(1, n_7 + 1) / n_7
f5 = np.exp(4 * t)-np.exp(4)
t = np.arange(1, n_3 + 1) / n_3
fma = 6 / 40
f6 = -70 * np.exp(-((t - 0.5) * (t - 0.5)) / (2 * fma**2))
f[:n_7] = f6[:n_7]
f[n_7:n_5] = 0.5 * f6[n_7:n_5]
f[n_5:n_3] = f6[n_5:n_3]
f[n_3:n_2] = f1[n_3:n_2]
f[n_2:n_2 + n_12] = f2
f[n_2 + 2 * n_12 - 1:n_2 + n_12 - 1:-1] = f2
f[n_2 + 2 * n_12 + n_20:n_2 + 2 * n_12 + 3 * n_20] = -np.ones(
n_2 + 2*n_12 + 3*n_20 - n_2 - 2*n_12 - n_20) * 25
k = n_2 + 2 * n_12 + 3 * n_20
f[k:k + n_7] = f5
diff = n - 5 * n_5
f[5 * n_5:n] = f[diff - 1::-1]
# zero-mean
bias = np.sum(f) / n
f = bias - f
elif name == 'piece-polynomial':
f = np.zeros(n)
n_5 = int(np.fix(n / 5))
n_10 = int(np.fix(n / 10))
n_20 = int(np.fix(n / 20))
t = np.arange(1, n_5 + 1) / n_5
f1 = 20 * (t**3 + t**2 + 4)
f3 = 40 * (2 * t**3 + t) + 100
f2 = 10 * t**3 + 45
f4 = 16 * t**2 + 8 * t + 16
f5 = 20 * (t + 4)
f6 = np.ones(n_10) * 20
f[:n_5] = f1
f[2 * n_5 - 1:n_5 - 1:-1] = f2
f[2 * n_5:3 * n_5] = f3
f[3 * n_5:4 * n_5] = f4
f[4 * n_5:5 * n_5] = f5[n_5::-1]
diff = n - 5*n_5
f[5 * n_5:n] = f[diff - 1::-1]
f[n_20:n_20 + n_10] = np.ones(n_10) * 10
f[n - n_10:n + n_20 - n_10] = np.ones(n_20) * 150
# zero-mean
bias = np.sum(f) / n
f = f - bias
elif name == 'riemann':
# Riemann's Non-differentiable Function
sqn = int(np.round(np.sqrt(n)))
idx = np.arange(1, sqn + 1)
idx *= idx
f = np.zeros_like(t)
f[idx - 1] = 1. / np.arange(1, sqn + 1)
f = np.real(np.fft.ifft(f))
else:
raise ValueError(
"unknown name: {}. name must be one of: {}".format(
name, _implemented_signals))
return f