{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![En tête general](img/En_tete_general.png)\n", "\n", "\n", "*(C) Copyright Franck CHEVRIER 2019-2020 http://www.python-lycee.com/*\n", "\n", " Pour exécuter une saisie Python, sélectionner la cellule et valider avec SHIFT+Entrée.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# L'ensemble de Mandelbrot \n", "\n", "Note : Cette activité ne nécessite pas la connaissance de l'écriture exponentielle d'un nombre complexe. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sommaire\n", "\n", "0. Définition de l'ensemble de Mandelbrot $\\mathcal{M}$
\n", "1. Étude mathématique du cas $c=i$.
\n", "2. Étude algorithmique du cas $c=1+i$.
\n", "3. Étude dans le cas général et représentation graphique
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 0. Définition de l'ensemble de Mandelbrot $\\mathcal{M}$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Pour tout $c \\in \\mathbb{C}$, on considère la suite de nombres complexes $(z_n)_{n \\geq 0}$ définie par :__\n", "\n", "\n", "__et on pose :__

\n", "$\\forall n \\in \\mathbb{N}$ ; $r_n = \\lvert z_n \\rvert$.

\n", "
\n", "Pour chaque valeur de $c$, la suite $(r_n)_{n \\geq 0}$ est soit bornée soit non bornée.

\n", " L'ensemble de Mandelbrot $\\mathcal{M}$ est l'ensemble des nombres complexes $c$ tels que la suite $(r_n)_{n \\geq 0}$ est bornée.\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Étude mathématique du cas $c=i$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Dans cette partie, on pose $c=i$.__

\n", "__1.1. Déterminer les formes algébriques des termes $z_1$, $z_2$ , $z_3$ et $z_4$.__

\n", "\n", "__1.2. Émettre une conjecture sur la valeur de $z_n$ suivant les valeurs de $n$, et démontrer cette conjecture.__

\n", "\n", "__1.3. $i$ appartient-il à l'ensemble $\\mathcal{M}$ de Mandelbrot ?__\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Étude algorithmique du cas $c=1+i$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Dans cette partie, on pose $c=1+i$.__

\n", "__2.1. En langage Python, le nombre complexe $i$ se code 1j et la fonction abs permet de calculer le module d'un nombre complexe.__
\n", "$\\quad\\;\\;$__a. Exécuter les cellules suivantes. Que permettent-elles de calculer ?__\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c = 1+1j ; z0 = 0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "abs(z0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "z1 = z0**2 +c\n", "z1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "abs(z1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\quad\\;\\;$__b. Effectuer des saisies pour calculer $z_2$ ; $z_3$, $r_2$ et $r_3$.__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Utiliser ces zones de saisie pour les calculs des termes\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__2.2. On souhaite maintenant automatiser le calcul des termes de la suite $(z_n)_{n \\geq 0}$.__
\n", "$\\quad\\;$__a. Définir une fonction Python z qui reçoit en argument n et renvoie le nombre complexe $z_n$.__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Écrire ici la fonction Python z\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\quad\\;$__b. Effectuer des appels à la fonction z pour retrouver les valeurs de $z_1$ ; $z_2$ et $z_3$.__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Utiliser ces zones de saisie pour les calculs des termes\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\quad\\;$__c. À l'aide de la fonction Python z, déterminer $z_6$ puis $r_6$.__
\n", "$\\quad\\quad$__La suite $(r_n)_{n \\geq 0}$ semble-t-elle bornée?__
\n", "$\\quad\\quad$__$1+i$ semble-t-il appartenir à l'ensemble $\\mathcal{M}$ de Mandelbrot ?__\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Utiliser ces zones de saisie pour les calculs\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Étude dans le cas général et représentation graphique" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Dans cette partie, on revient au cas général où $c \\in \\mathbb{C}$ est quelconque.__

\n", "__3.1. Redéfinir la fonction Python z (vue en 2.2.a) pour qu'elle reçoive en arguments n et c (dans cet ordre) et renvoie le nombre complexe $z_n$.__\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Écrire ici la fonction Python z\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Pour la suite, on admettra et on utilisera le résultat suivant :__\n", "\n", "
\n", "S'il existe un rang $N$ tel que $r_N>2$, alors la suite $(r_n)_{n \\geq 0}$ n'est pas bornée, et le nombre $c$ n'appartient alors pas à l'ensemble $\\mathcal{M}$ de Mandelbrot.\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__3.2. À l'aide de la fonction Python z, calculer $z_{10}$ puis $r_{10}$ dans le cas où $c=\\displaystyle\\frac{1+2i}{3}$.__
\n", "$\\quad\\;$__Le nombre $\\displaystyle\\frac{1+2i}{3}$ appartient-il à l'ensemble $\\mathcal{M}$ de Mandelbrot ?__\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Utiliser ces zones de saisie pour les calculs\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__3.3. Pour permettre de conjecturer si un nombre complexe $c$ appartient ou non à l'ensemble $\\mathcal{M}$ de Mandelbrot, on considère la fonction Python app_M donnée ci-dessous. Décrire la méthode expérimentale utilisée : Quel critère est appliqué ?__\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def app_M(c,N=30):\n", " \"\"\"\n", " Fonction qui conjecture si c appartient à l'ensemble de Mandelbrot\n", " \"\"\"\n", " for n in range(N):\n", " if abs(z(n,c))>2:\n", " return False\n", " \n", " return True " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__3.4. Effectuer des appels à la fonction app_M pour conjecturer si les nombres $\\displaystyle\\frac{1}{2}$ ; $\\displaystyle\\frac{i}{2}$ et $\\displaystyle-\\frac{3+2i}{5}$ appartiennent à $\\mathcal{M}$.__ " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Utiliser ces zones de saisie pour les appels à la fonction app_M\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__3.5 Grâce à la fonction Python app_M, on peut approcher la représentation graphique de l'ensemble de Mandelbrot dans le plan complexe.__
\n", "$\\quad$__Exécuter la fonction graph_M donnée ci-dessous pour visualiser $\\mathcal{M}$ (patienter quelques instants pendant les calculs...).__\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#import des modules nécessaires\n", "from PIL import Image, ImageDraw\n", "\n", "def graph_M(app_M=app_M,profondeur=30,xmin=-2,xmax=1,ymin=-1,ymax=1,pix_unite=250,couleur_fond=(223,242,255),couleur_figure=(49,140,231),couleur_axes=(34,66,124),nom=\"Ensemble de Mandelbrot\"):\n", " \"\"\"\n", " REPRESENTATION GRAPHIQUE D'UN ENSEMBLE DE COMPLEXES\n", " app_M: fonction booléenne qui indique si un complexe appartient à l'ensemble représenté\n", " profondeur: profondeur de la recherche pour la fonction app_M\n", " xmin, xmax, ymin, ymax : paramètres de réglage de la fenêtre de visualisation\n", " pix_unite: nombre de pixels par unité\n", " couleur_fond: couleur du fond\n", " couleur_figure: couleur de l'ensemble représenté\n", " couleur_axes: couleur des axes\n", " nom: nom de l'ensemble représenté\n", " \"\"\"\n", " \n", " # création du graphique\n", " largeur=pix_unite*(xmax-xmin)+1 ; hauteur=pix_unite*(ymax-ymin)+1 \n", " Graphique = Image.new('RGB', (largeur,hauteur), color = couleur_fond ) \n", " Curseur = ImageDraw.Draw(Graphique)\n", " \n", " # tracé de l'ensemble M\n", " for X in range(largeur):\n", " for Y in range(hauteur):\n", " # création des coordonnées mathématiques correspondant aux coordonnées de l'image\n", " x,y = xmin+X*(xmax-xmin)/largeur,ymin+(hauteur-Y)*(ymax-ymin)/hauteur\n", " # construction du complexe c\n", " c = complex(x,y)\n", " # coloration du point si c appartient à M\n", " if app_M(c,N=profondeur): Curseur.point([X, Y], couleur_figure)\n", "\n", " def conv_coord(x,y):\n", " \"fonction qui convertit une coordonnée du repère mathématique en coordonnée sur l'image\"\n", " return (x-xmin)*pix_unite,(y-ymin)*pix_unite,\n", " \n", " # tracé des axes\n", " Curseur.line([conv_coord(xmin,0),conv_coord(xmax,0)],fill=couleur_axes)\n", " Curseur.line([conv_coord(0,ymin),conv_coord(0,ymax)],fill=couleur_axes)\n", " \n", " # création des graduations annotées\n", " for x in range(int(xmin),int(xmax)+1):\n", " Curseur.line([conv_coord(x,-0.02),conv_coord(x,0.02)], fill=couleur_axes) \n", " Curseur.text(conv_coord(x+(-0.05 if x>=0 else 0.03),0.02),str(x),fill=couleur_axes)\n", " for y in range(int(ymin),int(ymax)+1):\n", " Curseur.line([conv_coord(-0.02,y),conv_coord(0.02,y)], fill=couleur_axes) \n", " Curseur.text(conv_coord(0.02,y+(-0.07 if y>=0 else 0.03)),str(-y),fill=couleur_axes)\n", " \n", " # écriture du titre / nom de la figure\n", " Curseur.text((0,0),nom,fill=couleur_figure)\n", " \n", " return Graphique\n", "\n", "graph_M()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Benoit_Mandelbrot](img/Benoit_Mandelbrot.jpg)\n", "\n", "
Benoit Mandelbrot (1924-2010) est considéré comme le découvreur des figures fractales, dont l'ensemble de Mandelbrot fait partie.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", " \n", "
Ensembles de Julia
\n", "
\n", "
\n", "

$\\quad$ Pour aller plus loin: Voir l'activité sur les ensembles de Julia.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*(C) Copyright Franck CHEVRIER 2019-2020 http://www.python-lycee.com/*\n" ] } ], "metadata": { "celltoolbar": "Raw Cell Format", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 2 }