Skip to content

Commit a9466b6

Browse files
committed
fixed merge conflict
2 parents eb3c7b4 + d9d8405 commit a9466b6

File tree

77 files changed

+2940
-1217
lines changed

Some content is hidden

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

77 files changed

+2940
-1217
lines changed

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ Nicole Mazzuca
33
Marius Becker
44
Gathros
55
Jeremie Gillet (- Jie -)
6+
Salim Khatib

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# The Arcane Algorithm Archive
2-
The Arcane Algorithm Archive for all our adventures on LeiosOS / simuleios <br/>
3-
The book can be found here: https://www.gitbook.com/book/leios/algorithm-archive/details.
4-
The github repository can be found here: https://github.com/leios/algorithm-archive.
2+
The Arcane Algorithm Archive is a collaborative effort to create a guide for all important algorithms in all languages.
3+
This goal is obviously too ambitious for a book of any size, but it is a great project to learn from and work on and will hopefully become an incredible resource for programmers in the future.
4+
The book can be found here: https://www.algorithm-archive.org/.
5+
The github repository can be found here: https://github.com/algorithm-archivists/algorithm-archive.
56
Most algorithms have been covered on the youtube channel LeiosOS: https://www.youtube.com/user/LeiosOS
67
and livecoded on Twitch: https://www.twitch.tv/simuleios
78

SUMMARY.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Summary
22

3-
* [README](README.md)
3+
* [Algorithm Archive](README.md)
44
* [TODO](TODO.md)
55
* [Introduction](chapters/introduction.md)
66
* [A Personal Note](chapters/getting_started.md)
@@ -46,5 +46,8 @@
4646
* [Physics Solvers](chapters/physics_solvers/physics_solvers.md)
4747
* [Verlet Integration](chapters/physics_solvers/verlet/verlet.md)
4848
* [Barnes-Hut](chapters/physics_solvers/barnes_hut.md)
49+
* [Quantum Systems](chapters/physics_solvers/quantum/quantum.md)
50+
* [Split-Operator Method](chapters/physics_solvers/quantum/split-op/split-op.md)
4951
* [Data Compression](chapters/data_compression/data_compression.md)
5052
* [Huffman Encoding](chapters/data_compression/huffman/huffman.md)
53+
* [Quantum Information](chapters/QI/QI.md)

book.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"gitbook": "3.x.x",
3-
"plugins": ["mathjax", "bibtex-cite", "creativecommons", "wordcount", "theme-api", "include-codeblock"],
3+
"plugins": ["mathjax", "bibtex-cite", "creativecommons", "wordcount", "theme-api", "include-codeblock", "ga"],
44
"lunr": {
55
"maxIndexSize": 1000000000
66
},
@@ -9,6 +9,9 @@
99
"fixlang": true,
1010
"unindent": true
1111
},
12+
"ga": {
13+
"token": "UA-118252470-1"
14+
},
1215
"theme-api": {
1316
"languages": [
1417
{
@@ -71,7 +74,12 @@
7174
{
7275
"lang": "elm",
7376
"name": "Elm"
77+
},
78+
{
79+
"lang": "LabVIEW",
80+
"name": "LabVIEW"
7481
}
82+
7583
],
7684
"split": false
7785
}

book_ace.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
3+
"plugins": ["mathjax", "bibtex-cite", "creativecommons", "wordcount", "theme-api", "include-codeblock", "ace"],
4+
"lunr": {
5+
"maxIndexSize": 1000000000
6+
},
7+
"pluginsConfig": {
8+
"theme-api": {
9+
"languages": [
10+
{
11+
"lang": "pseudo",
12+
"name": "Pseudocode",
13+
"default": true
14+
},
15+
{
16+
"lang": "jl",
17+
"name": "julia"
18+
},
19+
{
20+
"lang": "cs",
21+
"name": "C#"
22+
},
23+
{
24+
"lang": "c",
25+
"name": "C"
26+
}
27+
],
28+
"split": true
29+
},
30+
"include-codeblock": {
31+
"template": "ace",
32+
"unindent": true,
33+
"theme": "coffee"
34+
}
35+
}
36+
}

