Mini-cours au groupe de travail "Images"
MMI, Lyon
Arnaud Chéritat

Retour


29 janvier 2016
2e partie, suite


Rappel: on a obtenu des images du type

avec seuil=40 et

avec seuil=500.

Je rappelle également la partie centrale du code qui a produit ces images:

[...]

def compute(j,i) :
  z = center + (j-width/2+(height/2-i)*1.0j)*xw/width
  k = 0
  reason = NONE
  while True:
    if k >= max_iter :  reason = MAX;   break
    if z.real > seuil : reason = SEUIL; break
    if z.real < 1. :    reason = BASIN; break
    z = cmath.exp(z-1.5)
    k += 1
  if reason==BASIN : return [255,255,255]
  if reason==SEUIL : return [0,0,255]
  return [255,0,0]

[...]
On a pris max_iter=50 mais aucun point n'atteint les 50 itérations sur les images d'exemple.

Revenons à l'analyse mathématique et essayons de comprendre ce que l'on voit sur le dessin. On a un demi-plan

P: Re(z)<1
dont l'image est un disque, D: B(0,e-0.5), qui contient le point fixe attractif a≈0.301 et qui est inclus dans P.
Quelle est la pré-image de P ? Par pré-image on entend l'ensemble f-1(P) des points qui s'envoient dans P en un coup par f . Cet ensemble va contenir P. Il va également contenir la pré-image du demi-plan Re(z)<0. Cette dernière est plus facile à déterminer sachant que si les coordonnées cartésiennes de z sont (x,y) alors les coordonnées polaires de exp(z) sont (ex,y), autrement dit
exp(x+iy)=exei y
donc
arg(exp(z-1.5))=Im(z)

Ainsi Re(f(z)) < 0 ⇔ Im(z) ∈ [π/2,3π/2] mod 2π, c.à.d. la préimage du demi-plan à gauche est la réunion d'une infinité de bandes horizontales de hauteur π translatées les unes des autres par des vecteurs dans 2iπℤ.
De même en utilisant une paramétrisation polaire de la droite bordant P, on peut déterminer la forme de f-1(P). En blanc ci-dessous...

... c'est le complémentaire d'une infinité de doigts, en noir sur le dessin. La période est toujours 2iπ.

La fonction f est une application conforme de chaque doigt vers le demi-plan complémentaire de P. Sur le dessin ci-dessous, une illustration exacte du caractère conforme. Les deux parties ne sont pas à la même échelle : à gauche un quadrillage du demi-plan complémentaire de P, à droite sa pré-image dans un doigt par f.

Dans le dessin ci-dessous, dont je ne fournis pas le code, j'ai indiqué un point noir au niveau du point attractif a. Le disque D est en blanc et le demi-plan P moins le disque est en gris clair. Je rappelle que a≈0.3, D=B(0,e-0.5≈0.6) et P: Re(z)<1. Le niveau de gris suivant indique f-1(P) moins P. Et le suivant f-2(P) moins f-1(P). Le reste est en rouge vif et coincide avec f-2(ℂ moins P). Le rouge désaturé indique un lieu ou le rouge et le gris sombre sont tellement serrés qu'on ne les distingue plus.

Dans chaque doigt, on voit ainsi en rouge une copie de la réunion de tous les doigts. Ce je vais appeler des doigts d'ordre 2. Si on continue à itérer, on verra les doigts d'ordre 2 se remplir de doigts d'ordre 3, etc...

