Given a sequence of complex numbers (the coefficients on the successive terms of a complex polynomial, perhaps), its length a power of 2, compute its discrete Fourier transform. For a detailed explanation of the background to the algorithm, consult Introduction to algorithms, by Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest (Cambridge, Massachusetts: MIT Press, 1990), chapter 32.
The idea of the algorithm is to use recursive calls to fft to compute the
Fourier transforms of the ``unshuffled'' halves of the sequence. One then
obtains the first (respectively, second) len
/2 components of
the solution by multiplying each component of the Fourier transform of the
``odd'' half by the corresponding len
-th complex root of
unity, then adding it to (respectively, subtracting it from) the
corresponding component of the Fourier transform of the ``even'' half.
The internal unshuffle
procedure separates the elements of a
given sequence into two shorter sequences, the first containing the
elements in the even-numbered positions of the given sequence, the second
containing those in the odd-numbered positions. It returns a pair of which
the first shorter sequence is the car and the second the cdr. (This
version of unshuffle
presupposes that the sequence it is given
is always of even length.)
(define fft (let ((pi 3.14159265358979323846) (unshuffle (lambda (seq) (let loop ((rest seq) (evens '()) (odds '())) (if (null? rest) (cons (reverse evens) (reverse odds)) (loop (cddr rest) (cons (car rest) evens) (cons (cadr rest) odds))))))) (lambda (sequence) (let ((len (length sequence))) (if (= len 1) sequence (let ((nth-root (make-polar 1 (/ (* 2 pi) len))) ; principal len-th root of unity (half-len (quotient len 2)) (packs (unshuffle sequence))) (let loop ((step 0) (root 1) (evens (fft (car packs))) (odds (fft (cdr packs))) (front '()) (rear '())) (if (= step half-len) (append (reverse front) (reverse rear)) (loop (+ step 1) (* root nth-root) (cdr evens) (cdr odds) (cons (+ (car evens) (* root (car odds))) front) (cons (- (car evens) (* root (car odds))) rear))))))))))
This document is available on the World Wide Web as
http://www.math.grin.edu/~stone/events/scheme-workshop/fft.html