📚 The CoCalc Library - books, templates and other resources
License: OTHER
Empirical order of growth
Sometimes we can figure out what order of growth a function belongs to by running it with a range of problem sizes and measuring the run time.
order.py
contains functions from Appendix A we can use to estimate order of growth.
DFT
Here's an implementation of DFT using outer product to construct the transform matrix, and dot product to compute the DFT.
Here's an example comparing this implementation of DFT with np.fft.fft
Now, let's see what the asymptotic behavior of np.fft.fft
looks like:
Up through the biggest array I can handle on my computer, it's hard to distinguish from linear.
And let's see what my implementation of DFT looks like:
Definitely not linear. How about quadratic?
Looks quadratic.
Implementing FFT
Ok, let's try our own implementation of FFT.
First I'll get the divide and conquer part of the algorithm working:
This version breaks the array in half, uses dft
to compute the DFTs of the halves, and then uses the D-L lemma to stich the results back up.
Let's see what the performance looks like.
Looks about the same as DFT, quadratic.
Exercise: Starting with fft_norec, write a function called fft_rec that's fully recursive; that is, instead of using dft
to compute the DFTs of the halves, it should use fft_rec
. Of course, you will need a base case to avoid an infinite recursion. You have two options:
The DFT of an array with length 1 is the array itself.
If the parameter,
ys
, is smaller than some threshold length, you could use DFT.
Use test_fft_rec
, below, to check the performance of your function.
If things go according to plan, your FFT implementation should be faster than dft
and fft_norec
, but probably not as fast as np.fft.fft
. And it might be a bit steeper than linear.