La dérivée de la fonction exponentielle croît rapidement, elle est >1 sur tout l'ensemble de Julia et relativement élevée sur la majeure partie. Là où elle est élevée on constate une faible distorsion. En particulier, chaque génération de doigts occupe environ la moitié de l'aire de la génération précédente. (En fait ces aires sont infinies si on regarde dans le plan tout entier donc pour donner un sens à l'énoncé précédent, il faut comparer les aires dans une fenêtre donnée.)

Soit En la réunion de tous les doigts d'ordre n. Comme J(f) est (ici) l'intersection sur n des En, la perte d'aire mentionnée ci-dessus implique qu'il est en particulier de mesure de nulle (pour la mesure de Lebesgue*): la probabilité qu'un point choisi au hasard soit dans J est nulle.

*: étend la notion d'aire pour une grande classe de sous-ensemble du plan.
Ainsi, en poussant de plus en plus loin le nombre d'itérations et le seuil dans l'algorithme proposé plus haut:
on finirait par avoir une image toute blanche.

En pratique, cela requerrait d'augmenter considérablement la précision du calcul flottant, c.à.d. le nombre de bits utilisés pour représenter les réels.

Se pose ainsi la question de ce qu'on veut représenter. S'il semble naturel pour représenter un ensemble de colorier un pixel en fonction de l'aire que prend l'ensemble dans ce pixel, outre que c'est une technique a priori difficile, cela pose un problème pour les ensembles de mesure nulle : ils sont invisibles avec cette représentation.

Une ligne parfaite est invisible car infiniment fine : si on réalise un modèle physique de cette ligne, précise jusqu'à une l'échelle de quelques atomes, elle serait parfaitement invisible à l'oeil nu. Si on réalise un modèle précis à une dizaine de centimètres près d'une ligne droite et long de plusieurs kilomètres, elle sera invisible vue de loin. Il est d'ailleurs intéressant de savoir que les anneaux de Saturne sont tellements fins qu'ils sont pratiquement invisibles quand on les voit par la tranche.

Photo de saturne prise en 2007 par la sonde Cassini.
NASA/JPL Photojournal PIA09016.

Une approche classique pour représenter un ensemble fermé X de mesure éventuellement nulle consiste à le remplacer par son ε-voisinage : l'ensemble des points se trouvant à distance < ε de X. Ici ε est une petite distance qu'on choisit à l'avance, typiquement un peu plus grand que la taille d'un pixel. Nous reviendrons là dessus un peu plus bas.

Effet du seuil.

Revenons à l'algorithme et à son étude. Pour l'instant nous avons regardé les points qui finissent dans le bassin. Qu'en est-il de ceux qui finissent par dépasser le seuil ?

Les doigts sont la pré-image par f du demi-plan Re(z)>1 et la condition de seuil est définie par Re(z)>seuil, donc sa pré-image par f est le translaté des doigts vers la droite par la quantité log(seuil)-log(1). En effet, f est proportionnelle à exp. Cette pré-image, illustrée ci-dessous en bleu turquoise, est un incluse dans les doigts, représentés en noir. On voit qu'elle recouvre la majeure partie de ces derniers, même quand le seuil est grand.


Seuil=400

Rappellons que les points qui dépassent le seuil sont coloriés en bleu marine dans notre algorithme. Pour l'instant nous ne cherchons pas à justifier ce choix mais à en comprendre les conséquences.

La génération suivante de doigts est formée, je rappelle, des points qui tombent dans les doigts d'ordre 1 en appliquant f une fois, ceux qui tombent alors au delà du seuil vont former un sous-ensemble des doigts d'ordre 2 qui va être une copie du dessin ci-dessus. Et ainsi de suite pour toutes les générations. Ci-dessous un dessin pour 4 générations successives. J'ai appliqué une méthode de réduction des moirés que j'expliquerai plus loin. En tons orange on a les points qui finissent dans Re(z)<1 en 5 coups ou moins. En tons bleu turquoise ceux qui tombent dans Re(z)>seuil en 4 coups ou moins. Les tons sont dégradés en fonction du nombre de coups.


Seuil=60


Seuil=400

Revenons à la première image produite par l'algoritme, avec seuil=40. On sait maintenant expliquer les grandes zones arrondies. On sait aussi que les villosités qui s'y attachent en son des copies réduites (avec un peu de distorsion, et ce sur plusieurs générations.

Ce passage brusque d'un aspect zébré à une zone pleine est inélégant. De plus, la transition se fait le long d'une courbe lisse qui n'est pas du tout dans l'ensemble de Julia. Maintenant avec un seuil plus grand (500, proche du maximum possible avec cette méthode) :

On constate plusieurs problèmes: la courbe lisse a reculé mais est toujours visible. Sur les doigts d'ordre plus grand, elle a reculé encore moins. Les zones révélées possèdent des moirés considérables. La transition entre les moirés et les zones pleines est toujours très nette car les zones moirées semblent avoir des proportions de bleu et de blanc comparables, ce qui fait une moyenne bleu-clair.


Suite de la séance