chapters/FFT/code/c/fft.c

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,88 @@
1-
// written by Gathros.
2-
31
#include <complex.h>
42
#include <math.h>
5-
6-
// These headers are for presentation not for the algorithm.
73
#include <stdlib.h>
84
#include <time.h>
95
#include <stdio.h>
106

117
#define PI 3.1415926535897932384626
128

13-
void cooley_tukey(double complex *X, const size_t N){
14-
if(N >= 2){
15-
// Splits the array, so the top half are the odd elements and the bottom half are the even ones.
16-
double complex tmp [N/2];
17-
for(size_t i = 0; i < N/2; ++i){
18-
tmp[i] = X[2*i + 1];
19-
X[i] = X[2*i];
20-
}
21-
for(size_t i = 0; i < N/2; ++i){
22-
X[i + N/2] = tmp[i];
23-
}
9+
void cooley_tukey(double complex *X, const size_t N) {
10+
if (N >= 2) {
11+
double complex tmp [N / 2];
12+
for (size_t i = 0; i < N / 2; ++i) {
13+
tmp[i] = X[2*i + 1];
14+
X[i] = X[2*i];
15+
}
16+
for (size_t i = 0; i < N / 2; ++i) {
17+
X[i + N / 2] = tmp[i];
18+
}
2419

25-
// Recursion.
26-
cooley_tukey(X, N/2);
27-
cooley_tukey(X + N/2, N/2);
20+
cooley_tukey(X, N / 2);
21+
cooley_tukey(X + N / 2, N / 2);
2822

29-
// Combine.
30-
for(size_t i = 0; i < N/2; ++i){
31-
X[i + N/2] = X[i] - cexp(-2.0*I*PI*i/N)*X[i + N/2];
32-
X[i] -= (X[i + N/2]-X[i]);
33-
}
34-
}
23+
for (size_t i = 0; i < N / 2; ++i) {
24+
X[i + N / 2] = X[i] - cexp(-2.0 * I * PI * i / N) * X[i + N / 2];
25+
X[i] -= (X[i + N / 2]-X[i]);
26+
}
27+
}
3528
}
3629

37-
void bit_reverse(double complex *X, size_t N){
38-
// Bit reverses the array X[] but only if the size of the array is less then 2^32.
39-
double complex temp;
30+
void bit_reverse(double complex *X, size_t N) {
31+
double complex temp;
4032
unsigned int b;
4133

42-
for(unsigned int i = 0; i < N; ++i){
34+
for (unsigned int i = 0; i < N; ++i) {
4335
b = i;
4436
b = (((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1));
4537
b = (((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2));
4638
b = (((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4));
4739
b = (((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8));
48-
b = ((b >> 16) | (b << 16)) >> (32 - (unsigned int) log2((double)N));
49-
if(b > i){
40+
b = ((b >> 16) | (b << 16)) >>
41+
(32 - (unsigned int) log2((double)N));
42+
if (b > i) {
5043
temp = X[b];
5144
X[b] = X[i];
5245
X[i] = temp;
5346
}
5447
}
5548
}
5649

57-
void iterative_cooley_tukey(double complex *X, size_t N){
58-
int stride;
59-
double complex v,w;
60-
61-
// Bit reverse the array.
62-
bit_reverse(X, N);
63-
64-
// Preform the butterfly on the array.
65-
for(int i = 1; i <= log2((double)N); ++i){
66-
stride = pow(2, i);
67-
w = cexp(-2.0*I*PI/stride);
68-
for(size_t j = 0; j < N; j += stride){
69-
v = 1.0;
70-
for(size_t k = 0; k < stride/2; k++){
71-
X[k + j + stride/2] = X[k + j] - v*X[k + j + stride/2];
72-
X[k + j] -= (X[k + j + stride/2] - X[k + j]);
73-
v *= w;
74-
}
75-
}
76-
}
50+
void iterative_cooley_tukey(double complex *X, size_t N) {
51+
bit_reverse(X, N);
52+
53+
for (int i = 1; i <= log2((double)N); ++i) {
54+
int stride = pow(2, i);
55+
double complex w = cexp(-2.0 * I * PI / stride);
56+
for (size_t j = 0; j < N; j += stride) {
57+
double complex v = 1.0;
58+
for (size_t k = 0; k < stride / 2; ++k) {
59+
X[k + j + stride / 2] = X[k + j] - v * X[k + j + stride / 2];
60+
X[k + j] -= (X[k + j + stride / 2] - X[k + j]);
61+
v *= w;
62+
}
63+
}
64+
}
7765
}
7866

79-
void approx(double complex *X, double complex *Y, size_t N){
80-
// This is to show that the arrays are approximate.
81-
for(size_t i = 0; i < N; ++i){
82-
printf("%f\n", cabs(X[i]) - cabs(Y[i]));
83-
}
67+
void approx(double complex *X, double complex *Y, size_t N) {
68+
for (size_t i = 0; i < N; ++i) {
69+
printf("%f\n", cabs(X[i]) - cabs(Y[i]));
70+
}
8471
}
8572

86-
int main(){
87-
// Initalizing the arrays for FFT.
88-
srand(time(NULL));
89-
const size_t N = 64;
90-
double complex x[N], y[N], z[N];
91-
for(size_t i = 0; i < N; ++i){
92-
x[i] = rand() / (double) RAND_MAX;
93-
y[i] = x[i];
94-
z[i] = x[i];
95-
}
73+
int main() {
74+
srand(time(NULL));
75+
double complex x[64], y[64], z[64];
76+
for (size_t i = 0; i < 64; ++i) {
77+
x[i] = rand() / (double) RAND_MAX;
78+
y[i] = x[i];
79+
z[i] = x[i];
80+
}
9681

97-
// Preform FFT.
98-
cooley_tukey(y, N);
99-
iterative_cooley_tukey(z, N);
82+
cooley_tukey(y, 64);
83+
iterative_cooley_tukey(z, 64);
10084

101-
// Check if the different methods are approximate.
102-
approx(y, z, N);
85+
approx(y, z, 64);
10386

104-
return 0;
87+
return 0;
10588
}

chapters/FFT/cooley_tukey.md

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,3 @@
1-
<script>
2-
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
3-
</script>
4-
$$
5-
\newcommand{\d}{\mathrm{d}}
6-
\newcommand{\bff}{\boldsymbol{f}}
7-
\newcommand{\bfg}{\boldsymbol{g}}
8-
\newcommand{\bfp}{\boldsymbol{p}}
9-
\newcommand{\bfq}{\boldsymbol{q}}
10-
\newcommand{\bfx}{\boldsymbol{x}}
11-
\newcommand{\bfu}{\boldsymbol{u}}
12-
\newcommand{\bfv}{\boldsymbol{v}}
13-
\newcommand{\bfA}{\boldsymbol{A}}
14-
\newcommand{\bfB}{\boldsymbol{B}}
15-
\newcommand{\bfC}{\boldsymbol{C}}
16-
\newcommand{\bfM}{\boldsymbol{M}}
17-
\newcommand{\bfJ}{\boldsymbol{J}}
18-
\newcommand{\bfR}{\boldsymbol{R}}
19-
\newcommand{\bfT}{\boldsymbol{T}}
20-
\newcommand{\bfomega}{\boldsymbol{\omega}}
21-
\newcommand{\bftau}{\boldsymbol{\tau}}
22-
$$
23-
241
## What Makes a Fourier Transform Fast?
252

263
If there were ever an algorithm to radically change the landscape of computer science and engineering by making seemingly impossible problems possible, it would be the Fast Fourier Transform (FFT).
@@ -51,7 +28,9 @@ If we take a sum sinusoidal functions (like $$\sin(\omega t)$$ or $$\cos(\omega
5128
Each constituent wave can be described by only one value: $$\omega$$.
5229
So, instead of representing these curves as seen above, we could instead describe them as peaks in frequency space, as shown below.
5330

54-
![Fourier Example](res/FT_example.png)
31+
<p align="center">
32+
<img src="res/FT_example.png" width="500" height="250" />
33+
</p>
5534

5635
This is what the Fourier Transform does!
5736
After performing the transform, it is now much, much easier to understand precisely which frequencies are in our waveform, which is essential to most areas of signal processing.
@@ -138,9 +117,9 @@ In the end, the code looks like:
138117
{% sample lang="jl" %}
139118
[import:14-31, lang:"julia"](code/julia/fft.jl)
140119
{% sample lang="c" %}
141-
[import:13-35, lang:"c_cpp"](code/c/fft.c)
120+
[import:9-28, lang:"c_cpp"](code/c/fft.c)
142121
{% sample lang="cpp" %}
143-
[import:19-44, lang:"c_cpp"](code/c++/fft.cpp)
122+
[import:27-57, lang:"c_cpp"](code/c++/fft.cpp)
144123
{% sample lang="hs" %}
145124
[import:6-19, lang:"haskell"](code/hs/fft.hs)
146125
{% sample lang="py2" %}
@@ -170,7 +149,9 @@ And at each step, we use the appropriate term.
170149
For example, imagine we need to perform an FFT of an array of only 2 elements.
171150
We can represent this addition with the following (radix-2) butterfly:
172151

173-
![Radix-2, positive W](res/radix-2screen_positive.jpg)
152+
<p align="center">
153+
<img src="res/radix-2screen_positive.jpg" width="400" height="225" />
154+
</p>
174155

175156
Here, the diagram means the following:
176157

@@ -182,7 +163,9 @@ $$
182163

183164
However, it turns out that the second half of our array of $$\omega$$ values is always the negative of the first half, so $$\omega_2^0 = -\omega_2^1$$, so we can use the following butterfly diagram:
184165

185-
![Radix-2](res/radix-2screen.jpg)
166+
<p align="center">
167+
<img src="res/radix-2screen.jpg" width="400" />
168+
</p>
186169

187170
With the following equations:
188171

@@ -197,14 +180,18 @@ Now imagine we need to combine more elements.
197180
In this case, we start with simple butterflies, as shown above, and then sum butterflies of butterflies.
198181
For example, if we have 8 elements, this might look like this:
199182

200-
![Radix-8](res/radix-8screen.jpg)
183+
<p align="center">
184+
<img src="res/radix-8screen.jpg" width="500" height="500" />
185+
</p>
201186

202187
Note that we can perform a DFT directly before using any butterflies, if we so desire, but we need to be careful with how we shuffle our array if that's the case.
203188
In the code snippet provided in the previous section, the subdivision was performed in the same function as the concatenation, so the ordering was always correct; however, if we were to re-order with bit-reversal, this might not be the case.
204189

205190
For example, take a look at the ordering of FFT ([found on wikipedia](https://en.wikipedia.org/wiki/Butterfly_diagram)) that performs the DFT shortcut:
206191

207-
![Butterfly Diagram](res/butterfly_diagram.png)
192+
<p align="center">
193+
<img src="res/butterfly_diagram.png" width="600" height="500" />
194+
</p>
208195

209196
Here, the ordering of the array was simply divided into even and odd elements once, but they did not recursively divide the arrays of even and odd elements again because they knew they would perform a DFT soon thereafter.
210197

@@ -251,3 +238,27 @@ Note: I implemented this in Julia because the code seems more straightforward in
251238
Some rather impressive scratch code was submitted by Jie and can be found here: https://scratch.mit.edu/projects/37759604/#editor
252239
{% endmethod %}
253240

241+
242+
<script>
243+
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
244+
</script>
245+
$$
246+
\newcommand{\d}{\mathrm{d}}
247+
\newcommand{\bff}{\boldsymbol{f}}
248+
\newcommand{\bfg}{\boldsymbol{g}}
249+
\newcommand{\bfp}{\boldsymbol{p}}
250+
\newcommand{\bfq}{\boldsymbol{q}}
251+
\newcommand{\bfx}{\boldsymbol{x}}
252+
\newcommand{\bfu}{\boldsymbol{u}}
253+
\newcommand{\bfv}{\boldsymbol{v}}
254+
\newcommand{\bfA}{\boldsymbol{A}}
255+
\newcommand{\bfB}{\boldsymbol{B}}
256+
\newcommand{\bfC}{\boldsymbol{C}}
257+
\newcommand{\bfM}{\boldsymbol{M}}
258+
\newcommand{\bfJ}{\boldsymbol{J}}
259+
\newcommand{\bfR}{\boldsymbol{R}}
260+
\newcommand{\bfT}{\boldsymbol{T}}
261+
\newcommand{\bfomega}{\boldsymbol{\omega}}
262+
\newcommand{\bftau}{\boldsymbol{\tau}}
263+
$$
264+

0 commit comments

Comments
 (0)