<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pschultz</id>
	<title>Wiki du LAMA (UMR 5127) - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pschultz"/>
	<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php/Sp%C3%A9cial:Contributions/Pschultz"/>
	<updated>2026-05-21T07:42:48Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14239</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14239"/>
		<updated>2022-05-29T18:05:26Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Fractale_de_Newton Source : Wikipédia/Fractales de Newton]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul() et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine() qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] == self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération est égal à N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14238</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14238"/>
		<updated>2022-05-29T18:04:27Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   ==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   ==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      ===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
      ===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
      ===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
         ====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Fractale_de_Newton Source : Wikipédia/Fractales de Newton]&lt;br /&gt;
&lt;br /&gt;
      ===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul() et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine() qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
   == Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
      === Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] == self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération est égal à N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14237</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14237"/>
		<updated>2022-05-29T18:03:16Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Fractale_de_Newton Source : Wikipédia/Fractales de Newton]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul() et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine() qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] == self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération est égal à N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14236</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14236"/>
		<updated>2022-05-29T18:00:55Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Dessin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Fractale_de_Newton Source : Wikipédia/Fractales de Newton]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul() et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine() qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] == self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération est égal à N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14235</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14235"/>
		<updated>2022-05-29T17:58:26Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Les racines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Fractale_de_Newton Source : Wikipédia/Fractales de Newton]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul() et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine() qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14234</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14234"/>
		<updated>2022-05-29T17:57:20Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Différentes méthodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://fr.wikipedia.org/wiki/Fractale_de_Newton Source : Wikipédia/Fractales de Newton]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14233</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14233"/>
		<updated>2022-05-29T17:55:57Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Différentes méthodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14232</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14232"/>
		<updated>2022-05-29T17:54:50Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Calculs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14231</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14231"/>
		<updated>2022-05-29T17:54:30Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Calculs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14230</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14230"/>
		<updated>2022-05-29T17:54:12Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Construction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – &amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14229</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14229"/>
		<updated>2022-05-29T17:54:00Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Construction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - {frac:f(z)/f&#039;(z)}.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – &amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14228</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14228"/>
		<updated>2022-05-29T17:51:20Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Construction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z - &amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – &amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14227</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14227"/>
		<updated>2022-05-29T17:51:09Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Construction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-&amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – &amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14226</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14226"/>
		<updated>2022-05-29T17:49:28Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Calculs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – &amp;lt;sup&amp;gt;f(z)&amp;lt;/sup&amp;gt;/&amp;lt;sub&amp;gt;f’(z)&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14225</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14225"/>
		<updated>2022-05-29T17:48:34Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;+z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14224</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14224"/>
		<updated>2022-05-29T17:47:46Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Remarque */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]] Polynôme : z&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;-1&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14223</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14223"/>
		<updated>2022-05-29T17:46:39Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Calculs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Ce programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord, on peut utiliser la méthode de Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on à besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; – Z est inférieur a 1*10&amp;lt;sup&amp;gt;-6&amp;lt;/sup&amp;gt; (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14222</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14222"/>
		<updated>2022-05-29T17:43:12Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Coordonnées */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi / x_lo / y_hi / y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14221</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14221"/>
		<updated>2022-05-29T17:42:47Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Coordonnées */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&amp;lt;br&amp;gt;&lt;br /&gt;
Les paramètres x_hi-x_lo-y_hi-y_lo servent a définir la taille du plan complexe.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14220</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14220"/>
		<updated>2022-05-29T17:38:21Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Initialisation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
On crée une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales.&amp;lt;br&amp;gt;&lt;br /&gt;
On défini pour cette classe 6 variables :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14219</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14219"/>
		<updated>2022-05-29T17:36:07Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Construction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la Méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14218</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14218"/>
		<updated>2022-05-29T17:34:10Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Définition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque [https://fr.wikipedia.org/wiki/Nombre_complexe point complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le [https://fr.wikipedia.org/wiki/Plan_complexe plan complexe] et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14217</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14217"/>
		<updated>2022-05-29T17:33:08Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point [https://fr.wikipedia.org/wiki/Nombre_complexe complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14216</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14216"/>
		<updated>2022-05-29T17:32:26Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe[http://https://fr.wikipedia.org/wiki/Nombre_complexe complexe] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14215</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14215"/>
		<updated>2022-05-29T17:31:02Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point [[complexe]] z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14202</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14202"/>
		<updated>2022-05-29T15:49:20Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impaire est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14201</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14201"/>
		<updated>2022-05-29T15:46:34Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelles.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lesquels on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux conditions initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué à chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèques scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;exécute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent à l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;une image et d&#039;un plan ne sont pas traitées de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduit de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction dérivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itérations effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inférieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite se stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sorti de la boucle on ajoute à la variable globale I le nombre d’itérations effectuées pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations nécessaire pour trouver une racine et s&#039;arrête après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autres méthodes ayant des résultats similaires avec des complexités moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas à l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert à enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenus en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toutes les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les informations nécessaires il faut à présent recommencer pour changer la couleur de chacun des pixels de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux choses :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir à quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs à effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel à la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable à celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux premières couleurs de notre palette (noir et blanc) sont déjà utilisées on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;à remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14154</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14154"/>
		<updated>2022-05-29T13:17:01Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Dessin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;a remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&amp;lt;br&amp;gt;&lt;br /&gt;
Et une fois notre image entièrement traitée on l&#039;enregistre.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14153</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14153"/>
		<updated>2022-05-29T13:15:55Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Dessin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel de notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois la bonne couleur choisie il ne reste qu&#039;a remplacer le pixel en utilisant la fonction putpixel de la bibliothèque PIL.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Cosh_z.png&amp;diff=14150</id>
		<title>Fichier:Cosh z.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Cosh_z.png&amp;diff=14150"/>
		<updated>2022-05-29T13:11:36Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Sin_z.png&amp;diff=14148</id>
		<title>Fichier:Sin z.png</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Sin_z.png&amp;diff=14148"/>
		<updated>2022-05-29T13:11:16Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14147</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14147"/>
		<updated>2022-05-29T13:10:59Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:sin_z.png|500px]]    Polynôme : sin(z)-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:cosh_z.png|500px]]    Polynôme : cosh(z)-1&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14145</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14145"/>
		<updated>2022-05-29T13:06:04Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14144</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14144"/>
		<updated>2022-05-29T13:05:42Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
