Skip to content

Commit e590f67

Browse files
author
Travis CI User
committed
Deploy book to GitHub Pages Travis build: 1328
Commit: 02dd35341f4b48ceaf73dde4350526c4b6b72a31
1 parent b72aad7 commit e590f67

File tree

44 files changed

+674
-480
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+674
-480
lines changed

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ This file lists everyone, who contributed to this repo and wanted to show up her
5454
- Amaras
5555
- Jonathan Dönszelmann
5656
- Ishaan Verma
57+
- Delphi1024

contents/IFS/IFS.html

Lines changed: 6 additions & 6 deletions
Large diffs are not rendered by default.

contents/bitlogic/bitlogic.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

contents/bogo_sort/bogo_sort.html

Lines changed: 13 additions & 13 deletions
Large diffs are not rendered by default.

contents/bubble_sort/bubble_sort.html

Lines changed: 14 additions & 14 deletions
Large diffs are not rendered by default.

contents/computational_geometry/computational_geometry.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

contents/computer_graphics/computer_graphics.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

contents/computus/computus.html

Lines changed: 8 additions & 8 deletions
Large diffs are not rendered by default.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
2+
(defun coefficient (time-index freq-index dft-len)
3+
"Calculates a single twiddle factor for the Fourier Transform."
4+
(exp (- (/ (* #c(0 1) 2.0 pi time-index freq-index)
5+
dft-len))))
6+
7+
(defun dft (data)
8+
"Performs the Discrete Fourier Transform"
9+
(let ((dft-len (length data)))
10+
(loop for freq-index from 0 below dft-len collect
11+
(loop for time-index from 0 below dft-len sum
12+
(* (coefficient time-index freq-index dft-len) (elt data time-index))))))
13+
14+
(defun merge-sub-ffts (evens odds)
15+
"Combines the FFTs of the even and odd indices."
16+
(let* ((fft-length (+ (length evens) (length odds)))
17+
;; Calculate coefficients for the odd indices.
18+
(twiddle-factors (loop for i from 0 below (length odds)
19+
collect (coefficient 1.0 i fft-length)))
20+
;; Multiply values with coefficients.
21+
(odd-terms (mapcar #'* odds twiddle-factors)))
22+
;; Combine the two FFTs.
23+
(concatenate 'list
24+
(mapcar #'+ evens odd-terms)
25+
(mapcar #'- evens odd-terms))))
26+
27+
(defun cooley-tukey-rec (data)
28+
"Performs the Fourier Transform using the recursive Cooley-Tukey method."
29+
(if (<= (length data) 1)
30+
data
31+
(loop
32+
for i from 0 below (length data)
33+
;; Split even and odd indexed elements into two seperate lists.
34+
if (evenp i)
35+
collect (elt data i) into evens
36+
else
37+
collect (elt data i) into odds
38+
finally
39+
;; Calculate the Fourier Transform for the two smaller lists and
40+
;; combine them into the Fourier Transform of the full input.
41+
(return (merge-sub-ffts (cooley-tukey-rec evens)
42+
(cooley-tukey-rec odds))))))
43+
44+
(defun reverse-bits (value num-bits)
45+
"Reverses the bits of a value"
46+
(if (= num-bits 1)
47+
value
48+
;; Split bits into two parts.
49+
(let* ((num-low-bits (floor (/ num-bits 2)))
50+
(num-high-bits (- num-bits num-low-bits))
51+
(bit-mask (- (expt 2 num-low-bits) 1))
52+
(lower-half (logand value bit-mask))
53+
(upper-half (ash value (- num-low-bits))))
54+
;; Reverse the bits of each part, then swap the results.
55+
(logior (ash (reverse-bits lower-half num-low-bits) num-high-bits)
56+
(reverse-bits upper-half num-high-bits)))))
57+
58+
(defun bit-shuffle-indices (data)
59+
"Rearanges the elements in a list according to their bit-reversed indices."
60+
(loop
61+
with num-bits = (floor (log (length data) 2))
62+
for i from 0 below (length data)
63+
collect (elt data (reverse-bits i num-bits))))
64+
65+
(defun butterfly (a b coeff)
66+
"Calculates a single butterfly."
67+
(values (+ a (* coeff b)) (- a (* coeff b))))
68+
69+
(defun butterfly-group (data start stride)
70+
"Calculates a single group of butterflies."
71+
(dotimes (i stride)
72+
;; Take two elements which are stride apart and perform a butterfly on them.
73+
(let* ((first-elt-index (+ start i))
74+
(second-elt-index (+ start i stride))
75+
(first-elt (elt data first-elt-index))
76+
(second-elt (elt data second-elt-index))
77+
(coeff (coefficient 1.0 i (* 2 stride))))
78+
(multiple-value-bind (sum difference) (butterfly first-elt second-elt coeff)
79+
;; Write results back into the list.
80+
(setf (elt data first-elt-index) sum)
81+
(setf (elt data second-elt-index) difference)))))
82+
83+
(defun cooley-tukey-iter (data)
84+
"Performs the Fourier Transform using the iterative Cooley-Tukey method."
85+
(loop
86+
;; Bit-shuffle indices.
87+
with shuffled-data = (bit-shuffle-indices data)
88+
for stride = 1 then (* 2 stride)
89+
while (< stride (length shuffled-data))
90+
do
91+
;; Compute butterfly groups for the current stride.
92+
(loop for i from 0 below (length shuffled-data) by (* 2 stride) do
93+
(butterfly-group shuffled-data i stride))
94+
finally (return shuffled-data)))
95+
96+
(defun approx-eql (list1 list2)
97+
(let ((diffs (mapcar #'(lambda (e1 e2) (abs (- e1 e2)))
98+
list1
99+
list2)))
100+
(loop for d in diffs always (< d 1e-9))))
101+
102+
(defun test-fft (data)
103+
(let ((dft-result (dft data))
104+
(rec-result (cooley-tukey-rec data))
105+
(iter-result (cooley-tukey-iter data)))
106+
(format T "~&DFT and recursive Cooley-Tukey approx. equal: ~a"
107+
(approx-eql dft-result rec-result))
108+
(format T "~&DFT and iterative Cooley-Tukey approx. equal: ~a"
109+
(approx-eql dft-result iter-result))
110+
(format T "~&Recursive Cooley-Tukey and iterative Cooley-Tukey approx. equal: ~a"
111+
(approx-eql rec-result iter-result))))
112+
113+
(test-fft '(0.0 0.25 0.5 0.75 0.0 -0.25 -0.5 -0.75))

0 commit comments

Comments
 (0)