Programme optimisé

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche
import datetime
import pandas as pd
import numpy as np
from random import randint
from time import time

import plotly.offline as pyo
import plotly.express as px

pyo.init_notebook_mode()

import cufflinks as cf
cf.go_offline()
#import cmath
from math import log

def intervalle(min, max, nbInter):
    """Renvoie des tableaux contenant des valeurs pour x et y
    En entrée : min et max, les limites de l'espace et nbInter, le nombre de découpages voulus sur l'intervalle min-max
    En sortie : deux tableaux, tabx et taby, contenant les différentes valeurs de x et y selon le découpage"""
    inter = (max-min)/(nbInter-1)
    tab = [min]*(nbInter)
    for i in range (0,nbInter):
        tab[i] = min + (inter*i)
    return tab


def periodicity(précision, x,y,max_iteration):
    xold = 0
    yold = 0
    period = 0
    i = 0
    while (x*x + y*y <= 2*2 and i < max_iteration) :
        xtemp = x*x -y*y + x
        y = 2*x*x +y
        x = xtemp
        if abs(x-xold) < précision and abs(y-yold) < précision:
            i = max_iteration
        period += 1
        if period > 20 :
            period = 0
            xold = x
            yold = y
        i += 1
    return i

def Mandelbrot(x,y,nbIteration,noOpti):
    """Indique si un nombre complexe fait partie de l'ensemble de Mandelbrot ou non
    En entrée : x et y, deux coordonées, nbIteration, le nombre de répétitions de la formule et ModuleMax, le module à ne pas dépasser
    En sortie : un entier, indiquant si le complexe appartient à l'ensemble ou non """
    nombre = complex(x,y)
    z= nombre
    c=nombre
    
    
    x0 =x
    y0 =y
    x2 = 0
    y2 = 0
    
    i = 1
    appartient = True
    while i<=nbIteration and appartient == True:
        
        if noOpti == 1:
            if abs(z.real)>2 or abs(z.imag)>2 :
                appartient = False
            z = z*z+c
        if noOpti == 2:
            if x2+y2 >= 4 :
                appartient = False
            y = (x+x)*y+y0
            x = x2-y2+x0
            x2 = x*x
            y2 = y*y
        i += 1
    if appartient==True :
        return 0
    else :
        return log(log(i))

def mandelbrot_boundary_tracing(tabx, taby, max_iter,noOpti):
    """Permet de réaliser l'ensemble de Mandelbrot en utilisant les frontières"""
    grid_size = len(tabx)
    Todo = set()
    for i in range(grid_size):
        Todo.add((i, 0))
        Todo.add((i, grid_size-1))
    for i in range(grid_size):
        Todo.add((0, i))
        Todo.add((grid_size-1, i))

    Mem = [[-1 for _ in range(grid_size)] for _ in range(grid_size)]
    Done = [[False for _ in range(grid_size)] for _ in range(grid_size)]

    def value(i, j):
        n = Mem[j][i]
        if n >= 0:
            return n
        n = compute(i, j)
        Mem[j][i] = n
        return n
    
    def compute(i, j):
        n = Mandelbrot(tabx[i], taby[j], max_iter,noOpti)
        #print(i,j)
        return n
    

    while Todo:
        i, j = Todo.pop()
        c = value(i, j)
        Done[i][j] = True

        if i > 0:
            cc = value(i-1, j)
            if cc != c and not Done[i-1][j]:
                Todo.add((i-1, j))

        if i < grid_size-1:
            cc = value(i+1, j)
            if cc != c and not Done[i+1][j]:
                Todo.add((i+1, j))

        if j > 0:
            cc = value(i, j-1)
            if cc != c and not Done[i][j-1]:
                Todo.add((i, j-1))

        if j < grid_size-1:
            cc = value(i, j+1)
            if cc != c and not Done[i][j+1]:
                Todo.add((i, j+1))

        if i > 0 and j > 0:
            cc = value(i-1, j-1)
            if cc != c and not Done[i-1][j-1]:
                Todo.add((i-1, j-1))

        if i < grid_size-1 and j > 0:
            cc = value(i+1, j-1)
            if cc != c and not Done[i+1][j-1]:
                Todo.add((i+1, j-1))

        if i > 0 and j < grid_size-1:
            cc = value(i-1, j+1)
            if cc != c and not Done[i-1][j+1]:
                Todo.add((i-1, j+1))

        if i < grid_size-1 and j < grid_size-1:
            cc = value(i+1, j+1)
            if cc != c and not Done[i+1][j+1]:
                Todo.add((i+1, j+1))
    return Mem

def ensembleMandelbrot(Xmin,Xmax,Ymin,Ymax,largeur,hauteur,nbIteration,typeCalcul,noOpti=0,précision=0):
    """Retourne le tableau permettant d'afficher l'ensemble de Mandelbrot
    En entrée : min et max, les bornes, nbInter, le nombre de découpages voulus, nbIteration, le nombre de répétitions et ModuleMax, le module à ne pas dépasser
    En sortie : trois tableaux, le tableau des x, le tableau des y, et le tableau d'affichage de l'ensemble de Mandelbrot"""
    tabx = intervalle(Xmin,Xmax,largeur)
    taby = intervalle(Ymin,Ymax,hauteur)
    if typeCalcul == "boundary":
        img_nb1 = mandelbrot_boundary_tracing(tabx,taby,nbIteration,noOpti)
    if typeCalcul == "classic":
        img_nb1 = [[0]*len(taby) for i in range (len(tabx))]
        for j in range (len(taby)//2):
            for i in range (len(tabx)):
                img_nb1[-1-j][i] = Mandelbrot(tabx[i],taby[j],nbIteration,noOpti)
                img_nb1[j][i] = img_nb1[-1-j][i]
    if typeCalcul == "periodicity":
        img_nb1 = [[0]*len(taby) for i in range (len(tabx))]
        for j in range (len(taby)//2):
            for i in range (len(tabx)):
                img_nb1[-1-j][i] = periodicity(précision,i,j,nbIteration)
                img_nb1[j][i] = img_nb1[-1-j][i]
    return (tabx, taby, img_nb1)

    

def afficheMandelbrot(tab,tab2,tab3):
    fig = px.imshow(tab,origin="lower",color_continuous_scale="edge")#regarder min max
    fig.show()