&amp;lt;b&amp;gt;Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;D&#039;autres fractales réalisables.&amp;lt;/b&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14143</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14143"/>
		<updated>2022-05-29T13:05:00Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]]    Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]]    Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
D&#039;autres fractales réalisables.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14142</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14142"/>
		<updated>2022-05-29T13:04:45Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]] Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]] Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
D&#039;autres fractales réalisables.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14141</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14141"/>
		<updated>2022-05-29T13:04:36Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|500px]] Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|500px]] Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
D&#039;autres fractales réalisables.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14140</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14140"/>
		<updated>2022-05-29T13:04:19Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
Voici quelques exemples de fractales réalisées avec mon programme.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**5-1.jpg|800px]] Polynôme : z**5-1&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|800px]] Polynôme : z**6+z**3-1&amp;lt;br&amp;gt;&lt;br /&gt;
D&#039;autres fractales réalisables.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14139</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14139"/>
		<updated>2022-05-29T13:04:00Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Exemples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
Voici quelques exemples de fractales réalisées avec mon programme.&lt;br /&gt;
[[Fichier:z**5-1.jpg|800px]] Polynôme : z**5-1&lt;br /&gt;
[[Fichier:z**6+z**3-1.jpg|800px]] Polynôme : z**6+z**3-1&lt;br /&gt;
D&#039;autres fractales réalisables.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Z**6%2Bz**3-1.jpg&amp;diff=14138</id>
		<title>Fichier:Z**6+z**3-1.jpg</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Z**6%2Bz**3-1.jpg&amp;diff=14138"/>
		<updated>2022-05-29T13:03:13Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Z**5-1.jpg&amp;diff=14137</id>
		<title>Fichier:Z**5-1.jpg</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Z**5-1.jpg&amp;diff=14137"/>
		<updated>2022-05-29T13:02:48Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14136</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14136"/>
		<updated>2022-05-29T13:02:20Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;br /&gt;
