Nello scorso articolo, tramite poche righe di codice perl, abbiamo curiosato all’interno del frastagliato universo frattale, rappresentando gli insiemi di Mandelbrot e Julia in modalità rigorosamente monocromatica.
E’ davvero meraviglioso quando la natura ci sorprende facendo coesistere l’infinitamente semplice con lo smisuratamente complesso come in questo caso. Solo Lei può permettersi di farlo in modo così raffinato ed esuberante: una banale successione quadratica nel dominio dei numeri complessi, apparentemente insignificante ed innocua, è in grado di generare ricorsivamente “uno dei più complessi oggetti della matematica”; così è stato definito l’insieme di Mandelbrot da Benoît Mandelbrot, Heinz-Otto Peitgen e John H. Hubbard suoi iniziali divulgatori.
Il comportamento dei sistemi caotici ha ancora misteriose proprietà che l’uomo non è stato ancora in grado di decifrare; mattoncini matematici che la natura ha combinato per la costruzione dell’universo e di cui – forse – potremmo parlare nei prossimi articoli.
Erlang e frattali
In questo articolo, ho deciso di realizzare un’applicazione distribuita per la rappresentazione in Erlang degli insiemi frattali di Mandelbrot e Julia in Erlang introducendo anche i colori.
Un bel frullato di: caos, frattali, colori, concorrenza, programmazione funzionale, emozioni, infinito. Una frizzante e fatale alchimia di argomenti dalla quale non è possibile esser risucchiati!
Erlang
L’Erlang è un linguaggio funzionale progettato da Joe Armstrong, per conto di Ericsson, con lo scopo di favorire lo sviluppo di applicazioni: distribuite, soft-realtime, con un elevato grado di concorrenza ed affidabilità nel campo delle telecomunicazioni. La prima versione proprietaria del linguaggio è stata rilasciata internamente nel 1986 mentre, dopo varie vicessitudini, nel 1998 Erlang è stato distribuito opensource.
Concorrenza e gestione dei processi
The world is concurrent
Things in the world don’t share data
Things communicate with messages
Things fail – Joe Armstrong
Erlang è progettato per la concorrenza massiva. Per spingere tale caratteristica a livelli estremi, si è ben pensato di progettare un gestore di processi ed uno scheduler interni alla virtual-machine. Tali componenti non delegano i loro compiti al kernel del sistema operativo (come fa la quasi totalità degli altri linguaggi) e sono in grado di gestire processi con un’efficientissima gestione della memoria e dello scheduling.
Scrivere applicazioni distribuite, scalabili e robuste in Erlang è normalmente più semplice che in altri linguaggi. I processi possono esser distribuiti trasparentemente su più core oppure su più macchine e comunicano tramite message-passing asincrono.
Apprendere l’Erlang
Se siete semplicemente curiosi di conoscere la sintassi del linguaggio, potreste provare questo breve tutorial online che simula via web la shell di Erlang: Tryerlang.
Per un corso online è possibile visitare: Learn You Some Erlang oppure Erlang for Skeptics
I libri che non possono mancare nella biblioteca di chi ama tale linguaggio (sui quali ho studiato l’Erlang):
- Erlang Programming: A Concurrent Approach to Software Development, Francesco Cesarini and Simon Thompson, O’Reilly Media
- Programming Erlang: Software for a Concurrent World, Joe Armstrong, The Pragmatic Bookshelf
Applicazione Erlang: frk
Segue il codice sorgente in Erlang, del modulo principale, che ho scritto per la mia applicazione: frk.
-module(frk).
-author('LucaAmore').
-export([save/11, save/9, julia/9, mandelbrot/7]).
% extract all screen coords
screen(W, H)->
[ {X,Y} || Y <- lists:seq(0, H - 1), X <- lists:seq(0, W - 1) ].
% convert bitmap point to complex point
complex(X, Y, MinX, MinY, FactX, FactY)->
{ MinX + X * FactX, MinY + Y * FactY }.
iterate(_, _, _, _, MaxIterations, Iterations)
when Iterations >= MaxIterations -> Iterations;
iterate(Zre, Zim, _, _, _, Iterations)
when Zre * Zre + Zim * Zim > 4 -> Iterations;
iterate(Zre, Zim, Cre, Cim, MaxIterations, Iterations)->
iterate(
Zre * Zre - Zim * Zim + Cre,
2 * Zre * Zim + Cim,
Cre, Cim,
MaxIterations, Iterations+1
).
%------------------------------------------------------------------------
% Julia's set
%
% Z1 = C0, Zn+1 = Zn^2 + K
%------------------------------------------------------------------------
julia(X, Y, MinX, MinY, FactX, FactY, Kre, Kim, MaxIterations)->
{Cre, Cim} = complex(X, Y, MinX, MinY, FactX, FactY),
iterate(Cre, Cim, Kre, Kim, MaxIterations, 0).
%------------------------------------------------------------------------
% Mandelbrot's set
%
% Z1 = 0, Zn+1 = Zn^2 + C0
%------------------------------------------------------------------------
mandelbrot(X, Y, MinX, MinY, FactX, FactY, MaxIterations)->
{Cre, Cim} = complex(X, Y, MinX, MinY, FactX, FactY),
iterate(0, 0, Cre, Cim, MaxIterations, 0).
% Julia's set exploration
generate(julia, W, H, MinX, MaxX, MinY, MaxY, Kre, Kim, MaxIterations)
when W > 0, H > 0, MaxX > MinX, MaxY > MinY, MaxIterations > 0 ->
FactX = (MaxX - MinX) / W,
FactY = (MaxY - MinY) / H,
[ julia(X, Y, MinX, MinY, FactX, FactY, Kre, Kim, MaxIterations) ||
{X, Y} <- screen(W, H) ].
% Mandelbrot's set exploration
generate(mandelbrot, W, H, MinX, MaxX, MinY, MaxY, MaxIterations)
when W > 0, H > 0, MaxX > MinX, MaxY > MinY, MaxIterations > 0 ->
FactX = (MaxX - MinX) / W,
FactY = (MaxY - MinY) / H,
[ mandelbrot(X, Y, MinX, MinY, FactX, FactY, MaxIterations) ||
{X, Y} <- screen(W, H) ].
% save Julia's set in ppm format
save(julia, W, H, MinX, MaxX, MinY, MaxY, Kre, Kim, MaxIterations, FileName)
when W > 0, H > 0, MaxX > MinX, MaxY > MinY, MaxIterations > 0 ->
M = [
paletteblu:color(Iterations, MaxIterations) ||
Iterations <- generate(
julia, W, H, MinX, MaxX, MinY, MaxY, Kre, Kim, MaxIterations
)
],
ppm:save(image, W, H, 255, FileName, M).
% save Mandelbrot's set in ppm format
save(mandelbrot, W, H, MinX, MaxX, MinY, MaxY, MaxIterations, FileName)
when W > 0, H > 0, MaxX > MinX, MaxY > MinY, MaxIterations > 0 ->
M = [
palettered:color(Iterations, MaxIterations) ||
Iterations <- generate(
mandelbrot, W, H, MinX, MaxX, MinY, MaxY, MaxIterations
)
],
ppm:save(image, W, H, 255, FileName, M).
Per non appesantire troppo il codice ho deciso di utilizzare come formato delle immagini dioutput PPM (tra i più semplici disponibili) e poi convertirlo in PNG, tramite script bash, utilizzando l’utility convert di ImageMagick.
Tutte le immagini dei frattali di questoarticolosono stati generati da frk.
L’applicazione frk. rilasciata come software libero sotto licenza GNU/GPL, è disponibile presso: