Source:
This repo is about visualising the orbits of points in the 2D-plane under the map z -> z*z + c
known as Julia or Mandelbrot sets.
We are looking whether the iterates stay bounded are not. When we associate a colour that reflects this stability, this gives rise to Mandelbrot images.
These images are therefor a colourful representation of where the sequence is stable and how fast does these sequences diverge.
![zoom detail](https://private-user-images.githubusercontent.com/6793008/387149165-f0e9dcaa-34b2-4789-97fd-895355a6a7a9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwNTExNjAsIm5iZiI6MTczOTA1MDg2MCwicGF0aCI6Ii82NzkzMDA4LzM4NzE0OTE2NS1mMGU5ZGNhYS0zNGIyLTQ3ODktOTdmZC04OTUzNTVhNmE3YTkucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDhUMjE0MTAwWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MjRhY2RmZTRmZTY3NjczYmY5ZmJkMTA4ZmI1MWJmYjRhZWM4ZTBhNTYyOGM5OTg1NzJmZTBlNmJiZjNhZDI1YSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.7woIQu5_s8QXTShEy3R_2MiSGL_RcQ14keRpkYORzck)
This repo contains:
- a pur
Zig
computation - two
Livebook
to explore the orbits of points and to zoom into the Mandelbrot set.
The two Livebooks are:
- one proposing a pur
Elixir
orbit explorer. You click and it displays the orbit of any point. - the other proposing a Mandelbrot set explorer with a clickable image to zoom in (and out):
- we have a pur
Elixir
implementation using Numerical Elixir withEXLA
backend of the Mandelbrot set. - we have an enhanced version where the heavy computations are made with running embedded
Zig
code thanks to the libraryZigler
.
- we have a pur
The Zig
code is compiled to WebAssembly
to demonstrate quickly how this renders:
https://ndrean.github.io/zig-assembly-test/
Given a complex number c
and the polynomial p_c(x)=x^2+c
, we compute the sequence of iterates:
p(0)=c
p(p(0))=p(c)=c^2+2
p(p(c)) = c^4+2c^3+c^2+c
...
The set of this sequence is the orbit of the number c
under the map p
.
For example, for c=1
, we have the orbit O_1 = { 0, 1, 2, 5, 26,...}
but for c=-1
, we have a cyclic orbit, O_{-1} = {−1, 0, −1, 0,...}
.
The code below computes "orbits". You select a point and a little animation displays the orbit.
![orbit](https://private-user-images.githubusercontent.com/6793008/386333463-abe4a943-ac31-44db-85c4-906f14f958bd.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwNTExNjAsIm5iZiI6MTczOTA1MDg2MCwicGF0aCI6Ii82NzkzMDA4LzM4NjMzMzQ2My1hYmU0YTk0My1hYzMxLTQ0ZGItODVjNC05MDZmMTRmOTU4YmQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDhUMjE0MTAwWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZDFiZGRlNTE4ZDhjMDMzMjEwNmExNTUxYTI4NjlhY2MyNjA4NWE5NzI1ZGJhZmVhNWFjZWM0OGI0MWYxZDM2OSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.CyA0Qy6i-INg43oREUKxRFBfJ1uwITh4vwOFN1Exn5Q)
Given an image of size W x H in pixels,
- loop over 1..H rows,
i
, and over 1..W columns,j
- compute the coordinate
c
in the 2D-plane projection corresponding to the pixel(i,j)
- compute the "escape" iterations
n
, - compute the RGB colours for this
n
, - append to your final array.
- compute the coordinate
You can explore the fractal by clicking into the 2D-plane.
This happens thanks to KinoJS.Live
.
We have a pur Elixir
version that uses Nx
with the EXLA
backend, and another one that uses embedded Zig
code for the heavy computations. The later is 3-4 magnitude faster mostly because we are running compiled Zig code versus interpreted Elixir code in a Livebook running uncompiled on a BEAM.
![detail](https://private-user-images.githubusercontent.com/6793008/384718058-e747dbc9-02b1-4fd3-9670-73218d632a5a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwNTExNjAsIm5iZiI6MTczOTA1MDg2MCwicGF0aCI6Ii82NzkzMDA4LzM4NDcxODA1OC1lNzQ3ZGJjOS0wMmIxLTRmZDMtOTY3MC03MzIxOGQ2MzJhNWEucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDhUMjE0MTAwWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MzVlN2JjZWZmM2NlNTFjN2Q2NmExNTc2NjhkZDlmMjJhMjRkZmNmMjcwNTU1ZDUzOTVjMzdjNTJmYWM3ZTA5YSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.7CkElSavBj0GxX4I_u54xu-G24pIAysSLDcDEmkHohA)
[Needs latex]
In fact, this set is contained in a disk
$ D_2$ of radius 2. This does not mean that
$ 0_c$ is bounded whenever
We have a more precise criteria: whenever the absolute value
The Mandelbrot set
When the sequence
Since we have to stop the computations at one point, we set a limit
When the sequence
So to each null
or a value between 1 and
With this map:
we are able to plot something.
By convention it is black when the orbit
When you represente the full Mandelbrot set, you can take advantage of the symmetry; indeed, if
Firstly consider some
so
Lastly, consider
so the term grows to infinity and "escapes".
The mandelbrot set
Fix an integer
$n\geq 1$ and consider the set$M_n$ of complex numbers$c$ such that there absolute value at the rank$n$ is less than 2. In other words, $ M_n={c\in\mathbb{C}, , |z_n(c)|\leq 2} $. Then the complex numbers Mandelbrot-stable are precisely the numbers in all these $ M_n$, thus$M = \bigcap_n M_n$ . We conclude by remarking that each$M_n$ is closed as a preimage of the closed set $ [0,2]$ by a continous function, and since$M$ is an intersection of closed sets (not necesserally countable), it is closed.