&lt;br /&gt;
= Exemples =&lt;br /&gt;
Voici quelques exemples de fractales réalisées avec mon programme.&lt;br /&gt;
[[Fichier:z**5-1.png|800px]]&lt;br /&gt;
[[Fichier:z**6+z**3-1.png|800px]]&lt;br /&gt;
D&#039;autres fractales réalisables.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14135</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14135"/>
		<updated>2022-05-29T12:59:23Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Choix de la couleur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14134</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14134"/>
		<updated>2022-05-29T12:58:25Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Choix de la couleur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir alors qu&#039;à l&#039;inverse plus I est petit plus la couleur sera claire et proche du blanc.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14133</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14133"/>
		<updated>2022-05-29T12:57:00Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Choix de la couleur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j #somme des lignes parcourues et des pixels de la ligne en cours&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;. Cette fois-ci pas de cas ou z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; ne correspond à aucune racine car cela à été réglé par la fonction set_racine().&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir alors qu&#039;à l&#039;inverse plus I est petit plus la couleur sera claire et proche du blanc.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14132</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14132"/>
		<updated>2022-05-29T12:56:03Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Choix de la couleur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Pour savoir a quelles résultats se référer pour le pixel qui est traité on utilise la variable npix (initialisée au début de main()). Elle est ici sous la forme d&#039;un compteur pour minimiser les calculs a effectuer :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mais peut aussi être définie comme ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                npix = i*taille_img_y + j&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;. Cette fois-ci pas de cas ou z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; ne correspond à aucune racine car cela à été réglé par la fonction set_racine().&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir alors qu&#039;à l&#039;inverse plus I est petit plus la couleur sera claire et proche du blanc.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14131</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14131"/>
		<updated>2022-05-29T12:50:36Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Choix de la couleur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;. Cette fois-ci pas de cas ou z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; ne correspond à aucune racine car cela à été réglé par la fonction set_racine().&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir alors qu&#039;à l&#039;inverse plus I est petit plus la couleur sera claire et proche du blanc.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14130</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14130"/>
		<updated>2022-05-29T12:49:52Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Choix de la couleur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix() :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire (palette[0]).&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche (palette[1]).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant si notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; atteint bien une racine alors il faut savoir laquelle.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela on réutilise une boucle de minimum semblable a celle de set_racine():&amp;lt;br&amp;gt;&lt;br /&gt;
On compare les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on regarde quelle racine est la plus proche de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;. Cette fois-ci pas de cas ou z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; ne correspond à aucune racine car cela à été réglé par la fonction set_racine().&amp;lt;br&amp;gt;&lt;br /&gt;
On récupère donc l&#039;index de la racine associée dans R. Comme les deux première couleurs de notre palette (noir et blanc) sont déjà utilisée on utilise index+2 comme index à utiliser pour notre palette.&amp;lt;br&amp;gt;&lt;br /&gt;
De plus on crée une variable t qui sert &amp;quot;d&#039;atténuateur&amp;quot; que l&#039;on multiplie aux 3 composantes RGB de nos couleurs. Ainsi plus le nombre d&#039;itérations (I) de z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; sera grand plus t sera proche de zéro et plus la couleur sera terne et proche du noir alors qu&#039;à l&#039;inverse plus I est petit plus la couleur sera claire et proche du blanc.&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14129</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14129"/>
		<updated>2022-05-29T12:38:56Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Dessin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur à associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
