Skip to content

Commit a873ff9

Browse files
authored
Merge branch 'master' into stable_marriage_in_python
2 parents 15d740e + 3005e35 commit a873ff9

21 files changed

+627
-14
lines changed

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ This file lists everyone, who contributed to this repo and wanted to show up her
5050
- Akash Dhiman
5151
- Vincent Zalzal
5252
- Jonathan D B Van Schenck
53+
- James Goytia
5354
- Amaras

SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* [Introduction](contents/introduction/introduction.md)
55
* [How To Contribute](contents/how_to_contribute/how_to_contribute.md)
66
* [Plotting](contents/plotting/plotting.md)
7+
* [Domain Coloring](contents/domain_coloring/domain_coloring.md)
78
* [Iterated Function Systems](contents/IFS/IFS.md)
89
* [Data Structures](contents/data_structures/data_structures.md)
910
* [Stacks and Queues](contents/stacks_and_queues/stacks_and_queues.md)

contents/IFS/IFS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ Here, instead of tracking children of children, we track a single individual tha
132132
[import:39-52, lang:"cpp"](code/c++/IFS.cpp)
133133
{% sample lang="py" %}
134134
[import:5-12, lang:"python"](code/python/IFS.py)
135+
{% sample lang="c" %}
136+
[import:18-29, lang:"c"](code/c/IFS.c)
135137
{% endmethod %}
136138

137139
If we set the initial points to the on the equilateral triangle we saw before, we can see the Sierpinski triangle again after a few thousand iterations, as shown below:
@@ -199,6 +201,8 @@ In addition, we have written the chaos game code to take in a set of points so t
199201
[import, lang:"cpp"](code/c++/IFS.cpp)
200202
{% sample lang="py" %}
201203
[import, lang:"python"](code/python/IFS.py)
204+
{% sample lang="c" %}
205+
[import, lang:"c"](code/c/IFS.c)
202206
{% endmethod %}
203207

204208
### Bibliography

