Francesco Fassò, Andrea Giacobbe

Università degli studi di Padova

Note del corso di
Laboratorio Computazionale
A.A. 2009—2010

Capitolo 4: Julia e Mandelbrot

4.1 Teoria e disegni

Attenzione : i grafici possono essere di dimensioni notevoli e possono bloccare la macchina.
■ salvare spesso il notebook
■ cancellare spesso i grafici inutili

Data una funzione polinomiale P(z):ℂ->ℂ, vogliamo studiare le orbite delle iterate di P, ovvero vogliamo studiare l'insieme

{(Subscript[z, 0]),(Subscript[z, 1])=P((Subscript[z, 0])),..., (Subscript[z, n])=P((Subscript[z, n-1])),...}

Il caso piu semplice ma non triviale di polinomio è quello in cui (Subscript[P, c])(z)=(z^2)+c, con c un numero complesso che useremo come parametro

Vogliamo capire come si comportano le orbite. In particolare: fissato un c, per quali dati iniziali (Subscript[z, 0]) le orbite  rimangono limitate? Per quali altri dati iniziali (Subscript[z, 0]) le orbite non rimangono limitate?

4.1 Teoria e disegni

Fissiamo c complesso, e chiamiamo (Subscript[K, c]) l'insieme dei punti del piano le cui orbite non "si avvicinano" all'infinito, ovvero (Subscript[K, c])={z ∈ ℂ t.c.  (sup_n)|Nest[(Subscript[P, c]),z,n]|<+∞}.

Chiamiamo invece (Subscript[E, c])=ℂ - (Subscript[K, c]) il complementare, ovvero l'insieme dei punti che non rimangono limitati (che scappano all'infinito?)

In realtà, mostreremo che ogni elemento z di (Subscript[E, c]) è tale che (lim_(n->∞))|Nest[(Subscript[P, c]),z,n]|=+∞

Esempio: (Subscript[K, 0]) è il disco unitario.

Osservazione: unico altro caso non entusiasmante è c=-2, per cui si ottiene un intervallo. Tutti gli altri insiemi (Subscript[K, c]) hanno struttura interessante.

4.1 Teoria e disegni

Proposizione: Per ogni c∈ℂ, gli insiemi (Subscript[K, c]) ed (Subscript[E, c]) non sono vuoti

Dimostrazione: le due soluzioni all'equazione z=(Subscript[P, c])(z) sono punti fissi, e quindi le loro orbite non possono "avvicinarsi" all'infinito, e quindi appartengono a (Subscript[K, c]),

Anche le soluzioni dell'equazione z=(Subscript[P, c])((Subscript[P, c])(z)) sono o punti fissi od orbite periodiche di periodo 2.

Siccome L'equazione ha grado 4, allora ci sono i due punti fissi trovati sopra ed una nuova coppia di punti che forma un'orbita periodica di periodo 2.

Si potrebbe continuare così, ottenendo un insieme numerabile di punti che non possono tendere all'infinito

4.1 Teoria e disegni

D'altra parte, vogliamo mostrare che esiste un raggio r tale che se \[LeftBracketingBar]z\[RightBracketingBar]>r allora l'orbita di z tende all'infinito.

Supponiamo quindi che |z|=r+δ, e stimiamo la norma di |(Subscript[P, c])(z)|=|(z^2)+c|.

Di certo vale |(z^2)+c|≥((|z|)^2)-|c|=(r^2)+2 r δ + (δ^2)-|c|. Perché questa quantità sia maggiore di |z| bisogna e basta che

(r^2)+2 r δ + (δ^2)-\[LeftBracketingBar]c\[RightBracketingBar]>r+δ, ovvero bisogna che (r^2)+(2 δ-1) r + (δ^2)-δ-\[LeftBracketingBar]c\[RightBracketingBar]>0.

4.1 Teoria e disegni

Questo è verificato quando r è fuori dall'intervallo [(1/2)-δ-(Sqrt[(1/2)+|c|]),(1/2)-δ+(Sqrt[(1/2)+|c|])].

Che vuol dire r+δ>(1/2)+(Sqrt[(1/2)+|c|])

concludendo, ogni volta che \[LeftBracketingBar]z\[RightBracketingBar]>(1/2)+(Sqrt[(1/2)+\[LeftBracketingBar]c\[RightBracketingBar]]), allora la norma delle sue iterate è strettamente monotona e cresce verso +∞.

4.1 Teoria e disegni

Proposizione:  Per ogni c∈ℂ, l'insieme (Subscript[K, c]) è contenuto nel disco chiuso di raggio (1/2)+ (Sqrt[(1/2)+|c|]). Tutti i punti che, ad una qualche iterazione, escono da tale disco, tendono in norma a +∞. In particolare, tutti i punti di (Subscript[E, c]) tendono in norma a +∞

Definizione:  La frontiera (Subscript[J, c]) di (Subscript[K, c]) si chiama insieme di Julia del polinomio (Subscript[P, c])

Ogni tanto (spesso) equivocheremo, e chiameremo (Subscript[K, c]) l'insieme di Julia, che in realtà viene chiamato in letteratura insieme di Julia riempito (filled Julia set)

4.1 Teoria e disegni

Teorema (Julia-Fatou): 
1. (Subscript[K, c]) è compatto (è limitato perché contenuto nella palla di raggio (1/2)+ (Sqrt[(1/2)+|c|]), si dimostra che è chiuso)
2. se l'origine appartiene a (Subscript[K, c]) allora esso è connesso ed ha interno non vuoto. In questo caso, il suo bordo (Subscript[J, c]) è pure connesso

3. se l'origine non appartiene a (Subscript[K, c]) allora esso è totalmente disconnesso ed ha interno vuoto ma rimane non numerabile, e prende il nome di Cantor Dust. In questo caso, (Subscript[J, c])=(Subscript[K, c])

"Definizione": un "Cantor dust" è immagine omomorfa del prodotto di insiemi di Cantor.

Riepilogando: un insieme C è "polvere di Cantor" quando è chiuso, ed è costituito da punti sempre di frontiera (è totalmente disconnesso) e che sono di accumulazione (quindi i punti di C si "addensano" gli uni contro gli altri)

4.1 Teoria e disegni

Domanda tecnica: come si fa a stabilire se l'orbita di un punto scappa all'infinito? Abbiamo mostrato che se una qualche iterata di (Subscript[z, 0]) esce dal disco di raggio (1/2)+ (Sqrt[(1/2)+|c|]) allora l'orbita di (Subscript[z, 0]) va all'infinito, ma nulla più. Non possiamo fare infinite iterazioni per vedere se scapperà o no.

Formalizzazione della risposta: fissiamo un numero massimo n di iterazioni abbastanza grande. Se l'orbita di (Subscript[z, 0]) esce dal disco di raggio (1/2)+ (Sqrt[(1/2)+|c|]) prima di n iterazioni allora stabiliamo che (Subscript[z, 0]) scapperà, altrimenti decidiamo che non scappa.

Otteniamo così un insieme che contiene strettamente l'insieme (Subscript[K, c]).

4.1 Teoria e disegni

Vediamo ora come produrre il disegno di un insieme di Julia, almeno quando questo ha interno non vuoto (uno piccolo aggiustamento ci permetterà di disegnare anche i Julia che sono Cantor dust)

L'idea è quella di creare una funzione, chiamiamola Scappa, che dato (c ed un n ed) un punto iniziale (Subscript[z, 0]) restituisce 0 se il punto non scappa ed 1 se il punto scappa.

Ovviamente, un punto è fuggito se entro un numero n abbastanza grande ma prefissato di iterazioni, esso esce dalla palla di raggio (1/2)+ (Sqrt[(1/2)+|c|]), altrimenti dobbiamo rassegnarci a considerarlo come punto di (Subscript[K, c]) (anche se questo non è necessariamente vero)

4.1 Teoria e disegni

Per produrre il disegno, si campiona in una griglia e si ottengono i valori 0 od 1 in tale griglia (si ha quindi una tabella n×n, di 0 od 1)

Si pensa alla griglia–matrice come ad una pixellatura del quadratato, e la si disegna assegnando un colore (nero) all'1 ed un altro colore (bianco) allo 0

Per associare a tale matrice una immagine con colori si possono usare varie funzioni. In ordine di velocità di "rendering": Image, ArrayPlot,  MatrixPlot, ReliefPlot, Raster, ListDensityPlot

4.1 Teoria e disegni

Vediamo prima come creare la funzione Scappa[c, n,z] che dati il numero complesso c, il numero di iterazioni n, ed il punto iniziale (Subscript[z, 0]), restituisca 0 od 1 a seconda che (Subscript[z, 0]) scappa o meno.

Per definire la funzione Scappa, bisogna ripetere la mappa ed ottenere i punti (Subscript[z, k]) finchè questi non fuggono o fino a raggiungere n. Se prima di n iterazioni gli (Subscript[z, k]) fuggono allora la funzione ritorna 0, se dopo n iterazioni non è fuggito si ritorna 1

