Skip to content

Fix the size of the diagrams. Add res folders. #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions chapters/FFT/cooley_tukey.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ If we take a sum sinusoidal functions (like $$\sin(\omega t)$$ or $$\cos(\omega
Each constituent wave can be described by only one value: $$\omega$$.
So, instead of representing these curves as seen above, we could instead describe them as peaks in frequency space, as shown below.

<p align="center">
<img src="res/FT_example.png" width="500" height="250" />
<p>
<img class="center" src="res/FT_example.png" width="500" />
</p>

This is what the Fourier Transform does!
Expand Down Expand Up @@ -149,8 +149,8 @@ And at each step, we use the appropriate term.
For example, imagine we need to perform an FFT of an array of only 2 elements.
We can represent this addition with the following (radix-2) butterfly:

<p align="center">
<img src="res/radix-2screen_positive.jpg" width="400" height="225" />
<p>
<img class="center" src="res/radix-2screen_positive.jpg" width="400" />
</p>

Here, the diagram means the following:
Expand All @@ -163,8 +163,8 @@ $$

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:

<p align="center">
<img src="res/radix-2screen.jpg" width="400" />
<p>
<img class="center" src="res/radix-2screen.jpg" width="400" />
</p>

With the following equations:
Expand All @@ -180,17 +180,17 @@ Now imagine we need to combine more elements.
In this case, we start with simple butterflies, as shown above, and then sum butterflies of butterflies.
For example, if we have 8 elements, this might look like this:

<p align="center">
<img src="res/radix-8screen.jpg" width="500" height="500" />
<p>
<img class="center" src="res/radix-8screen.jpg" width="500" />
</p>

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.
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.

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:

<p align="center">
<img src="res/butterfly_diagram.png" width="600" height="500" />
<p>
<img class="center" src="res/butterfly_diagram.png" width="600" />
</p>

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.
Expand Down
4 changes: 2 additions & 2 deletions chapters/data_compression/huffman/huffman.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ Well, here we build it from the bottom up like so:
And that's it.
Here's an image of what this might look like for the phrase `bibbity_bobbity`:

<p align="center">
<img src="res/huffman_tree.png" width="500" height="500" />
<p>
<img class="center" src="res/huffman_tree.png" width="500" />
</p>

This will create a codebook that looks like this:
Expand Down
8 changes: 6 additions & 2 deletions chapters/differential_equations/euler/euler.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ Now, solving this set of equations in this way is known as the *forward* Euler M
In fact, there is another method known as the [*backward* Euler Method](backward_euler.md), which we will get to soon enough.
For now, it is important to note that the error of these methods depend on the timestep chosen.

<div style="text-align:center"><img src ="res/error.png" /></div>
<p>
<img class="center" src="res/error.png" />
</p>

For example, here we see dramatically different results for different timesteps for solving the ODE $$y' = \frac{x^3}{6}$$, whose solution is $$y = \frac{x^2}{2}$$.
The blue line is the analytical solution, the green is with a timestep of 0.5 and the red is with a timestep of 1.
Expand All @@ -67,7 +69,9 @@ The solution here is $$y(t) = e^{-3t}$$ and we can find this solution somewhat e
That said, by choosing a larger timestep, we see the Euler method's solution oscillate above and below 0, which should *never* happen.
If we were to take the Euler method's solution as valid, we would incorrectly assume that $$e^{-3t}$$ will become negative!

<div style="text-align:center"><img src ="res/instability.png" /></div>
<p>
<img class="center" src="res/instability.png" />
</p>

Like above, the blue line is the analytical solution, the green is with a timestep of 0.5 and the red is with a tiemstep of 1.
Here, it's interesting that we see 2 different instability patterns.
Expand Down
8 changes: 4 additions & 4 deletions chapters/euclidean_algorithm/euclidean.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ The algorithm is a simple way to find the *greatest common divisor* (GCD) of two

