Cerco di spiegare in modo semplice l'esperimento che ho fatto oggi, piuttosto lungo e complesso che mi ha fuso il cervello per far funzionare tutto! 😅 L'Insieme di Mandelbrot, che potete vedere su Wikipedia e Google Immagini, è descritto dal punto di vista matematico, appartiene al piano complesso. Si può implementare tramite algoritmo, il risultato può essere molto bello visivamente. Faccio alcune premesse:
Perché C + Python assieme?
In pratica ho voluto unire due cose: l'efficienza computazionale del C con la comodità e semplicità nella gestione grafica di Python (libreria Matplotlib, in particolare tramite Heatmap di cui avevo già parlato).
L'idea quindi è stata quella di creare un programma in C (non entro nei dettagli dell'algoritmo, è un po' complicato, se interessati riporto comunque tutto il codice) che calcola una matrice, questo insieme di Mandelbrot (dimensione 200x200, con max 100 iterazioni per ogni cella, da qui si vede che sono già numeri abbastanza importanti ed è opportuno rendere efficiente il codice). La matrice viene salvata su file, col nome output.txt e contiene valori 0-1 (a seconda che appartenga o no all'insieme). Poi dinamicamente creo uno script Python che acquisisce in input la matrice, da questo file output.txt generato dal precedente programma in C e si occupa di stampare graficamente i valori, ho scelto di stamparlo tramite Heatmap (mappa di calore).
Ho scritto "per un mondo più colorato" perché, sia guardando la galleria presente su Wikipedia, sia Google Immagini, alcune rappresentazioni che si possono fare sono davvero carine! Avviando lo script Python, si ottengono visualizzazioni come quelle del collage di immagini che segue (ho inserito i nomi, dove di default nello script Python ho inserito color='YlGnBu'
, possiamo appunto cambiare questo nome a seconda della scala di colori che preferiamo).
Ecco il codice C completo (che come detto va ad originare anche il file Python):
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
int main() {
register short i,j,iter,Nx,Ny,maxiter;
register float real, imag;
register bool in_set;
Nx=200;
Ny=200;
maxiter=100;
bool V[Nx][Ny];
for(j=0;j<Ny;j++) {
for(i=0;i<Nx;i++) {
real = (i - Nx/2.0)*4.0/Nx; // mappa i pixel in una griglia Nx x Ny nell'intervallo (-2, 2) sulla parte reale
imag = (j - Ny/2.0)*4.0/Ny; // mappa i pixel in una griglia Nx x Ny nell'intervallo (-2i, 2i) sulla parte immaginaria
in_set = true;
iter = 0;
float zr = 0.0;
float zi = 0.0;
float zr_temp;
while(iter < maxiter) {
zr_temp = zr*zr - zi*zi + real;
zi = 2*zr*zi + imag;
zr = zr_temp;
if(zr*zr + zi*zi > 4.0) {
in_set = false;
break;
}
iter++;
}
V[i][j] = in_set;
}
}
FILE *f1=fopen("output.txt","w");
for(j = 0; j < Ny; j++) {
for(i = 0; i < Nx; i++) {
if(V[i][j]==true){
fprintf(f1, "1");
}else{
fprintf(f1, "0");
}
}
fprintf(f1,"\n");
}
fclose(f1);
FILE *f2=fopen("grafico.py","w");
fprintf(f2,"import numpy as np\nfrom matplotlib import pyplot as plt\nV = np.zeros((%d,%d), dtype=int)\nwith open(\"output.txt\", \"r\") as file:\n\tfor i in range(%d):\n\t\tline = file.readline().strip()\n\t\tchars = list(line)\n\t\tfor j in range(%d):\n\t\t\tval = int(chars[j])\n\t\t\tV[i][j] = val\ncolor='YlGnBu'\nplt.imshow(V,color)\nplt.show()",Nx,Ny,Nx,Ny);
fclose(f2);
return 0;
}
Se non interessa il codice in sé e nemmeno come viene definito matematicamente questo insieme frattale, spero almeno che piacciano le immagini (sì, quelle su Wikipedia sono più belle delle mie, forse la risoluzione più alta e anche miglior scelta dei colori ahah 🙂).
