ThinkDSP
This notebook contains code examples from Chapter 8: Filtering and Convolution
Copyright 2015 Allen Downey
Smoothing
As the first example, I'll look at daily closing stock prices for Facebook, from its IPO on 2012-05-18 to 2020-03-27 (note: the dataset includes only trading days )
Date | Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|---|
0 | 2012-05-18 | 42.049999 | 45.000000 | 38.000000 | 38.230000 | 38.230000 | 573576400 |
1 | 2012-05-21 | 36.529999 | 36.660000 | 33.000000 | 34.029999 | 34.029999 | 168192700 |
2 | 2012-05-22 | 32.610001 | 33.590000 | 30.940001 | 31.000000 | 31.000000 | 101786600 |
3 | 2012-05-23 | 31.370001 | 32.500000 | 31.360001 | 32.000000 | 32.000000 | 73600000 |
4 | 2012-05-24 | 32.950001 | 33.209999 | 31.770000 | 33.029999 | 33.029999 | 50237200 |
Date | Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|---|
1972 | 2020-03-23 | 149.660004 | 152.309998 | 142.250000 | 148.100006 | 148.100006 | 29830800 |
1973 | 2020-03-24 | 155.210007 | 161.309998 | 152.570007 | 160.979996 | 160.979996 | 30440400 |
1974 | 2020-03-25 | 158.919998 | 162.990005 | 153.059998 | 156.210007 | 156.210007 | 35184300 |
1975 | 2020-03-26 | 158.250000 | 164.000000 | 157.020004 | 163.339996 | 163.339996 | 26556800 |
1976 | 2020-03-27 | 158.199997 | 160.089996 | 154.750000 | 156.789993 | 156.789993 | 24861900 |
Extract the close prices and days since start of series:
Make a window to compute a 30-day moving average and convolve the window with the data. The valid
flag means the convolution is only computed where the window completely overlaps with the signal.
Plot the original and smoothed signals.
Smoothing sound signals
Generate a 440 Hz sawtooth signal.
Make a moving average window.
Plot the wave.
Pad the window so it's the same length as the signal, and plot it.
Apply the window to the signal (with lag=0).
Compute a convolution by rolling the window to the right.
Plot the result of the convolution and the original.
Compute the same convolution using numpy.convolve
.
Frequency domain
Let's see what's happening in the frequency domain.
Compute the smoothed wave using np.convolve
, which is much faster than my version above.
Plot spectrums of the original and smoothed waves:
For each harmonic, compute the ratio of the amplitudes before and after smoothing.
Plot the ratios again, but also plot the FFT of the window.
Gaussian window
Let's compare boxcar and Gaussian windows.
Make the boxcar window.
Make the Gaussian window.
Plot the two windows.
Convolve the square wave with the Gaussian window.
Compute the ratio of the amplitudes.
Compute the FFT of the window.
Plot the ratios and the FFT of the window.
Combine the preceding example into one big function so we can interact with it.
Try out different values of M
and std
.
Convolution theorem
Let's use the Convolution theorem to compute convolutions using FFT.
I'll use the Facebook data again, and smooth it using np.convolve
and a 30-day Gaussian window.
I ignore the dates and treat the values as if they are equally spaced in time.
Plot the original and smoothed data.
Pad the window and compute its FFT.
Apply the convolution theorem.
Plot the two signals (smoothed with numpy and FFT).
Confirm that the difference is small.
scipy.signal
provides fftconvolve
, which computes convolutions using FFT.
Confirm that it gives the same answer, at least approximately.
We can encapsulate the process in a function:
And confirm that it gives the same answer.
Autocorrelation
We can also use the convolution theorem to compute autocorrelation functions.
Compute autocorrelation using numpy.correlate
:
Compute autocorrelation using my fft_convolve
. The window is a reversed copy of the signal. We have to pad the window and signal with zeros and then select the middle half from the result.
Test the function.
Plot the results.
Confirm that the difference is small.