Here, we simply line the two numbers up every step and subtract the lower value from the higher one every timestep. Once the two values are equal, we call that value the greatest common divisor. A graph of `a` and `b` as they change every step would look something like this:

<p align="center">
<img src="res/subtraction.png" width="500" height="500" />
<p>
<img class="center" src="res/subtraction.png" width="500" />
</p>

Modern implementations, though, often use the modulus operator (%) like so
Expand Down Expand Up @@ -64,8 +64,8 @@ Modern implementations, though, often use the modulus operator (%) like so

Here, we set `b` to be the remainder of `a%b` and `a` to be whatever `b` was last timestep. Because of how the modulus operator works, this will provide the same information as the subtraction-based implementation, but when we show `a` and `b` as they change with time, we can see that it might take many fewer steps:

<p align="center">
<img src="res/modulus.png" width="500" height="500" />
<p>
<img class="center" src="res/modulus.png" width="500" />
</p>

The Euclidean Algorithm is truly fundamental to many other algorithms throughout the history of computer science and will definitely be used again later. At least to me, it's amazing how such an ancient algorithm can still have modern use and appeal. That said, there are still other algorithms out there that can find the greatest common divisor of two numbers that are arguably better in certain cases than the Euclidean algorithm, but the fact that we are discussing Euclid two millenia after his death shows how timeless and universal mathematics truly is. I think that's pretty cool.
Expand Down
8 changes: 4 additions & 4 deletions chapters/monte_carlo/monte_carlo.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Since it's a square, the $$\text{length}$$ and $$\text{width}$$ are the same, so
If we embed a circle into the square with a radius $$r = \text{length}$$ (shown below), then it's area is $$\text{Area}_{\text{circle}}=\pi r^2$$.
For simplicity, we can also say that $$\text{Area}_{\text{square}}=4r^2$$.

<p align="center">
<img src="res/square_circle.png" width="300"/>
<p>
<img class="center" src="res/square_circle.png" width="300"/>
</p>

Now, let's say we want to find the area of the circle without an equation.
Expand Down Expand Up @@ -59,8 +59,8 @@ $$

If we use a small number of points, this will only give us a rough approximation, but as we start adding more and more points, the approximation becomes much, much better (as shown below)!

<p align="center">
<img src="res/monte_carlo.gif" width="400"/>
<p>
<img class="center" src="res/monte_carlo.gif" width="400"/>
</p>

