Important note: this particular section will be expanded upon after the Fourier transform and Fast Fourier Transform (FFT) chapters have been revised.
Now, let me tell you about a bit of computational magic:
Convolutions can be performed with Fourier Transforms!
This is crazy, but it is also incredibly hard to explain, so let me do my best.
As described in the chapter on Fourier Transforms, Fourier Transforms allow programmers to move from real space to frequency space.
When we transform a wave into frequency space, we can see a single peak in frequency space related to the frequency of that wave.
No matter what function we send into a Fourier Transform, the frequency-space image can be interpreted as a series of different waves with a specified frequency.
Each of these waves is parameterized by another
So here's the idea: if we take two functions
Where
At first, this might not seem particularly intuitive, but remember that frequency space is essentially composed of a set of exponentials. As mentioned in the section about Multiplication as a Convolution, multiplication in base 10 space is also a convolution. The convolutional theorem extends this concept into multiplication with any set of exponentials, not just base 10. Obviously, this description is still lacking a bit of explanation, but I promise we will add more when revising the Fourier transform sections!
By using a Fast Fourier Transform (FFT) in code, this can take a standard convolution on two arrays of length
{% method %} {% sample lang="jl" %} import:5-8, lang:"julia" {% endmethod %}
This method also has the added advantage that it will always output an array of the size of your signal; however, if your signals are not of equal size, we need to pad the smaller signal with zeros. Also note that the Fourier Transform is a periodic or cyclic operation, so there are no real edges in this method, instead the arrays "wrap around" to the other side, creating a cyclic convolution like we showed in the periodic boundary condition case for the one-dimensional convolution.
For this example code, we will be using two sawtooth functions as we did in the chapter on one-dimensional convolutions:
{% method %} {% sample lang="jl" %} import, lang:"julia" {% sample lang="py" %} import, lang:"python" {% endmethod %}
This should produce the following output:
<script> MathJax.Hub.Queue(["Typeset",MathJax.Hub]); </script>The code examples are licensed under the MIT license (found in LICENSE.md).
- The image "Cyclic" was created by James Schloss and is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.
The text of this chapter was written by James Schloss and is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.
After initial licensing (#560), the following pull requests have modified the text or graphics of this chapter:
- none