Convolutions, Fast Fourier Transform and polynomials (2022)
alvarorevuelta.com
alvarorevuelta.com
[1]: http://numbers.computation.free.fr/Constants/Algorithms/fft....
Sure, pick a large prime. Double it and add 1 (and call it n). If it's still prime, then you know the prime factorization of n-1. Pick your generator, and check if it raised to the p is 1, or if squaring it is one. If not, it's a generator of the multiplicative group mod n.
Explicit bound is in https://www.daemonology.net/papers/fft.pdf
[1] One-Dimensional Quaternion Discrete Fourier Transform and an Approach to Its Fast Computation:
https://www.mdpi.com/2079-9292/12/24/4974
[2] Convolution Theorems for Quaternion Fourier Transform: Properties and Applications:
https://onlinelibrary.wiley.com/doi/10.1155/2013/162769
[3] On the Matrix Form of the Quaternion Fourier Transform and Quaternion Convolution:
So suppose you have a 1000 digit number. You then take each digit and use it as the coefficient of a 1000 element polynomial. You can then multiply these polynomials together using the fft method as described in the article. To convert the result back to a number you need to do the carries. So if an element is bigger than 10 you carry the excess to the next digit. You then take the coefficients and turn them into numbers.
That's the basic idea. There is some subtlety I've glossed over due to precision needed for the carries and to be sure that rounding the fft result to the nearest integer is correct. That is the way big number multiplication is done in GMP which is the leading Library for this sort of thing.
All of this happens in a field of an elliptic curve so the complexity reduction is greatly appreciated.
https://gmplib.org/manual/Multiplication-Algorithms
GMP has lots of other methods in between schoolbook multiplication and FFT multiplication. A nice one is Karatsuba multiplication which is very easy to understand and delivers O(n^1.58) rather than O(n^2) performance. Python uses this method for multiplying large numbers together
http://gmplib.org/devel/log.i7.1024.png
More context and explanation can be found at: http://gmplib.org/devel/
BTW, I like Bernstein's survey of different multiplication algorithms at
https://cr.yp.to/papers/m3.pdf
(there is a unifying theme about using ring isomorphisms to explain many of the "standard" routines.)
https://hal.science/hal-02070778v2/document
A pop-sci description can be found at
https://theconversation.com/weve-found-a-quicker-way-to-mult...
It derives the FFT algorithm from polynomial multiplication and it’s fantastic.
I rewatch it every 6 months or so.
Some call this a “harmonic” fft, and there are also non-harmonic FFTs:
- the “additive NTT” of [LCH14] on GF(2^n)
- the circle fft on the unit circle X^2+Y^2=1 of a finite field [HLP24]
- the ecfft on a sequence of elliptic curve isogenies [BCKL21]
[LCH14]: https://arxiv.org/abs/1404.3458
[HLP24]: https://eprint.iacr.org/2024/278
[BCKL21]: https://arxiv.org/pdf/2107.08473
Got curious about this recently. I’m not great at citation tracing, but did make it back to this 1995 paper by David Eppstein [0] where he uses it to efficiently solve Subset Sum after an incremental update. Surely Knuth’s TAOCP had it even earlier?
The fact that FFT polynomial multiplication also lets you solve Exact Subset Sum with Repetition in sub-exponential time came as a real shock to me. [1] Crucially, this algo is O(N log N) where N = the maximum element, not N = the set size, so it isn’t a P ≠ NP counterexample or anything.
[0] https://escholarship.org/content/qt6sd695gn/qt6sd695gn.pdf
[1] https://x.com/festivitymn/status/1788362552998580473?s=46&t=...
It should also be noted that, while it was not exactly the birth of the FFT, Cooley-Tukey's 1965 paper [4] on it was what kickstarted research on FFT and its applications. This was just a few years after that.
[1] https://doi.org/10.1090/S0025-5718-1971-0301966-0
[2] https://doi.org/10.1016/S0022-0000(71)80014-4
This paper talks about it in the context of RL https://arxiv.org/abs/1712.06115 but most approaches fit within that paradigm.
> In other words, performing the convolution of two signals in time domain is equivalent to multiplying them in the frequency domain.
Great article, as it breaks down a complex idea into much smaller steps that even my math challenged mind can somehow grasp, but did I miss a step? Or is it left as an exercise to the reader to look up? I was already stretching my math ability to that point, but it felt a little bit like - “and then, draw the rest of the F-ing owl” to me. Is it just me?
Great writing otherwise.
Does it clarify the missing step? Happy to update the post with what's missing.
My impression is that this sort of method isn't used by computer algebra system for this reason.
"(...) or my physics research I have worked with expressions that was just shy of a terabyte long and had > 100M terms"
https://www.youtube.com/watch?v=CcZf_7Fb4Us
https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_cor... is one example.
comparing pure python and numpy fft feels not right to me.
the result will be similar, sure, but the effect might then only show for much larger inputs.
Thanks for the feedback.