&lt;br /&gt;
=== Choix de la couleur ===&lt;br /&gt;
Le dessin fait appel a la fonction set_color_pix :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_color_pix(self,npix):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Sélectionne la couleur en fonction de la racine atteinte.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        color = (0,0,0)&lt;br /&gt;
        if self.I[npix] &amp;gt;= self.N:&lt;br /&gt;
            color = self.palette[0]&lt;br /&gt;
        elif self.I[npix] == 0:&lt;br /&gt;
            color = self.palette[1]&lt;br /&gt;
        else:&lt;br /&gt;
                #Definition de la couleur a choisir&lt;br /&gt;
            index = 0&lt;br /&gt;
            mini = abs(self.R[0] - self.L[npix])&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - self.L[npix]) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - self.L[npix])&lt;br /&gt;
                    index = i&lt;br /&gt;
&lt;br /&gt;
            color = self.palette[index + 2]&lt;br /&gt;
&lt;br /&gt;
        t = (1-(self.I[npix]/self.N))**2&lt;br /&gt;
        color = (int(color[0]*t),int(color[1]*t),int(color[2]*t))&lt;br /&gt;
        return color&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Il y a deux cas de base pour lesquels le choix est rapide :&amp;lt;br&amp;gt;&lt;br /&gt;
- Si son nombre d’itération dépasse N alors on applique une couleur noire palette[0].&amp;lt;br&amp;gt;&lt;br /&gt;
- Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche palette[1].&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14128</id>
		<title>Fractales de Newton et sensibilité aux conditions initiales</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fractales_de_Newton_et_sensibilit%C3%A9_aux_conditions_initiales&amp;diff=14128"/>
		<updated>2022-05-29T12:35:57Z</updated>

		<summary type="html">&lt;p&gt;Pschultz : /* Dessin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Ce projet a été réalisé en Python sur PyScripter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Définition =&lt;br /&gt;
&lt;br /&gt;
Les fractales de Newton sont une représentation graphique des racines associées à chaque point complexe z d&#039;un plan.&amp;lt;br&amp;gt;&lt;br /&gt;
La fractale de Newton est définie dans le plan complexe et caractérisée par l&#039;application de la méthode de Newton à un polynôme complexe.&lt;br /&gt;
&lt;br /&gt;
= Construction =&lt;br /&gt;
&lt;br /&gt;
On utilise la méthode de Newton qui associe z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; à z-f(z)/f&#039;(z).&amp;lt;br&amp;gt;&lt;br /&gt;
Cette règle mène ensuite à une suite de points z&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;,z&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;,etc.. Si la suite converge vers une racine k du polynôme, alors z&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; appartient à la région k.&amp;lt;br&amp;gt;&lt;br /&gt;
Cette région est appelée &amp;quot;bassin d&#039;attraction de la racine k&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:fract_turt.png|700px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Remarque =&lt;br /&gt;
&lt;br /&gt;
On remarque rapidement en regardant les fractales de Newton que des similarités se distinguent à toutes échelle.&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:z**3-1.png|300px]] [[Fichier:z^3-1_zoom1.png|300px]] [[Fichier:z^3-1_zoom2.png|300px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant il existe aux frontières de ces bassins d’attraction des points pour lequel on ne trouve aucune convergence.&amp;lt;br&amp;gt;&lt;br /&gt;
Ces frontières très minces tendent à montrer une sensibilité très élevée aux condition initiales : trois points très proches peuvent avoir une racine distincte.&amp;lt;br&amp;gt;&lt;br /&gt;
Ici un décalage de +0.5i a été appliqué a chacun des points et ils ont tous une racine associée différente.&amp;lt;br&amp;gt;&lt;br /&gt;
[[fichier:fract_turt_sensi.png|700px]]&lt;br /&gt;
&lt;br /&gt;
= Programme =&lt;br /&gt;
Ce programme a donc pour but de calculer puis dessiner une fractale à partir d&#039;un polynôme complexe donné en paramètre.&amp;lt;br&amp;gt;&lt;br /&gt;
Il nécessite les bibliothèque scipy et PIL :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from scipy.misc import derivative&lt;br /&gt;
from PIL import Image&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Initialisation==&lt;br /&gt;
J’ai créé une classe Fractale pour diminuer le nombre de paramètres de chaque fonction et rendre certaines variables globales. On défini en tout 6 choses :&amp;lt;br&amp;gt;&lt;br /&gt;
  -	f : le polynôme complexe dont on veut la représentation&amp;lt;br&amp;gt;&lt;br /&gt;
  -	N : le nombre maximal d’itérations que peut faire une suite avant d’être dite « non-convergente »&amp;lt;br&amp;gt;&lt;br /&gt;
  -	R : la liste des racines du polynôme&amp;lt;br&amp;gt;&lt;br /&gt;
  -	L : la liste des z obtenu au terme de la suite de la méthode de Newton&amp;lt;br&amp;gt;&lt;br /&gt;
  -	I : le nombre d’itérations nécessaire à chaque z pour atteindre une racine&amp;lt;br&amp;gt;&lt;br /&gt;
  -	Palette : n’est autre que la palette de couleur utilisée pour dessiner les fractales&lt;br /&gt;
&lt;br /&gt;
Ce qui donne ceci :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Fractale:&lt;br /&gt;
&lt;br /&gt;
    def __init__(self,f,N=50):&lt;br /&gt;
        self.f = f  #Polynôme&lt;br /&gt;
        self.N = N  #Nombre maximal d&#039;itération avant la &amp;quot;non-convergence&amp;quot;&lt;br /&gt;
        self.R = [] #Liste des racines&lt;br /&gt;
        self.L = [] #Liste des z finaux des points&lt;br /&gt;
        self.I = [] #Liste du nombre d&#039;iteration&lt;br /&gt;
        self.palette = [(0,0,0),(255,255,255),(23, 49, 144),(174, 10, 10),(73, 53, 72),(38, 161, 0),(226, 219, 190),(134, 187, 216),(238, 66, 102),(184, 59, 21),(60, 187, 177),(64, 64, 64),(122, 122, 122),(192, 192, 192)]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main==&lt;br /&gt;
La fonction main est celle qui appellera toutes les autres pour assurer le bon fonctionnement du programme.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def main(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Programme principal&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
            #Initialisation des variables&lt;br /&gt;
        taille_img_x = int(input(&amp;quot;Taille x de votre image (une taille impair est préférable pour que le 0,0 soit centré)&amp;quot;))&lt;br /&gt;
        taille_img_y = int(input(&amp;quot;Taille y de votre image&amp;quot;))&lt;br /&gt;
        im = Image.new(&#039;RGB&#039;, (taille_img_x, taille_img_y), (255, 255, 255)) #Crée une image blanche de la taille souhaitée&lt;br /&gt;
        npix = 0 &lt;br /&gt;
        compteur = 0       &lt;br /&gt;
        pix_tot = taille_img_x*taille_img_y&lt;br /&gt;
&lt;br /&gt;
            #Set des coordonnées pour la création de z&lt;br /&gt;
        for pix_x in range(taille_img_x):&lt;br /&gt;
            for pix_y in range(taille_img_y):&lt;br /&gt;
                coord = Fractale.coordonees(pix_x,pix_y,taille_img_x,taille_img_y)&lt;br /&gt;
                x = coord[0]&lt;br /&gt;
                y = coord[1]&lt;br /&gt;
                z = complex(x,y)&lt;br /&gt;
&lt;br /&gt;
                    #Recuperation des resultats de calcul_racine()&lt;br /&gt;
                z_f = Fractale.calcul_racine(self,z) #Theoriquement proche d&#039;une racine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    #Definition de la racine&lt;br /&gt;
                Fractale.set_racine(self,z_f)&lt;br /&gt;
&lt;br /&gt;
                compteur +=1&lt;br /&gt;
            print((compteur/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            #Creation de l&#039;image&lt;br /&gt;
&lt;br /&gt;
        for i in range(taille_img_x):&lt;br /&gt;
            for j in range(taille_img_y):&lt;br /&gt;
                im.putpixel((i,j), Fractale.set_color_pix(self,npix))&lt;br /&gt;
                npix += 1&lt;br /&gt;
&lt;br /&gt;
            print(50+(npix/pix_tot*100)/2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        im.save(&amp;quot;Images\\Finale_pres\\z^5-1.jpg&amp;quot;,&amp;quot;JPEG&amp;quot;)&lt;br /&gt;
        print(&amp;quot;Votre image est prête&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
Pour que le programme s&#039;execute correctement il faut commencer par initialiser quelques variables:&lt;br /&gt;
  -  La taille de l&#039;image (en x et en y)&lt;br /&gt;
  -  im : Une toile blanche de la taille souhaitée sur laquelle &amp;quot;dessiner&amp;quot; notre fractale&lt;br /&gt;
  -  npix : ou numéro pixel qui servira plus tard pour le dessin&lt;br /&gt;
  -  compteur et pix_tot servent a l&#039;affichage en pourcentage de la progression du programme&lt;br /&gt;
&lt;br /&gt;
===Coordonnées===&lt;br /&gt;
Pour avoir le résultat souhaité on travaille avec des z de petite taille (généralement entre 2+2i et -2-2i).&amp;lt;br&amp;gt;&lt;br /&gt;
Pour ça il nous faut transformer les coordonnées pixels en coordonnées réelles. En effet les coordonnées d&#039;un image et d&#039;un plan ne sont pas traitée de la même façon :&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:transf_coord.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
En résolvant un petit système :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def coordonees(pix_x,pix_y,taille_x,taille_y):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Transforme les coordonnées pixel en coordonnées réelles.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        x_hi = 2&lt;br /&gt;
        x_lo = -2&lt;br /&gt;
        y_hi = -2&lt;br /&gt;
        y_lo = 2&lt;br /&gt;
        x = (((x_hi-x_lo)/taille_x)*pix_x) + x_lo&lt;br /&gt;
        y = (((y_hi-y_lo)/taille_y)*pix_y) + y_lo&lt;br /&gt;
        return (x,y)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
on obtient une équation et nous voilà avec des coordonnées utilisables pour nos calculs. On crée donc notre z complexe à partir du x et du y déduis de ce calcul.&lt;br /&gt;
&lt;br /&gt;
===Calculs===&lt;br /&gt;
&lt;br /&gt;
Mon programme utilise la méthode de Newton, c&#039;est un programme plutôt lent qui possède une complexité quadratique.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Avec le z calculé précédemment dans la fonction coord on peut donc effectuer la méthode Newton afin de trouver vers quelle racine il converge.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai eu besoin du module scipy et de sa fonction derivative qui renvoi le résultat de la dérivée de notre fonction. &amp;lt;br&amp;gt;&lt;br /&gt;
On défini donc Zn+1 comme étant z – f(z)/f’(z).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Compteur est le nombre d’itération effectuées jusqu’à ce que z trouve une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On stop donc la boucle de calcul si le nombre d’itérations dépasse N (un nombre arbitraire défini dans le init) ou si Zn+1 – Z est inferieur a 1*10-6 (la suite n’évolue plus).Théoriquement lorsque la suite ce stabilise c’est que l’on se trouve proche d’une racine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Une fois sortis de la boucle on ajoute à la variable globale I le nombre d’itérations effectuée pour ce z et on renvoi le z final obtenu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def calcul(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Compte le nombre d&#039;itérations necéssaire pour trouver une racine et s&#039;arrete après N itérations.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
        compteur = 0&lt;br /&gt;
&lt;br /&gt;
        while compteur &amp;lt; self.N and abs(Zn_plus_1 - z) &amp;gt;= 1e-6:&lt;br /&gt;
            z = Zn_plus_1&lt;br /&gt;
            Zn_plus_1 = z - (self.f(z) / derivative(self.f,z,1e-12))&lt;br /&gt;
            compteur += 1&lt;br /&gt;
&lt;br /&gt;
        self.I.append(compteur)&lt;br /&gt;
        return z&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Différentes méthodes====&lt;br /&gt;
Cependant, il existe d’autre méthodes ayant des résultats similaires avec des complexité moindre ou non.&amp;lt;br&amp;gt;&lt;br /&gt;
On peut notamment citer la méthode de la sécante avec une complexité linéaire de 1.618 qui approxime la dérivée au lieu de la calculer mais qui a donc un résultat moins précis.&amp;lt;br&amp;gt;&lt;br /&gt;
Pour utiliser ces autres méthodes il suffit de remplacer l&#039;affectation de z&amp;lt;sub&amp;gt;n+1&amp;lt;/sub&amp;gt; par celle de la méthode souhaitée.&amp;lt;br&amp;gt;&lt;br /&gt;
Je ne présenterai ici que la méthode de Newton.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:methodes_fract.png]]&lt;br /&gt;
&lt;br /&gt;
===Les racines===&lt;br /&gt;
&lt;br /&gt;
Comme vous l&#039;avez certainement remarquer ce programme ne demande pas a l&#039;utilisateur de renseigner les racines du polynôme.&amp;lt;br&amp;gt;&lt;br /&gt;
Cependant pour que le programme fonctionne il faut avoir accès aux racines.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela il existe les variables globales R et L. Pour rappel L sert a enregistrer les z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; obtenu en fin de process de la fonction calcul et R est la liste des racines.&amp;lt;br&amp;gt;&lt;br /&gt;
Or il faut remplir cette liste !&amp;lt;br&amp;gt;&lt;br /&gt;
C&#039;est la fonction set_racine qui s&#039;en occupe.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def set_racine(self,z):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Modifie le tableaux des racines R et celui des z finaux L.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if self.R == []:&lt;br /&gt;
            self.R.append(z)&lt;br /&gt;
            self.L.append(z)&lt;br /&gt;
        elif len(self.R) == 1:&lt;br /&gt;
            if abs(self.R[0] - z) &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
        else:&lt;br /&gt;
            mini = abs(self.R[0] - z)&lt;br /&gt;
            for i in range(len(self.R)):&lt;br /&gt;
                if abs(self.R[i] - z) &amp;lt; mini:&lt;br /&gt;
                    mini = abs(self.R[i] - z)&lt;br /&gt;
            if mini &amp;lt; 0.1:&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
            else:&lt;br /&gt;
                self.R.append(z)&lt;br /&gt;
                self.L.append(z)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Si R est vide on entre la valeur de notre z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; actuel comme première racine et on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; a la liste L.&amp;lt;br&amp;gt;&lt;br /&gt;
S’il n’y a qu’une seule racine on la compare à z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;, s’ils sont trop éloignés alors on crée une deuxième racine (en ajoutant z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à R) puis on ajoute z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à L. Sinon on ajoute juste z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; à la liste L sans ajouter de racine.&amp;lt;br&amp;gt;&lt;br /&gt;
Enfin s’il y en a plus on compare une à une toute les racines avec z&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt; et on sélectionne la plus proche avant d’effectuer la même chose que pour le cas à une seul racine.&lt;br /&gt;
&lt;br /&gt;
== Dessin ==&lt;br /&gt;
Nous avons désormais toutes les clés pour la réalisation de la fractale.&amp;lt;br&amp;gt;&lt;br /&gt;
Après avoir parcouru une première fois tout notre plan pour recueillir les information nécessaire il faut à présent recommencer pour changer la couleur de chacun des pixel e notre image.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Pour cela j’ai utilisé la bibliothèque Image de PIL qui permet de modifier une image à sa guise.&amp;lt;br&amp;gt;&lt;br /&gt;
Ainsi on peut sélectionner la couleur a associer au pixel en fonction de deux chose :&lt;br /&gt;
  -	Son nombre d’itération&lt;br /&gt;
  -	La racine atteinte&lt;br /&gt;
Si son nombre d’itération dépasse N alors on applique une couleur noire palette[0].&lt;br /&gt;
Sinon si son nombre d’itération est 0 alors c’est une racine et on lui donne un couleur blanche palette[1].&lt;/div&gt;</summary>
		<author><name>Pschultz</name></author>
	</entry>
</feed>