Re: Considerations in the design of a ShortTimeFFT window?

Dietrich Brunn via SciPy-Dev <[email protected]> Mon, 04 Mar 2024 17:02:43 +0100
Newsgroups gmane.comp.python.scientific.devel
Message-ID <4574139.cEBGB3zze1@rechentux>
--===============2354477832907900687==
Content-Type: multipart/signed; boundary="nextPart2674302.X9hSmTKtgW";
 micalg="pgp-sha512"; protocol="application/pgp-signature"

--nextPart2674302.X9hSmTKtgW
Content-Type: multipart/alternative; boundary="nextPart4972776.0VBMTVartN";
 protected-headers="v1"
Content-Transfer-Encoding: 7Bit
From: Dietrich Brunn <[email protected]>
To: [email protected]
Cc: [email protected], Edward Richards <[email protected]>
Date: Mon, 04 Mar 2024 17:02:34 +0100
Message-ID: <4574139.cEBGB3zze1@rechentux>
In-Reply-To: <4203513.1IzOArtZ34@rechentux>
MIME-Version: 1.0

This is a multi-part message in MIME format.

--nextPart4972776.0VBMTVartN
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"

The example got truncated while pasting - here is the remainder:


=2E..
ax1.plot(t, dx, alpha=3D0.5, label=3D"STFT-based $dx/dt$")


for ax_ in (*axx0, ax1):
    ax_.legend()
    ax_.grid(True)

plt.show()

Cheers, dietrich



On Monday, 4 March 2024 16:51:51 CET Dietrich Brunn wrote:
> Hi Ned,
> I took the time to think about this a little bit: Unfortunately I am not
> aware of useful literature for choosing STFT windows. Note that the conce=
pt
> of a dual window for the ISTFT does not seem to be widely known in the
> signal processing community. The only other implementation I know, which
> provides a dual window is LTFAT [1]
>=20
> Designing a STFT based differentiator is a bit involving, so let's discuss
> an FFT based one first: The continuous-time signal representation of a
> sampled signal of finite length can be expressed by a complex-valued
> Fourier series  E. g., for signal of duration one, we can write
>=20
> x(t) =3D Sum[  X[l]  exp(2j=CF=80(l =CE=94 f) t ) ] with l being the summ=
ation index.
>=20
> The coefficients X[l] can be calculated with an FFT ([2] discusses this f=
rom
> a different angle). Differentiation with respect to time gives
>=20
> d/dt x(t) =3D Sum[  X[l]  2j=CF=80(l =CE=94 f) exp(2j=CF=80(l =CE=94 f) t=
) ] .
>=20
> Note that x(t) is assumed to be periodic. Hence a discontinuity between
> start and end of signal produces ringing due to Gibb's phenomenon.
>=20
>=20
> The key insight of the ShortTimeFFT implementation is that any signal can=
 be
> represented by a series expansion of time- and frequency-shifted dual
> windows, i.e.,
>=20
> x(t) =3D Sum[  S[q, p] d(t - p =CE=94t) exp(2j=CF=80(q =CE=94 f) t ) ]
>=20
> with (p =CE=94t) representing the time shift,  (q =CE=94 f) the frequency=
 shift, d(t)
> the dual window and S[p, q] the STFT coefficient (consult [3] for details=
).
> Differentiation with respect to time gives
>=20
> d/dt x(t) =3D Sum[ S[q, p] 2j=CF=80(q =CE=94 f)  d(t - p =CE=94t) exp(2j=
=CF=80(q =CE=94 f) t ) ]  +
>                             S[q, p] exp(2j=CF=80(q =CE=94 f) t )  d/dt d(=
t - p =CE=94t) ]
>=20
> Note that:
>=20
> * The window dependent term is parameterized by the derivative of the  du=
al
> window d/dt d(t - p =CE=94t).
>=20
> * If the signal is not periodic in each slice which is stenciled out by t=
he
> sliding window, Gibb's phenomenon will strike again (this is what you
> probably observe in your simulation). Hence it is a good idea to choose a
> dual window, like the Hann window, which suppresses discontinuities at the
> beginning and end of the signal slice.
>=20
> * Not only the dual window but also its derivative needs to suppress those
> discontinuities.
>=20
> The following example shows an example of STFT based differentiation. The
> hop width is chosen small enough to supress Gibb's phenomenon in the dual
> window derivative. Note that Gibb's phenomenon  can be observed at the
> beginning and the end of the signal.
>=20
> import matplotlib.pyplot as plt
>=20
> import numpy as np
>=20
> from scipy.signal import ShortTimeFFT
>=20
> from scipy.signal import windows
>=20
> from scipy.fft import rfft, rfftfreq, irfft
>=20
>=20
> # Create periodic test signal and its derivative:
>=20
> n, T =3D 1000, 1/1000  # samples and sampling interval for 1 second signal
>=20
> t =3D np.arange(n) * T  # time stamps
> # Create single frequency signal and derivative:
>=20
> f =3D rfftfreq(n, T)
> k_c =3D f.searchsorted(7)
> omega_c =3D 2*np.pi*f[k_c]
> X =3D np.zeros(len(f))
> X[k_c] =3D n/2/omega_c
> x =3D irfft(X, n=3Dn)
> y =3D irfft(2j*np.pi*f*X, n=3Dn)  # dx / dt
>=20
> # Two ShortTimeFFT instances are needed:
>=20
> kw =3D dict(hop=3D10, fs=3D1/T,fft_mode=3D'onesided', phase_shift=3DNone)
> SFT =3D ShortTimeFFT.from_dual(windows.hann(32, sym=3DFalse), **kw)
>=20
> # Differentiate dual window per FFT:
>=20
> diff_dual_win =3D irfft(rfft(SFT.dual_win) * 2j*np.pi*rfftfreq(SFT.m_num))
> dSFT =3D ShortTimeFFT.from_dual(diff_dual_win, **kw)
>=20
>=20
> # Perform the filtering:
>=20
--nextPart4972776.0VBMTVartN
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"

