##ThinkDSP
This notebook contains solutions to exercises in Chapter 6: Discrete Cosine Transform
Copyright 2015 Allen Downey
Exercise: In this chapter I claim that analyze1
takes time proportional to and analyze2
takes time proportional to . To see if that's true, run them on a range of input sizes and time them. In IPython, you can use the magic command %timeit
.
If you plot run time versus input size on a log-log scale, you should get a straight line with slope 3 for analyze1
and slope 2 for analyze2
. You also might want to test dct_iv
and scipy.fftpack.dct
.
I'll start with a noise signal and an array of power-of-two sizes
The following function takes an array of results from a timing experiment, plots the results, and fits a straight line.
Here are the results for analyze1
.
The estimated slope is close to 2, not 3, as expected. One possibility is that the performance of np.linalg.solve
is nearly quadratic in this range of array sizes.
The line is curved, which suggests that we have not reached the array size where the runtime shows cubic growth. With larger array sizes, the estimated slope increases, so maybe it eventually converges on 3.
To finish this exercise, generate similar results for the other functions.
Exercise: One of the major applications of the DCT is compression for both sound and images. In its simplest form, DCT-based compression works like this:
Break a long signal into segments.
Compute the DCT of each segment.
Identify frequency components with amplitudes so low they are inaudible, and remove them. Store only the frequencies and amplitudes that remain.
To play back the signal, load the frequencies and amplitudes for each segment and apply the inverse DCT.
Implement a version of this algorithm and apply it to a recording of music or speech. How many components can you eliminate before the difference is perceptible?
thinkdsp
provides a class, Dct
that is similar to a Spectrum
, but which uses DCT instead of FFT.
As an example, I'll use a recording of a saxophone:
Here's a short segment:
And here's the DCT of that segment:
There are only a few harmonics with substantial amplitude, and many entries near zero.
You might want to write a function that takes a DCT and sets elements below some threshold to 0. Test it with a short segment.
To compress a longer segment, we can make a DCT spectrogram. The following function is similar to wave.make_spectrogram
except that it uses the DCT.
To complete this exercise, use this function to make a DCT spectrogram and compress it. Then you can convert back to a wave using Spectrogram.make_wave
.