Usate While con un parametro k che incrementa. Il ciclo while si esaurisce quando il parametro k è arrivato ad n oppure quando il punto è scappato. Quindi vogliamo che la funzione restituisca 0 se k<n all' uscita od 1 se k=n

4.1 Teoria e disegni

Un ultimo comando da usare è quello che k e rende 1 se k=n e 0 se k<n. Si chiama Floor

Floor[10/11]
Floor[11/11]

4.1 Teoria e disegni

Conviene usare il comando Module per fare le varie cose, magari usando alcune variabili locali come il raggio massimo r=(1/2)+ (Sqrt[(1/2)+Abs[c]]). Ci si può chiedere se si debba, o se convenga, rendere locali al modulo anche le variabili k,z.

La struttura di Scappa sarà

Scappa[c_,n_,z_]:=Module[{r=(1/2)+ (Sqrt[(1/2)+Abs[c]]),k=1,w=z},
While[|w|< r&&k<n;cambia w ed incrementa k];
Floor[k/n]]

4.1 Teoria e disegni

In linea di massima, l'esecuzione di un modulo è un pò più veloce se esso non contiene la dichiarazione di variabili locali. Nel caso l'esecuzione di un modulo venga ripetuta molte volte, in un processo iterativo, dunque è preferibile non rendere locali le variabili.

Nel nostro caso, tuttavia, compileremo il modulo, e per questo le variabili dovranno essere rese locali (vedere  sotto).

Esercizio 4.1.1i: definire una funzione Scappa[c,n,z] che fissato c ed una soglia n, ad ogni z associa il numero 0 se z non va all'infinito ed 1 se z va all'infinito.

4.1 Teoria e disegni

Ora che abbiamo la funzione Julia, possiamo valutarla sui punti di una griglia rettangolare nel piano.

