scipy.signal¶
Functions in the signal
module can be called by prepending them by
scipy.signal.
. The module defines the following two functions:
sosfilt¶
scipy
:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.sosfilt.html
Filter data along one dimension using cascaded second-order sections.
The function takes two positional arguments, sos
, the filter
segments of length 6, and the one-dimensional, uniformly sampled data
set to be filtered. Returns the filtered data, or the filtered data and
the final filter delays, if the zi
keyword arguments is supplied.
The keyword argument must be a float ndarray
of shape
(n_sections, 2)
. If zi
is not passed to the function, the
initial values are assumed to be 0.
# code to be run in micropython
from ulab import numpy as np
from ulab import scipy as spy
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
sos = [[1, 2, 3, 1, 5, 6], [1, 2, 3, 1, 5, 6]]
y = spy.signal.sosfilt(sos, x)
print('y: ', y)
y: array([0.0, 1.0, -4.0, 24.0, -104.0, 440.0, -1728.0, 6532.000000000001, -23848.0, 84864.0], dtype=float)
# code to be run in micropython
from ulab import numpy as np
from ulab import scipy as spy
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
sos = [[1, 2, 3, 1, 5, 6], [1, 2, 3, 1, 5, 6]]
# initial conditions of the filter
zi = np.array([[1, 2], [3, 4]])
y, zf = spy.signal.sosfilt(sos, x, zi=zi)
print('y: ', y)
print('\n' + '='*40 + '\nzf: ', zf)
y: array([4.0, -16.0, 63.00000000000001, -227.0, 802.9999999999999, -2751.0, 9271.000000000001, -30775.0, 101067.0, -328991.0000000001], dtype=float)
========================================
zf: array([[37242.0, 74835.0],
[1026187.0, 1936542.0]], dtype=float)
spectrogram¶
In addition to the Fourier transform and its inverse, ulab
also
sports a function called spectrogram
, which returns the absolute
value of the Fourier transform. This could be used to find the dominant
spectral component in a time series. The arguments are treated in the
same way as in fft
, and ifft
.
# code to be run in micropython
from ulab import numpy as np
from ulab import scipy as spy
x = np.linspace(0, 10, num=1024)
y = np.sin(x)
a = spy.signal.spectrogram(y)
print('original vector:\t', y)
print('\nspectrum:\t', a)
original vector: array([0.0, 0.009775015390171337, 0.01954909674625918, ..., -0.5275140569487312, -0.5357931822978732, -0.5440211108893639], dtype=float64)
spectrum: array([187.8635087634579, 315.3112063607119, 347.8814873399374, ..., 84.45888934298905, 347.8814873399374, 315.3112063607118], dtype=float64)
As such, spectrogram
is really just a shorthand for
np.sqrt(a*a + b*b)
:
# code to be run in micropython
from ulab import numpy as np
from ulab import scipy as spy
x = np.linspace(0, 10, num=1024)
y = np.sin(x)
a, b = np.fft.fft(y)
print('\nspectrum calculated the hard way:\t', np.sqrt(a*a + b*b))
a = spy.signal.spectrogram(y)
print('\nspectrum calculated the lazy way:\t', a)
spectrum calculated the hard way: array([187.8635087634579, 315.3112063607119, 347.8814873399374, ..., 84.45888934298905, 347.8814873399374, 315.3112063607118], dtype=float64)
spectrum calculated the lazy way: array([187.8635087634579, 315.3112063607119, 347.8814873399374, ..., 84.45888934298905, 347.8814873399374, 315.3112063607118], dtype=float64)