<html>
<head>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3DUTF-8">
</head>
<body><p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0=
;">The example got truncated while pasting - here is the remainder:</p>
<br /><br /><p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-r=
ight:0;">...</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;"><sp=
an style=3D"font-family:JetBrains Mono;"><span style=3D"font-size:0.67em;">=
<span style=3D"color:#bcbec4;">ax1.plot(t, dx, </span><span style=3D"color:=
#aa4926;">alpha</span><span style=3D"color:#bcbec4;">=3D</span><span style=
=3D"color:#2aacb8;">0.5</span><span style=3D"color:#bcbec4;">, </span><span=
 style=3D"color:#aa4926;">label</span><span style=3D"color:#bcbec4;">=3D</s=
pan><span style=3D"color:#6aab73;">&quot;STFT-based $dx/dt$&quot;</span><sp=
an style=3D"color:#bcbec4;">)</p>
<p>&nbsp;<p>&nbsp;</span><span style=3D"color:#cf8e6d;">for </span><span st=
yle=3D"color:#bcbec4;">ax_ </span><span style=3D"color:#cf8e6d;">in </span>=
<span style=3D"color:#bcbec4;">(*axx0, ax1):<br />&nbsp;&nbsp;&nbsp; ax_.le=
gend()<br />&nbsp;&nbsp;&nbsp; ax_.grid(</span><span style=3D"color:#cf8e6d=
;">True</span><span style=3D"color:#bcbec4;">)</p>
<p>&nbsp;<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-righ=
t:0;">plt.show()</span></span></span></p>
<br /><p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0=
;"><span style=3D"color:#bcbec4;">Cheers, dietrich</p>
<p>&nbsp;</span></p>
<br /><p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0=
;">On Monday, 4 March 2024 16:51:51 CET Dietrich Brunn wrote:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; Hi Ned,</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; I took the time to think about this a little bit: Unfortunately I am not<=
/p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; aware of useful literature for choosing STFT windows. Note that the conce=
pt</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; of a dual window for the ISTFT does not seem to be widely known in the</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; signal processing community. The only other implementation I know, which<=
/p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; provides a dual window is LTFAT [1]</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; Designing a STFT based differentiator is a bit involving, so let's discus=
s</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; an FFT based one first: The continuous-time signal representation of a</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; sampled signal of finite length can be expressed by a complex-valued</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; Fourier series&nbsp; E. g., for signal of duration one, we can write</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; x(t) =3D Sum[&nbsp; X[l]&nbsp; exp(2j=CF=80(l =CE=94 f) t ) ] with l bein=
g the summation index.</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; The coefficients X[l] can be calculated with an FFT ([2] discusses this f=
rom</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; a different angle). Differentiation with respect to time gives</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; d/dt x(t) =3D Sum[&nbsp; X[l]&nbsp; 2j=CF=80(l =CE=94 f) exp(2j=CF=80(l =
=CE=94 f) t) ] .</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; Note that x(t) is assumed to be periodic. Hence a discontinuity between</=
p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; start and end of signal produces ringing due to Gibb's phenomenon.</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; The key insight of the ShortTimeFFT implementation is that any signal can=
 be</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; represented by a series expansion of time- and frequency-shifted dual</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; windows, i.e.,</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; x(t) =3D Sum[&nbsp; S[q, p] d(t - p =CE=94t) exp(2j=CF=80(q =CE=94 f) t )=
 ]</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; with (p =CE=94t) representing the time shift,&nbsp; (q =CE=94 f) the freq=
uency shift, d(t)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; the dual window and S[p, q] the STFT coefficient (consult [3] for details=
).</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; Differentiation with respect to time gives</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; d/dt x(t) =3D Sum[ S[q, p] 2j=CF=80(q =CE=94 f)&nbsp; d(t - p =CE=94t) ex=
p(2j=CF=80(q =CE=94 f) t ) ]&nbsp; +</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp; S[q, p] exp(2j=CF=80(q =CE=94 f) t )&nbsp; d/dt d(t - p=
 =CE=94t) ]</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; Note that:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; * The window dependent term is parameterized by the derivative of the&nbs=