Creiamo la tabella Table[x + I y, {y, ymin, ymax, d}, {x, xmin, xmax, d}] e mappiamoci sopra la funzione Scappa[c,n,#] (Attenzione all'ordine degli iteratori nella Table: va prima x o prima y)

Si ottiene così una matrice quadrata di dimensioni (((Subscript[x, max])-(Subscript[x, min]))/(d x))× (((Subscript[y, max])-(Subscript[y, min]))/(d y))  la cui componente (i,j) è 0 se l' orbita del punto corrispondente della griglia scappa all'infinito, 1 se non scappa.

4.1 Teoria e disegni

Esercizio 4.1.2ii: usare la funzione Scappa per definire una funzione Julia[{{xmin,xmax},{ymin,ymax},d},c,n] che disegna l'insieme di Julia associato a c∈ ℂ nel dominio [xmin,xmax]×[ymin,ymax] con il finezza d.

Suggerimenti pratici: i grafici creati possono essere di grandi dimensioni:
■ salvare spesso il notebook
■ cancellare spesso i grafici che non servono più
■ sperimentare con valori dei parametri molto piccoli ed incrementarli man mano. 
■ Costruite le vostre funzioni per approssimazioni successive, aggiungendo via via le opzioni più sofisticate, e controllate passo passo che quel che  scrivete funzioni.

4.1 Teoria e disegni

Un problema, molto importante, è che la funzione Scappa è molto lenta ad essere eseguita.

Per velocizzare sensibilmente i conti (essenziale per poter fare figure il più possibile dettagliate) conviene compilare la funzione.

Per la compilazione si usa il comando Compile

4.1 Teoria e disegni

La sintassi è Compile[{variabili}, funzione da compilare]

le variabili si possono dichiarare {{x, _Real}, {z, _Complex}, ...}. Il default è Real

Osservazione : Compile non produce codice compilato (in istruzioni macchina) e mandato direttamente alla CPU. Produce codice interpretato dal kernel.

Questo assicura la portabilità fra piattaforme diverse, a prezzo di un po' di velocità

4.1 Teoria e disegni

Una funzione compilata è (anche molto) più veloce di una non compilata soprattutto perché il kernel sa a priori con che tipo di variabili tratta, e se queste sono per esempio reali, fa tutti i conti in floating point.

Attenzione: evitare l'uso di variabili globali in una funzione compilata,

ovvero: tutte le variabili che, in Compile[{variabili}, espressione] appaiono nella "espressione" (tipo l'iteratore k nella funzione Julia) devono essere rese locali (con Module o With)

Esercizio 4.1.2: definire una funzione ScappaC[c,n,z] che è la funzione Scappa compilata. Usare poi la funzione ScappaC per definire una funzione JuliaC[{{xmin,xmax},{ymin,ymax},d},c,n] che fa le stesse cose della funzione Julia usando però la funzione ScappaC.

4.1 Teoria e disegni

Confrontiamo la velocità. Scriviamo una tabella di (10^4) punti complessi e valutiamo le funzioni in quei punti. Usiamo Timing per vedere quanto tempo impiegano ad essere valutate

(Per eseguire questi comandi bisogna aver definito le funzioni Scappa e ScappaC)

tb=Table[Random[Complex],{10000}];

Timing[Map[Scappa[#,1,50]&,tb]][[1]]
Timing[Map[ScappaC[#,1,50]&,tb]][[1]]

Si guadagna circa un fattore 5

4.1 Teoria e disegni

Possibili miglioramenti :

Può essere conveniente usare come parametri i numeri nx ed ny dei punti sui due lati della griglia, piuttosto che i passi dx e dy.

Basta infatti definire una funzione JuliaC[ {x1_, x2_, nx_}, {y1_, y2_, ny_}, c_,n_]:=... ottenuta valutando la precedente per dx= ... etc.

4.1 Teoria e disegni

Nota: Come si potrebbe fissare la dimensione massima della figura, invece che quella orizzontale? Come si potrebbe scegliere la finezza in modo che essa sia omogenea nelle due direzioni a priorità di finezza nell'asse delle x?

In vista di quanto si dovrà fare più avanti, cioè colorare i punti in funzione della loro velocità di fuga, può essere utile modificare le funzioni ScappaC e JuliaC in modo da colorare i punti di (Subscript[K, c]) e del suo complementare con colori diversi dal bianco e dal nero.

Per esempio, rosso—Hue[0] i punti che non scappano e blu—Hue[.6] quelli che scappano.

4.1 Teoria e disegni

La colorazione si fa in modo diverso per ognuna delle funzioni consigliate. Per Image si usa la specifica ColorSpace->RGB, a patto di sostituire ad ogni entrata della tabella una terna di numeri che rappresentano la colorazione nella convenzione RGB.

Con ArrayPlot, la cosa è più semplice (e quindi la preferiamo): basta definire una funzione a valore un colore, ed usare l'opzione ColorFunction->Funzione

Siccome ScappaC produce come risultato 0 oppure 1, usando la funzione Hue si avrebbero i punti che scappano colorati allo stesso modo di quelli che non scappano (Hue è periodica e va da Hue[0] a  Hue[1] che sono entrambi rossi).

Se vogliamo che gli "1" siano colorati con Hue[.6] ci basta usare una "funzione colore" che a 0 assegna Hue[0] e ad 1 assegna Hue[.6]. Tale funzione è ColorFunction->(Hue[.6 #]&)

4.1 Teoria e disegni

Il procedimento usato finora non funziona molto bene, soprattutto per i casi nei quali (Subscript[K, c]) è totalmente disconnesso.

Infatti, all'aumentare del numero n delle iterazioni, l'insieme dei punti che non scappano si riduce progressivamente. Dunque la struttura di (Subscript[K, c]) è descritta grossolanamente se n è piccolo ed è completamente persa se n è grande.

Tipicamente, se (Subscript[K, c]) è totalmente disconnesso, nessuno dei suoi punti appartiene alla griglia.

Si può cercare di ovviare a questa situazione riducendo il passo della griglia, ma questo procedimento diventa molto oneroso in termini di tempi di calcolo. Inoltre, rappresentare una "Cantor dust" con un insieme un po' più grande di punti non è comunque molto illuminante.

4.1 Teoria e disegni

Quello che si fa è di colorare i punti del piano con un colore che è funzione del loro tempo di fuga. Cioè del numero di iterazioni al quale lasciano il cerchio di raggio (1/2)+ (Sqrt[(1/2)+|c|]).

Se, come uno può aspettarsi, il tempo di fuga cresce all'avvicinarsi a (Subscript[K, c]), questo insieme sarà circondato da regioni di "tempo di fuga" crescente e dunque di diversi colori. Si può dunque dedurre la struttura di (Subscript[K, c]) dalla struttura degli insiemi di ugual tempo di fuga che lo circondano.

Se si è proceduto come indicato finora,il modo più semplice di farlo è quello di modificare la funzione Scappa facendole produrre (k/n) invece della sua parte intera.

4.1 Teoria e disegni

NB: Non si può far andare l'argomento di Hue da 0  a 1 perché  Hue[1] = Hue[0] = rosso e non si distinguerebbero i punti che non scappano da quelli che scappano al primo colpo. Si può invece sperimentare con diverse funzioni di colorazione. Per esempio Hue[0.6((#)^2)], oppure  Hue[0.6(Sqrt[#])]

Esercizio 4.1.3: definire una funzione ScappaC[c,n,z] che è la funzione ScappaC compilata ma che da come risultato un numero in [0,1]. Usare poi la funzione JuliaC con il nuovo ScappaC per mostrare insiemi di Julia totalmente disconnessi.

4.2 Disegni più accurati: programma esterno

In realtà, anche la velocità acquisita con la compilazione non basta.

Si vorrebbe infatti poter investigare i disegni, per mettere a fuoco le autosimilarità e la struttura degli insiemi di Julia

Mathematica non è fatto per calcoli ricorsivi, e noi abbiamo davvero bisogno di iterare una mappa per circa 200 volte e più se vogliamo fare uno zoom

4.2 Disegni più accurati: programma esterno

Un modo per fare questo c'è: si usa un programma esterno davvero compilato nel vostro linguaggio preferito diciamo C o Fortran

Si fa poi dialogare Mathematica l'eseguibile prodotto compilando il programma

Il modo corretto di farlo sarebbe quello di far colloquiare Mathematica con il programma esterno attraverso la RAM

Il grave difetto della tecnica del professionista è  la portabilita'!  Le librerie che definiscono le funzioni elementari del linguaggio in cui si programma e quelle che spiegano  a Mathematica come dialogare con gli eseguibili cambiano  a seconda di quale sia: il sistema operativo, la versione del compilatore, la versione di Mathematica.

4.2 Disegni più accurati: programma esterno

La tecnica che useremo è forse meno "elegante", ma più facile da implementare. Si tratta di:

0 scrivere un programma che legge i dati in ingresso da un file dati.in, fa i conti, scrive i risultati in un file dati.out

1 chiedere a Mathematica di scrivere su dati.in i dati in ingresso

2 chiedere a Mathematica di far girare l' eseguibile ottenuto compilando il programma

3. far leggere a Mathematica la tabella di numeri così ottenuta

4 chiedere a Mathematica di rendere in un disegno l'insieme di Julia

4.2 Disegni più accurati: programma esterno

La prima cosa da fare, è quindi di scrivere un un programma, diciamo julia.for, che fa la parte iterativa.

Il programma, una volta compilato, prende in ingresso i valori

■ {xmin, xmax}, {ymin, ymax} dobbiamo dirgli dove stiamo disegnando
■ c o meglio {cre, cim} perché non esiste la estensione Complex in Fortran
■ numit perché dobbiamo dirgli quante volte provare prima di decidere che un punto scappa
■ ndiv perché dobbiamo dirgli quanto sgranato deve essere il disegno

L' output del programma sarà una lunga lista di numeri compresi tra 0 ed 1

4.2 Disegni più accurati: programma esterno

Dobbiamo poi scrivere la funzione in Mathematica, che:

■ seleziona la directory di lavoro Directory[], SetDirectory[]
■ si assicura che ci siano i files che ci devono essere (dati.in) e non ci siano 
quelli che non ci devono essere (dati.out)
■ esporta nel file dati.in la lista di dati scritti cosi' come servono al programma
■ fa girare il programma
■ legge i dati ottenuti con il programma
■ li rende con Image, o funzioni parenti

Vediamo le cose nel dettaglio

4.2 Disegni più accurati: programma esterno

si deve dire al computer in quale directory risiedono i file

SetDirectory[NotebookDirectory[]]

Controlliamo che sia vero

Directory[]

4.2 Disegni più accurati: programma esterno

Si devono sistemare i file di input–output: il file dati.in deve esistere, il file dati.out non deve esistere

If[FileNames["dati.in"]=={}, ciao>>"dati.in"];  
 If[FileNames["dati.out"]=!={}, DeleteFile["dati.out"]];

4.2 Disegni più accurati: programma esterno

si scrive la lista di xmax, ..., in dati.in. Scriviamo prima una riga di comando che sono i valori assegnati alle variabili della funzione JuliaE (non va scritto nella funzione)

xmin=-2;xmax=2;ymin=-1.2;ymax=1.2; c=0.3 I; ndiv=300; numit=100;

Questo invece va scritto nel comando: si apre il file dati.in, si crea la lista, si scrive la lista nel file, lo si chiude... forse si può usare semplicemente Export, ma la formattazione del file è una cosa delicata

OpenWrite["dati.in",FormatType->FortranForm];
ls={xmin,xmax,ymin,ymax,Re[c],Im[c],ndiv,numit};
Map[Write["dati.in",#]&,ls];
Close["dati.in"];

4.2 Disegni più accurati: programma esterno

si chiede al programma di girare

Run["./julia"];

Ovviamente, il programma eseguibile julia si deve ottenere compilando il file fortran julia.for. Il comando per farlo è g77 julia.for -o julia.exe. Attenzione che in macchine Windows la sintassi è Run[julia], ed il file julia deve avere estensione exe.

Poi, si legge il risultato

cc=ReadList["dati.out",Number];

4.2 Disegni più accurati: programma esterno

Visto che il programma mi rende una lunga lista con numeri interi e non una tabella d×d, la debbo partizionare per ottenere una tabella quadrata di dimensione (d+1)×(d+1). Bisogna anche dividere per n, perché il programma rende il numero di iterazioni fatte per scappare

tt=Partition[(1/numit)cc,ndiv+1];

4.2 Disegni più accurati: programma esterno

Infine, si produce l' immagine

ArrayPlot[tt,ColorFunction->(Hue[0.6 #]&)]

4.2 Disegni più accurati: programma esterno

Esercizio 4.2.1: definire la funzione JuliaE che usa il programma esterno.

In questo modo, la produzione delle immagini è abbastanza veloce da fare delle animazioni

4.2 Disegni più accurati: programma esterno

Per illustrare la autosimilarità degli insiemi di Julia si possono fare ingradimenti successivi, "zoomando" su dettagli dell'immagine. Per rendere chiaro il procedimento, è utile aggiungere una "finestrella" sull' immagine per mostrare quale parte del disegno. Per creare la finestrella, un quadrato, basta creare una linea che passa per quattro assegnati punti. Poi la si "mostra" insieme alla figura nella quale deve apparire.

Si può definire una funzione che crea un DisegnaJuliaExt con la finestrella o molto meglio, basta creare una funziona che mostra un DisegnaJuliaExt già creato assieme ad una finestrella

Esercizio 4.2.2: Studiare la "self-similarity" di un insieme di Julia ingrandendo ricorsivamente su di un dettaglio dell'insieme. Per rendere gli ingrandimenti conviene visualizzare un rettangolino che indichi la regione nella quale si è ingrandito. Mostrare alla fine tutti i grafici insieme.

4.3 Mandelbrot e bacini di attrazione

Come dipende l' insieme di Julia (Subscript[J, c]) da c?

Definizione:   si chiama insieme di Mandelbrot l' insieme M={c∈ℂ: (Subscript[J, c]) è connesso}={c∈ℂ : 0 ∈(Subscript[K, c])}

L' insieme di Mandelbrot si può studiare numericamente: grazie al Teorema di Julia e Fatou, per sapere se un punto  c sta in M basta integrare l' orbita di (Subscript[P, c]) con dato  iniziale 0 e vedere se tale orbita resta limitata.

Si trova così che l'insieme di Mandelbrot ha una struttura molto complessa  e autosimilare ...

4.3 Mandelbrot e bacini di attrazione

... e molto famosa

Esercizio 4.3.1: disegnare l'insieme di Mandelbrot

4.3 Mandelbrot e bacini di attrazione

L' insieme di Mandelbrot è un sottoinsieme dello spazio dei c ed è costruito basandosi sul comportamento dell' origine.

In realtà dice un'enormità di cose sugli insiemi di Julia

Se il parametro c è nella regione blu (ovvero appartiene all'insieme di Mandelbrot M), allora l'insieme di Julia è connesso ed ha interno: c'è un'ampio dominio di punti che non scappano all'infinito

Altrimenti quasi tutti i punti scappano all'infinito, mentre quelli che non scappano sono un insieme totalmente disconnesso che si definisce Cantor—dust.

4.3 Mandelbrot e bacini di attrazione

Come mai, se c∈ M ci sono così tanti punti che non scappano?

Il motivo è che tali punti convergono verso un'orbita periodica ed attrattiva.

Ovvero, gli insiemi di Julia (gli insiemi (Subscript[K, c])) sono il bacino di attrazione di un'orbita speciale, che attrae tutte le orbite che partono da (Subscript[K, c])

Cominciamo con il domandarci quante e quali sono le orbite periodiche della mappa

(Subscript[P, c]):ℂ->ℂ, z->(z^2)+c

4.3 Mandelbrot e bacini di attrazione

Il primo esempio di orbita periodica è il punto fisso od equilibrio ovvero un punto (OverBar[z]) tale che (Subscript[P, c])[(OverBar[z])]=(OverBar[z]).

Ovviamente, l'orbita di un punto fisso è la successione (OverBar[z]),(OverBar[z]),(OverBar[z]),...

Algebricamente, i punti fissi della mappa sono gli z tali che (z^2)+c=z

Osservazione: la mappa (Subscript[P, c]) ha due punti fissi, ha un'orbita periodica di periodo 2, ha 2 orbite periodiche di periodo 3, ha 2 orbite periodiche di periodo 4...

4.3 Mandelbrot e bacini di attrazione

Se esiste invece un N tale che ((Subscript[P, c])^N)[(OverBar[z])]=(OverBar[z]), allora {(OverBar[z]),(Subscript[P, c])[(OverBar[z])], ...,((Subscript[P, c])^(N-1))[(OverBar[z])]}  è un'orbita periodica, di periodo N

Data una orbita, il periodo dell'orbita è il minimo N che riporta (OverBar[z]) in sè

Osservazione: se un'orbita {(Subscript[z, 1]),...,(Subscript[z, N])} è periodica di periodo N allora ogni suo elemento (Subscript[z, i]) è punto fisso per la mappa ((Subscript[P, c])^N)

Esercizio 4.3.2: calcolare le orbite periodiche di (Subscript[P, c]) (fino ad un ordine ragionevole) e disegnarle in una manipolazione

4.3 Mandelbrot e bacini di attrazione

Come si fa a determinare il comportamento asintotico di un'orbita (Subscript[z, 0]),(Subscript[z, 1]),…? Bello sarebbe se tutte le orbite convergono verso i punti fissi (Subscript[P, c])[z]=z

Proposizione: un punto fisso (Subscript[z, 0]) attrae i punti vicini se \[LeftBracketingBar](Subscript[P, c])'[(Subscript[z, 0])]\[RightBracketingBar]<1, li repelle se \[LeftBracketingBar](Subscript[P, c])'[(Subscript[z, 0])]\[RightBracketingBar]>1. Siccome la funzione (Subscript[P, c]) ed il punto fisso (Subscript[(OverBar[z]), c]) sono dipendenti da c, allora l'insieme dei c in cui il punto fisso "cambia carattere" è l'insieme dei c tali che \[LeftBracketingBar](Subscript[P, c])'[(Subscript[(OverBar[z]), c])]\[RightBracketingBar]=1

Dimostrazione: Se|(Subscript[P, c])'[(Subscript[z, 0])]|<c<1 allora esiste un intorno di (Subscript[z, 0]) nel quale |(Subscript[P, c])[z]-(Subscript[P, c])[(Subscript[z, 0])]|<(c+ϵ)|z-(Subscript[z, 0])|. Ovvero |(Subscript[P, c])[z]-(Subscript[z, 0])|<|z-(Subscript[z, 0])|

pertanto, in tale intorno, la mappa (Subscript[P, c]) avvicina ogni punto ad (Subscript[z, 0]).

Se invece |(Subscript[P, c])'[(Subscript[z, 0])]|>1 si procede in modo analogo e si ottiene l'affermazione contraria.

4.3 Mandelbrot e bacini di attrazione

Proposizione: un'orbita periodica di periodo N 
■ attrae i punti vicini se, per un x di questa orbita (e quindi per ogni z dell'orbita) vale |D[((Subscript[P, c])^N),z]|<1, 
■ li repelle se vale vale |D[((Subscript[P, c])^N),z]|>1. 
Ricordiamo che la funzione (Subscript[P, c]) e l'orbita periodica {(Subscript[(OverBar[z]), c,1]),…,(Subscript[(OverBar[z]), c,N])} sono dipendenti da c, allora l'insieme dei c in cui il punto fisso "cambia carattere" è l'insieme dei c tali che |(Subscript[P, c])'[(Subscript[(OverBar[z]), c,1])]|=1

Abbiamo quindi imparato che cosa rende attrattiva (stabile) o repulsiva (instabile) un'orbita periodica della mappa (Subscript[P, c]).

Definizione:  diciamo che z è 
■ attrattivo se esiste un intorno U di z tale che l'orbita di ogni w∈U tende a z per n->∞.
■ repulsivo se esiste un intorno U di z tale che ogni w∈U ha orbita che esce definitivamente da U.

4.3 Mandelbrot e bacini di attrazione

Definizione: attrattività e repulsività di un'orbita periodica si definisce e si studia in modo analogo, riguardandola come un punto fisso di una potenza N della mappa (Subscript[P, c]).

Esercizio 4.3.3: disegnare il bordo della regione in cui i punti fissi da attrattivi diventano repulsivi (il punto fisso ((1-(Sqrt[1-4 c]))/2), visto che l'altro punto fisso è sempre repulsivo). Fare lo stesso per le orbite periodiche di periodo 2 (e 3, e 4, ...)

4.3 Mandelbrot e bacini di attrazione

Insomma, gli insiemi di Julia connessi non sono solo insiemi di punti che non tendono a +∞, ma sono in realtà bacini di attrazione di equilibri o di orbite periodiche (a volte di qualcosa di peggio).

Quando il parametro c sta nel corpo centrale (la cardioide) dell'insieme di Mandelbrot, allora il corrispondente insieme di Julia ha la forma di un disco "corrugato", e si chiama "disco di Siegel". Tale insieme è il bacino di attrazione del punto fisso in figura

4.3 Mandelbrot e bacini di attrazione

4.3 Mandelbrot e bacini di attrazione

Quando il punto c abbandona il corpo centrale e si sposta nel lobo grande (il cerchio grande attaccato alla cardioide), del punto fisso nasce un'orbita periodica di periodo 2 attrattiva (i due punti in figura). L'insieme di Julia è il bacino di attrazione di quell'orbita periodica.

4.3 Mandelbrot e bacini di attrazione

Ci sono anche le regioni in cui ad essere attrattiva è un'orbita periodica di periodo 3

4.3 Mandelbrot e bacini di attrazione

Molto lontano dal corpo centrale, ci sono situazioni più ricche. In questo caso il punto in figura è un punto fisso, ma non è attrattivo. La dinamica della mappa iterata genera rotazioni lungo i livelli disegnati

4.3 Mandelbrot e bacini di attrazione

Poco prima di lasciare un lobo per un'altro, l'orbita periodica diventa "degenere". Qui un punto fisso sta per trasformarsi in un'orbita periodica di periodo 5.

4.3 Mandelbrot e bacini di attrazione

Un'altra domanda è interessante porsi: se spostiamo c all' interno di ciascun "germoglio" dell'insieme di Mandelbrot, allora l' insieme di Julia cambia molto?

E se invece ci si sposta da un germoglio all'altro come cambia (Subscript[J, c])?

Vediamo alcune immagini prese dal libro The Beauty of Fractals, H.-O. Peitgen e P.H. Richter, Springer-Verlag 1987.

4.3 Mandelbrot e bacini di attrazione

Ecco l'insieme di Mandelbrot ed alcuni insiemi di Julia corrispondenti ad alcune scelte di c

4.3 Mandelbrot e bacini di attrazione

Esercizio 4.3.4: creare una manipolazione che mostra l'insieme di Mandelbrot come spazio dei parametri e, ogni volta che si seleziona un punto c dell'insieme di Mandelbrot, mostra il relativo insieme di Julia. In alternativa creare una tabella che mostra scelte di punti nell'insieme di Mandelbrot e relativi insiemi di Julia.

Esercizio 4.3.5: mostrare alcune scelte di insieme di Julia ed evidenziare come esso sia il bacino di attrazione di una qualche orbita. Studiare questo fatto per varie scelte di c nei vari "germogli" dell'insieme di Mandelbrot e discutere le differenze.

4.4 Altro modo di disegnare l'insieme di Julia

Come abbiamo visto, in condizioni abbastanza generali, quando l' insieme di Julia ha interno non vuoto allora tutti i suoi punti convergono verso un'orbita periodica

Cosa succede "rovesciano" la dinamica? L'orbita periodica sicuramente diventa repulsiva

Forse i punti convergono verso il bordo? In realtà la risposta è si!

Questo permette di disegnare gli insiemi di Julia con interno non vuoto in modo molto veloce, e poco costoso computazionalmente

4.4 Altro modo di disegnare l'insieme di Julia

L'inversa della mappa (Subscript[P, c]) è una mappa a più valori. Precisamente è una mappa 1->2 (manda un elemento in sottoinsiemi di ℂ contenenti due elementi).

Chiamiamo tale mappa (Subscript[Q, c]). Applicandola una volta a 0 si ottengono 2 valori (±(Sqrt[-c])). Applicandola una seconda volta si ottengono 4 valori.

Dopo N iterate, si ha una lista di (2^N) punti. Se l'affermazione fatta e non dimostrata è vera, questi punti dovrebbero accumulare tutti sulla frontiera dell'insieme (Subscript[J, c])

Esercizio 4.4.1: disegnare l'insieme di Julia usando la tecnica appena descritta.