contents/IFS/code/c/IFS.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <math.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <time.h>
5+
6+
struct point {
7+
double x, y;
8+
};
9+
10+
double drand() {
11+
return ((double) rand() / (RAND_MAX));
12+
}
13+
14+
struct point random_element(struct point *array, size_t n) {
15+
return array[rand() % (int)n];
16+
}
17+
18+
void chaos_game(struct point *in, size_t in_n, struct point *out,
19+
size_t out_n) {
20+
21+
struct point cur_point = {drand(), drand()};
22+
23+
for (int i = 0; i < out_n; ++i) {
24+
out[i] = cur_point;
25+
struct point tmp = random_element(in, in_n);
26+
cur_point.x = 0.5 * (cur_point.x + tmp.x);
27+
cur_point.y = 0.5 * (cur_point.y + tmp.y);
28+
}
29+
}
30+
31+
int main() {
32+
struct point shape_points [3] = {{0.0,0.0}, {0.5,sqrt(0.75)}, {1.0,0.0}};
33+
struct point out_points[1000];
34+
35+
srand(time(NULL));
36+
37+
chaos_game(shape_points, 3, out_points, 1000);
38+
39+
FILE *fp = fopen("out.dat", "w+");
40+
41+
for (int i = 0; i < 1000; ++i) {
42+
fprintf(fp, "%f\t%f\n", out_points[i].x, out_points[i].y);
43+
}
44+
45+
fclose(fp);
46+
47+
return 0;
48+
}
49+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# setting output to file of size 800 x 800
2+
set terminal pngcairo size 1000, 1000
3+
set output 'domain.png'
4+
5+
# sets title for full plot
6+
set title 'f(z)=z^2'
7+
8+
# removes legend
9+
unset key
10+
11+
# projects image onto 2D plane
12+
set view map
13+
14+
# sets aspect ratio of plot to be square
15+
set size square
16+
17+
# sets x and y range and labels
18+
set xrange[-2:2]
19+
set yrange[-2:2]
20+
21+
set xlabel "Re(z)"
22+
set ylabel "Im(z)"
23+
24+
# scaling the x, y, and colorbar tics to zero so they are not seen in the plot
25+
set xtics border scale 0,0
26+
set ytics border scale 0,0
27+
set cbtics border scale 0,0
28+
29+
# sets tics in color bar at 0 and 2pi
30+
set cbtics ("0" -3.14159, '2pi' 3.14159)
31+
32+
set cblabel "Phase Angle"
33+
set cbrange [ -3.14159 : 3.14159 ]
34+
35+
# use hsv for colorbar and set palette to use full hsv space
36+
set palette model HSV
37+
set palette defined ( 0 0 1 1, 1 1 1 1 )
38+
39+
# setting isosamples for output grid and samples for input grid
40+
set isosamples 2000, 2000
41+
set samples 2000, 2000
42+
43+
# setting functions necessary for domain coloring
44+
# setting threshold for gridlines. Smaller threshold will make smaller lines
45+
thresh = 0.1
46+
f(z) = z**2
47+
48+
# atan2 returns a range from -pi to pi, so we need to add pi, but this offsets
49+
# the value by 180 degrees, so we also imput (-y, -x) for another 180 degrees
50+
# to invert rotation
51+
angle(x,y) = (pi + atan2(-y,-x)) / (2*pi)
52+
53+
# complex magnitude
54+
r(x,y) = sqrt(x*x + y*y)
55+
56+
# complex phase and magnitude
57+
theta(x,y) = atan2(y,x)
58+
z(x,y) = r(x,y)*exp(theta(x,y)*sqrt(-1))
59+
60+
# imaginary and real output functions
61+
imaginary_f(z) = imag(f(z))
62+
real_f(z) = real(f(z))
63+
64+
# magnitude contours
65+
magnitude_shading(x,y) = 0.5 + 0.5*(abs(f(z(x,y)))-floor(abs(f(z(x,y)))))
66+
67+
# gridlines
68+
gridlines(x,y) = (abs(sin(real_f(z(x,y))*pi)**thresh) \
69+
* abs(sin(imaginary_f(z(x,y))*pi))**thresh)
70+
71+
# overall coloring function
72+
color(x,y) = hsv2rgb(angle(real_f(z(x,y)), imaginary_f(z(x,y))), \
73+
magnitude_shading(x,y), \
74+
gridlines(x,y))
75+
76+
save_encoding = "utf8"
77+
78+
# Last datafile plotted: "++"
79+
# In this case, it means, "plot the data file created with the
80+
# samples and isosamples"
81+
splot '++' using 1:2:(color($1,$2)) with pm3d lc rgb variable nocontour
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Domain coloring
2+
3+
Domain coloring is a much more complicated plotting technique than those outlined in the [plotting chapter](../plotting/plotting.md) and is used to plot complex functions where both the input and output have imaginary and real components.
4+
For the code in this chapter, we will focus on languages that are easily able to plot two-dimensional images or heat maps, instead of languages meant for number-crunching.
5+
That is to say that this chapter will certainly have a code implementation in gnuplot, but it will not likely have an implementation in C, Fortran, or Java because these languages do not have plotting capabilities in-built.
6+
7+
To start, imagine the following function: $$f(z) = z^2$$.
8+
In this case, we could create a plot that looks like this:
9+
10+
<p>
11+
<img class="center" src="res/z2.png" style="width:70%" />
12+
</p>
13+
14+
This indicates that for various input values along $$z$$, we have different function outputs from $$f(z)$$.
15+
For this function, $$z\in\mathbb{R}$$ is purely in real space and because of this, the output is also in real space.
16+
Now let's imagine another function with complex input $$(z \in \mathbb{C})$$, but a purely real output $$(f(z) \in \mathbb{R})$$:
17+
18+
$$
19+
f(z) = |z|
20+
$$
21+
22+
In this case, this can be plotted as a two-dimensional dataset like so:
23+
24+
<p>
25+
<img class="center" src="res/absz.png" style="width:84%" />
26+
</p>
27+
28+
Here, the $$x$$-axis and $$y$$-axis represent the imaginary and real components of the input variable, respectively.
29+
The color bar represents the output of $$f(z)$$.
30+
31+
At this point, we can start to see the problem.
32+
If the output of $$f(z)$$ also requires plotting of real and imaginary components, then we would need four dimensions to appropriately represent the full function space, one axis for the real component and another for the imaginary component of both the input ($$z$$) and the output of $$f(z)$$!
33+
Unfortunately, feeble human minds are incapable of understanding four spatial dimensions without projecting onto lower dimensionality, so we need to improvise.
34+
35+
We do this by assuming the complex output can be represented in the following form:
36+
37+
$$
38+
z = re^{i \theta} = r(\cos(\theta) + i\sin(\theta))
39+
$$
40+
41+
where, $$r$$ is a complex magnitude and $$\theta$$ is a complex phase.
42+
This is the formula for a circle in the complex plane and we can easily find $$r$$ and $$\theta$$ like so:
43+
44+
$$
45+
\begin{align}
46+
r &= \sqrt{\text{Re}(z)^2 + \text{Im}(z)^2} \\
47+
\theta &= \text{atan}\left(\frac{\text{Im}(z)}{\text{Re}(z)}\right)
48+
\end{align}
49+
$$
50+
51+
Once we have our complex function output in this form, we then color the output domain according to a color space with at least 2 independent dimensions, like RGB (Red, Green, Blue), or HSV (Hue, Saturation, Value) {{ "hsv" | cite }}.
52+
The choice of color space is completely dependent on what the users feel is most visually intuitive.
53+
In any case, one dimension of the color system will be used to represent the complex magnitude and another dimension of the color system will be used to represent the complex phase of the output.
54+
The $$xy$$ grid will be representing the real and imaginary inputs to these functions.
55+
That is to say, we plug every value in the 2D complex plane into the function and then color each pixel based on the function output.
56+
57+
As an example, let's look at the simplest function we can $$f(z) = z$$, but in this case $$z \in \mathbb{C}$$.
58+
If we use an RGB color scheme, where red represents $$\theta$$ and blue represents $$r$$, we can generate the following image:
59+
60+
<p>
61+
<img class="center" src="res/rgb1.png" style="width:84%" />
62+
</p>
63+
64+
As a note here, there is a clear phase discontinuity along the horizontal axis, which is a consequence of the fact that
65+
the complex phase wraps around the origin, ranging from 0 (clear) to $$2\pi$$ (red).
66+
In addition, the edges of the plot are blue because the function's magnitude increases linearly as we move from the origin.
67+
68+
If we instead look at the function $$f(z) = z^2$$, we can generate a similar plot:
69+
70+
<p>
71+
<img class="center" src="res/rgb2.png" style="width:84%" />
72+
</p>
73+
74+
Here, it is clear that the complex phase wraps around the origin twice, creating two separate phase discontinuities on top of each other.
75+
This indicates a $$4\pi$$ phase winding.
76+
For some purposes, such as vortex tracking for inviscid fluids, this visualization is ideal, because a vortex is located precisely at the center of the phase discontinuity {{ "schloss2019" | cite }} {{ "pethick2008" | cite }}.
77+
For other purposes, the discontinuity is visually distracting, and for this reason, many people use an HSV scheme for plotting complex functions {{ "wegert2012" | cite }} {{ "poelkedomain" | cite }} {{ "lundmark2004" | cite }}.
78+
So here is the same function $$\left(f(z)=z^2\right)$$, but using hue to represent the complex phase and saturation to represent the magnitude:
79+
80+
<p>
81+
<img class="center" src="res/hsv.png" style="width:84%" />
82+
</p>
83+
84+
In this plot, the Value for HSV was always set to 1.
85+
When looking at the edges of the plot, the hue changes rapidly, but each color is mirrored on the opposite edge.
86+
This indicates the $$4\pi$$ phase winding we saw in the RGB plot.
87+
Also, because the complex magnitude increases as we move further from the center of the plot, the saturation also increases.
88+
Thus the center of the plot is completely washed out!
89+
We need to fix this in subsequent plots to make them more representative of the actual data.
90+
91+
One easy way to show the increasing complex magnitude without sacrificing phase information is by using contours.
92+
Essentially, at ever integer value of the magnitude, we want to draw some kind of line.
93+
There are a number of ways to generate these lines, and one simple way is by using an alternative shading function like so:
94+
95+
$$
96+
g(r) = r-\lfloor r \rfloor.
97+
$$
98+
99+
This will create the following image:
100+
101+
<p>
102+
<img class="center" src="res/hsv2.png" style="width:84%" />
103+
</p>
104+
105+
This function will essentially create a smooth gradient, but because of the floor operation $$\left(\lfloor \cdot \rfloor \right)$$, the saturation will go from 0 to 1 between each integer value of the magnitude.
106+
Here, it is clear that the magnitude is increasing as $$z^2$$ from the origin; however, because the saturation is fluctuating so much, it is difficult to see the phase pattern next to each contour.
107+
This can be fixed simply by adding an offset to the shading function such that,
108+
109+
$$
110+
g(r) = \frac{1}{2} + \frac{1}{2}\left(r-\lfloor r \rfloor \right).
111+
$$
112+
113+
Which will produce the following image:
114+
115+
<p>
116+
<img class="center" src="res/hsv3.png" style="width:84%" />
117+
</p>
118+
119+
This means that the saturation will fluctuate from $$\frac12$$ to 1 instead of from 0 to 1, which makes it way easier to see phase information next to contours.
120+
Again, there are a lot of different ways to play with these equations, so feel free to use whatever function you want!
121+
As long as some sort of rounding operation is used to establish some form of integer value for the magnitude, it should be possible to create contours of various types.
122+
123+
At this point, changing the saturation shows changes in the complex magnitude, and changing the hue shows changes in the complex phase.
124+
Unfortunately, neither the magnitude nor the phase directly show what is happening in real or imaginary space with the output.
125+
To show this, we might want to draw grid lines that color our pixels black whenever the imaginary or real components of the output function are integer values.
126+
127+
For example, let's go back to a simpler function $$f(z) = z$$.
128+
If we draw lines on this plot, corresponding to integer values in the output, we get a simple grid
129+
130+
<p>
131+
<img class="center" src="res/hsv4.png" style="width:84%" />
132+
</p>
133+
134+
Like before, the choice of which function to use in order to create the grid lines is somewhat arbitrary.
135+
It is important to choose a function that sharply drops to 0 or peaks at 1 for all integer values, and then we simply plug values of $$f(z)$$ into this function.
136+
For the purposes of this chapter, we chose the following function
137+
138+
$$
139+
h(z) = |\sin(\pi\times\text{Re}(f(z)))^t|\times|\sin(\pi\times\text{Im}(f(z)))^t|,
140+
$$
141+
142+
where $$t$$ is some threshold value, and was set to be 0.1 in our plot.
143+
A plot of $$h(z)$$ for $$f(z) = z$$ where $$z\in\mathbb{R}$$ is shown below:
144+
145+
<p>
146+
<img class="center" src="res/shade.png" style="width:84%" />
147+
</p>
148+
149+
So, putting it all together and returning to the function of $$f(z) = z^2$$, we find the following image.
150+
151+
<p>
152+
<img class="center" src="res/hsv5.png" style="width:84%" />
153+
</p>
154+
155+
Here, the diagonal lines through the center represent integer values along the imaginary axis for $$f(z)$$ and the vertical and horizontal lines represent integer values of the real axis for $$f(z)$$.
156+
An easy way to determine which lines correspond to which integer values is by plugging in certain values for $$z$$ into $$f(z)$$.
157+
For example, there is a black line at $$z = 1 + 1i$$ where $$f(z) = 2i$$, this means that all values along that contour correspond to values that are constrained to having an imaginary component of precisely 2.
158+
159+
Overall, there are plenty of interesting ways to plot complex functions and make really compelling and beautiful images!
160+
We will be using domain coloring in other contexts throughout this text when describing methods that heavily use complex space.
161+
162+
## Video Explanation
163+
164+
Here is a video describing domain coloring:
165+
166+
<div style="text-align:center">
167+
<iframe width="560" height="315" src="https://www.youtube.com/embed/EbanExb75mc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
168+
</div>
169+
170+
## Example Code
171+
172+
Here is the full script to generate a domain colored output of $$f(z)=z^2$$.
173+
174+
{% method %}
175+
{% sample lang="gnuplot" %}
176+
[import, lang:"gnuplot"](code/gnuplot/domain_coloring.gp)
177+
{% endmethod %}
178+
179+
### Bibliography
180+
181+
{% references %} {% endreferences %}
182+
183+
<script>
184+
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
185+
</script>
186+
187+
## License
188+
189+
##### Code Examples
190+
191+
The code examples are licensed under the MIT license (found in [LICENSE.md](https://github.com/algorithm-archivists/algorithm-archive/blob/master/LICENSE.md)).
192+
193+
##### Text
194+
195+
The text of this chapter was written by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
196+
197+
[<p><img class="center" src="../cc/CC-BY-SA_icon.svg" /></p>](https://creativecommons.org/licenses/by-sa/4.0/)
198+
199+
##### Images/Graphics
200+
201+
- The image "[z2](res/z2.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
202+
- The image "[absz](res/absz.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
203+
- The image "[rgb1](res/rgb1.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
204+
- The image "[rgb2](res/rgb2.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
205+
- The image "[hsv1](res/hsv.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
206+
- The image "[hsv2](res/hsv2.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
207+
- The image "[hsv3](res/hsv3.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
208+
- The image "[hsv4](res/hsv4.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
209+
- The image "[shade](res/shade.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
210+
- The image "[hsv5](res/hsv5.png)" was created by [James Schloss](https://github.com/leios) and is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
211+
212+
##### Pull Requests
213+
214+
The following pull requests have modified the text or graphics of this chapter:
215+
- none

0 commit comments

Comments
 (0)