The true power of monte carlo comes from the fact that it can be used to integrate literally any object that can be embedded into the square.
Expand Down
8 changes: 6 additions & 2 deletions chapters/physics_solvers/verlet/verlet.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,19 @@ Both of these methods work simply by iterating timestep-by-timestep and can be w
{% sample lang="scratch" %}
### Scratch
Submitted by Jie
![Scratch 2D implementation](code/scratch/verlet_scratch.png)
<p>
<img class="center" src="code/scratch/verlet_scratch.png" />
</p>
Link: [https://scratch.mit.edu/projects/173039394/](https://scratch.mit.edu/projects/173039394/)
{% sample lang="matlab" %}
### Matlab
[import, lang:"matlab"](code/matlab/verlet.m)
{% sample lang="LabVIEW" %}
### LabVIEW
Submitted by P. Mekhail
![Verlet LabVIEW](code/labview/verlet_labview.png)
<p>
<img class="center" src="code/labview/verlet_labview.png" />
</p>
{% sample lang="javascript" %}
### JavaScript
[import, lang:"javascript"](code/javascript/verlet.js)
Expand Down
25 changes: 19 additions & 6 deletions chapters/principles_of_code/building_blocks/bitlogic.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,27 +94,40 @@ There are more complicated things that can be done with the bitshift operators;
In addition to the bitshift operations, there are a number of logical operations that can be performed on one or two bits together.
These operations are called *gates*, and follow soemwhat straightforward logic.
The *AND* gate, for example, reads in 2 bits and will only output a 1 value if both inputs are 1. This can be seen in the corresponding truth table:
![AND Truth Table](and.jpg)

<p>
<img class="center" src="res/and.jpg" width="423" />
</p>

The *OR* gate will output 1 if either input bits are 1:

![OR Truth Table](or.jpg)
<p>
<img class="center" src="res/or.jpg" width="423" />
</p>

The *exclusive OR* or *XOR* gate is the same as the *OR* gate, but will not output 1 if both bits are 1:

![XOR Truth Table](xor.jpg)
<p>
<img class="center" src="res/xor.jpg" width="423" />
</p>

The *NOT* gate simply flips the input bit:

![NOT Truth Table](not.jpg)
<p>
<img class="center" src="res/not.jpg" width="423" />
</p>

By combining the NOT and AND gates, we get the *NAND* gate:

![NAND Truth Table](nand.jpg)
<p>
<img class="center" src="res/nand.jpg" width="423" />
</p>

And NOT and OR create *NOR*:

![NOR Truth Table](nor.jpg)
<p>
<img class="center" src="res/nor.jpg" width="423" />
</p>

There are a few other gates, but this is enough for most things. We'll add more as the need arises!

Expand Down
4 changes: 3 additions & 1 deletion chapters/principles_of_code/notation/notation.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ We've outlined the most common complexity cases of different algorithms here, bu
Which is better: $$O(n^2)$$ or $$O(log(n))$$?
Well, let's plot all the different cases out, and the answer should become obvious.

![Complexity plot](cplot.png)
<p>
<img class="center" src="res/cplot.png" />
</p>

Here, we see each of the complexity cases as $$n$$ increases.
Clearly, linear time is not bad when compared to polynomial or exponential time; however, if you can manage something in logarithmic or constant time, do it!
Expand Down
8 changes: 6 additions & 2 deletions chapters/principles_of_code/version_control.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,18 @@ If you just want to get the feel for how git works, I suggest going to [github.c
Note that you will not be able to contribute to any old directory on github, simply because if anyone could contribute any code they wanted to any repository they wanted, the world would become incredibly chaotic.
Because of this, you may want to create a repository under your own github username or make your own copy of someone elses code on github by clicking the *fork* button:

![How to fork](fork.png)
<p>
<img class="center" src="res/fork.png" />
</p>

Note that if you have a fork of a particular code repository, you can ask the owner of the original code repository to pull your changes into their version of the code with a *pull request*, but we are getting ahead of ourselves here.
If you cannot think of what repository to work on and want to collaborate on this project in the future, feel free to fork the [Algorithm Archive](https://github.com/algorithm-archivists/algorithm-archive) and modify that!

Regardless, as long as there is a repository under your username on github, we can continue by linking that remote github location to your local git directory. First, we need to find the url of the github repository, as shown here:

![How to clone](clone.png)
<p>
<img class="center" src="res/clone.png" />
</p>

Note that there are 2 provided urls here, one for *ssh* and another for *https*. From the user's perspective, the difference between the two is minimal: ssh requires the user to type only a password when interacting with the remote github repository, while https requires both a username and password.
Now, you will probably be interacting with github a lot, so ssh will definitely save time and is preferred for many people who use git a lot; however, [there is some initial set-up](https://help.github.com/articles/connecting-to-github-with-ssh/).
Expand Down
7 changes: 3 additions & 4 deletions chapters/taylor/taylor_series.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@ Note that here, we assume the acceleration to be constant, but it could technica

Truth be told, the Taylor Series Expansion can be found in the most unusual places and is used as the foundation of many different algorithms throughout this book. At first, it might not seem obvious why, but we can approximate almost any smooth function with a Taylor Series Expansion, and the more terms we include, the better our approximation becomes! For example, take Figure 1. Any function can be approximated as a sum of all the derivatives for that function. If we evaluate these derivatives at any point, we closely approximate the actual function.

![Function sum][function_sum]
<p>
<img class="center" src="res/function_sum.png" />
</p>

This shows the true power of the Taylor Series Expansion. It allows us to more easily tackle complicated functions by approximating them as functions we can actually use and imagine!

[function_sum]: function_sum.png


<script>
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
</script>
Expand Down
22 changes: 12 additions & 10 deletions chapters/tree_traversal/tree_traversal.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ This has not been implemented in your chosen language, so here is the Julia code

At least to me, this makes a lot of sense. We fight recursion with recursion! First, we first output the node we are on and then we call `DFS_recursive(...)` on each of its children nodes. This method of tree traversal does what its name implies: it goes to the depths of the tree first before going through the rest of the branches. In this case, the ordering looks like:

<p align="center">
<img src="res/DFS_pre.png" width="500" height="500" />
<p>
<img class="center" src="res/DFS_pre.png" width="500" />
</p>

Note that the in the code above, we are missing a crucial step: *checking to see if the node we are using actually exists!* Because we are using a vector to store all the nodes, we will be careful not to run into a case where we call `DFS_recursive(...)` on a node that has yet to be initialized; however, depending on the language we are using, we might need to be careful of this to avoid recursion errors!
Expand Down Expand Up @@ -85,8 +85,8 @@ This has not been implemented in your chosen language, so here is the Julia code
[import:8-9, lang:"haskell"](code/haskell/TreeTraversal.hs)
{% endmethod %}

<p align="center">
<img src="res/DFS_post.png" width="500" height="500" />
<p>
<img class="center" src="res/DFS_post.png" width="500" />
</p>

In this case, the first node visited is at the bottom of the tree and moves up the tree branch by branch. In addition to these two types, binary trees have an *in-order* traversal scheme that looks something like this:
Expand Down Expand Up @@ -116,8 +116,8 @@ This has not been implemented in your chosen language, so here is the Julia code
[import:11-15, lang:"haskell"](code/haskell/TreeTraversal.hs)
{% endmethod %}

<p align="center">
<img src="res/DFS_in.png" width="500" height="500" />
<p>
<img class="center" src="res/DFS_in.png" width="500" />
</p>


Expand Down Expand Up @@ -157,8 +157,8 @@ This has not been implemented in your chosen language, so here is the Julia code

All this said, there are a few details about DFS that might not be idea, depending on the situation. For example, if we use DFS on an incredibly long tree, we will spend a lot of time going further and further down a single branch without searching the rest of the data structure. In addition, it is not the natural way humans would order a tree if asked to number all the nodes from top to bottom. I would argue a more natural traversal order would look something like this:

<p align="center">
<img src="res/BFS_simple.png" width="500" height="500" />
<p>
<img class="center" src="res/BFS_simple.png" width="500" />
</p>

And this is exactly what Breadth-First Search (BFS) does! On top of that, it can be implemented in the same way as the `DFS_stack(...)` function above, simply by swapping the `stack` for a `queue`, which is similar to a stack, exept that it only allows you to interact with the very first element instead of the last. In code, this looks something like:
Expand Down Expand Up @@ -209,11 +209,13 @@ tree_traversal.c
### JavaScript
[import, lang:"javascript"](code/javascript/tree.js)
{% sample lang="py" %}
### Python
### Python
[import, lang:"python"](code/python/Tree_example.py)
{% sample lang="scratch" %}
### Scratch
![scratch tree](code/scratch/scratch_tree.png)
<p>
<img class="center" src="code/scratch/scratch_tree.png" />
</p>
{% sample lang="rs"%}
### Rust
[import, lang:"rust"](code/rust/tree.rs)
Expand Down
6 changes: 6 additions & 0 deletions styles/website.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@
.book .book-body .page-wrapper {
margin-bottom: 12em;
}

img.center {
display: block;
margin-left: auto;
margin-right: auto;
}