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;">"STFT-based $dx/dt$"</span><sp= an style=3D"color:#bcbec4;">)</p> <p> <p> </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 /> ax_.le= gend()<br /> ax_.grid(</span><span style=3D"color:#cf8e6d= ;">True</span><span style=3D"color:#bcbec4;">)</p> <p> <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> </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;">>= ; Hi Ned,</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; 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;">>= ; 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;">>= ; provides a dual window is LTFAT [1]</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; 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;">>= ; Fourier series 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; x(t) =3D Sum[ X[l] 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; d/dt x(t) =3D Sum[ X[l] 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; windows, i.e.,</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; x(t) =3D Sum[ 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; with (p =CE=94t) representing the time shift, (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;">>= ; 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;">>= ; Differentiation with respect to time gives</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; d/dt x(t) =3D Sum[ S[q, p] 2j=CF=80(q =CE=94 f) d(t - p =CE=94t) ex= p(2j=CF=80(q =CE=94 f) t ) ] +</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; &n= bsp;  = ; S[q, p] exp(2j=CF=80(q =CE=94 f) t ) d/dt d(t - p= =CE=94t) ]</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; Note that:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; * 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;">>= ; window d/dt d(t - p =CE=94t).</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; * 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;">>= ; 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;">>= ; 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;">>= ; 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;">>= ; beginning and end of the signal slice.</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; * 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;">>= ; discontinuities.</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; window derivative. Note that Gibb's phenomenon can be observed at t= he</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; beginning and the end of the signal.</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; import matplotlib.pyplot as plt</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; import numpy as np</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; from scipy.signal import ShortTimeFFT</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; from scipy.signal import windows</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; from scipy.fft import rfft, rfftfreq, irfft</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Create periodic test signal and its derivative:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; n, T =3D 1000, 1/1000 # samples and sampling interval for 1 second = signal</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; t =3D np.arange(n) * T # time stamps</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Create single frequency signal and derivative:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; f =3D rfftfreq(n, T)</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; k_c =3D f.searchsorted(7)</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; X =3D np.zeros(len(f))</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; X[k_c] =3D n/2/omega_c</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; x =3D irfft(X, n=3Dn)</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; y =3D irfft(2j*np.pi*f*X, n=3Dn) # dx / dt</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Two ShortTimeFFT instances are needed:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Differentiate dual window per FFT:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Perform the filtering:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; S_x =3D SFT.stft(x)</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Plot windows:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; axx0[0].set(title=3D"Windows")</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; axx0[1].set(title=3D"Dual Windows")</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; 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;">>= ; 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;">>= ; 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;">>= ; 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;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; # Plot signal:</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; </p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; fg1, ax1 =3D plt.subplots()</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; ax1.set(title=3Drf"STFT-based Differentiator for $f_c=3D{f[k_c]}\,$H= z Signal",</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; xlabel=3D"Time $t$&q= uot;, ylabel=3D"Amplitude")</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; ax1.plot(t, omega_c * x, alpha=3D0.5, label=3Dr"$x(t) \cdot 2\pi f_c= $")</p> <p style=3D"margin-top:0;margin-bottom:0;margin-left:0;margin-right:0;">>= ; ax1.plot(t, y, '--', alpha=3D0.5, label=3D"$y =3D dx/dt$")</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==--