p; dual</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; window d/dt d(t - p =CE=94t).</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; * If the signal is not periodic in each slice which is stenciled out by t=
he</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; sliding window, Gibb's phenomenon will strike again (this is what you</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; probably observe in your simulation). Hence it is a good idea to choose a=
</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; dual window, like the Hann window, which suppresses discontinuities at th=
e</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; beginning and end of the signal slice.</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; * Not only the dual window but also its derivative needs to suppress thos=
e</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; discontinuities.</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; The following example shows an example of STFT based differentiation. The=
</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; hop width is chosen small enough to supress Gibb's phenomenon in the dual=
</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; window derivative. Note that Gibb's phenomenon&nbsp; can be observed at t=
he</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; beginning and the end of the signal.</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; import matplotlib.pyplot as plt</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; import numpy as np</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; from scipy.signal import ShortTimeFFT</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; from scipy.signal import windows</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; from scipy.fft import rfft, rfftfreq, irfft</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Create periodic test signal and its derivative:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; n, T =3D 1000, 1/1000&nbsp; # samples and sampling interval for 1 second =
signal</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; t =3D np.arange(n) * T&nbsp; # time stamps</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Create single frequency signal and derivative:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; f =3D rfftfreq(n, T)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; k_c =3D f.searchsorted(7)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; omega_c =3D 2*np.pi*f[k_c]</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; X =3D np.zeros(len(f))</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; X[k_c] =3D n/2/omega_c</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; x =3D irfft(X, n=3Dn)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; y =3D irfft(2j*np.pi*f*X, n=3Dn)&nbsp; # dx / dt</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Two ShortTimeFFT instances are needed:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; kw =3D dict(hop=3D10, fs=3D1/T,fft_mode=3D'onesided', phase_shift=3DNone)=
</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; SFT =3D ShortTimeFFT.from_dual(windows.hann(32, sym=3DFalse), **kw)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Differentiate dual window per FFT:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; diff_dual_win =3D irfft(rfft(SFT.dual_win) * 2j*np.pi*rfftfreq(SFT.m_num)=
)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; dSFT =3D ShortTimeFFT.from_dual(diff_dual_win, **kw)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Perform the filtering:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; S_x =3D SFT.stft(x)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; dS_x =3D 2j*np.pi*SFT.f[:, np.newaxis] * S_x</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; dx =3D SFT.istft(dS_x, k1=3Dn) + dSFT.istft(S_x, k1=3Dn)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Plot windows:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; fg0, axx0 =3D plt.subplots(2, 1, sharex=3D'all', tight_layout=3DTrue)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; axx0[0].set(title=3D&quot;Windows&quot;)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; axx0[1].set(title=3D&quot;Dual Windows&quot;)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; axx0[0].plot(SFT.win, '.-', alpha=3D0.5, label=3D'SFT')</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; axx0[0].plot(dSFT.win, '.-', alpha=3D0.5, label=3D'dSFT')</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; axx0[1].plot(SFT.dual_win, '.-', alpha=3D0.5, label=3D'SFT')</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; axx0[1].plot(dSFT.dual_win, '.-', alpha=3D0.5, label=3D'dSFT')</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; # Plot signal:</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; </p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; fg1, ax1 =3D plt.subplots()</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; ax1.set(title=3Drf&quot;STFT-based Differentiator for $f_c=3D{f[k_c]}\,$H=
z Signal&quot;,</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlabel=3D&quot;Time $t$&q=
uot;, ylabel=3D&quot;Amplitude&quot;)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; ax1.plot(t, omega_c * x, alpha=3D0.5, label=3Dr&quot;$x(t) \cdot 2\pi f_c=
$&quot;)</p>
<p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">&gt=
; ax1.plot(t, y, '--', alpha=3D0.5, label=3D&quot;$y =3D dx/dt$&quot;)</p>
<br /><br /></body>
</html>
--nextPart4972776.0VBMTVartN--

--nextPart2674302.X9hSmTKtgW
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE2SZhCS7+RzbiScjDpKQpg4NlCTYFAmXl8JoACgkQpKQpg4Nl
CTbQNQf/WHRwDI5JB2mWTEbjlIbIDfvYB1Db4u8R3K1rkFQmv+E9UGoq5HKPeJt2
cXsGR7baCQsUScPqkjmTX3EkjL/MjhOnUEOcNn8ly2JymK0Dp+ZUA4Sd0r3WNXso
0e4COi54L7FFAhpKpRtTvFiXsXjh8hb/xM/QNsZKN0zIOwXi/pJqYhjQqbLdcVxi
N5uT4FNCvj3RHTauNpjU68VOilxYyLMxWVh/6UXr44S0dVhI4lU2QkehI/WPNl40
X2YF4vlupf/TbGYAgICD0pGzeV4CKnPSV3s0o7c3M1tji8jyUThY/yXHyJ3K7Fhs
kuW7luHXdxRg3qb9NyjEma43JjIu5Q==
=GIxB
-----END PGP SIGNATURE-----

--nextPart2674302.X9hSmTKtgW--




--===============2354477832907900687==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
SciPy-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/scipy-dev.python.org/
Member address: [email protected]

--===============2354477832907900687==--