Zum Inhalt springen

Mandelbrot-Menge (Praktische Berechnung)

aus AufEinWort, der freien Forschung

Die grafische Darstellung der Mandelbrot-Menge und ihrer Strukturen im Randbereich ist nur mittels Computer durch sogenannte Fraktalgeneratoren möglich. Dabei entspricht jeder Bildpunkt einer Zahl c der komplexen Ebene. Der Computer ermittelt für alle Bildpunkte, ob die zugehörigen Folgen divergieren oder nicht. Sobald der Betrag |zn| eines Folgengliedes die Fluchtgrenze s=2 überschreitet, ist klar, dass die Folge divergiert; die Iterationszahl n kann als Maß für den Divergenzgrad dienen. Die Bildpunkte werden nach einer Farbtabelle eingefärbt, die jeder Iterationszahl eine Farbe zuordnet.[1]

Für harmonische Farbübergänge wird in der Praxis ein Fluchtradius r>2 gewählt, da andernfalls die Breite der Farbstreifen zu sehr oszilliert. Je größer der Fluchtradius gewählt wird, desto besser entsprechen die Farbgrenzen den Äquipotentiallinien, die sich ergeben, wenn die Mandelbrot-Menge als elektrisch geladener Leiter interpretiert wird. Für kontinuierliche Farbverläufe, wie in der obigen Galerie einer Zoomfahrt, ist es erforderlich, entweder die genaue Fluchtzeit t zu ermitteln, bei der der Fluchtradius r gerade erreicht wird, oder den Abstand d zum Rand der Menge abzuschätzen.[2]

Da die Anzahl der Iterationsschritte n, nach der die Fluchtgrenze s=2 überschritten wird, beliebig groß sein kann, muss als Abbruchkriterium eine maximale Iterationszahl nmax festgelegt werden. Alle Zahlen c, deren Folgen danach einen Fluchtradius r>2 noch nicht erreicht haben, werden zur Menge 𝕄 gezählt. Je geringer der Abstand von c zum Rand der Menge ist, desto größer ist in der Regel die Iterationszahl n, bei der r erreicht oder überschritten wird. Je stärker die Vergrößerung ist, mit der der Rand dargestellt wird, desto größer muss die maximale Iterationszahl nmaxgewählt werden, und umso mehr Rechenzeit ist nötig.

Ein erheblicher Teil der Rechenzeit wird dort benötigt, wo die Zahlenfolge nicht divergiert. Moderne Programme versuchen daher, die Rechenzeit an diesen Stellen durch verschiedene Verfahren zu verkürzen. Eine Möglichkeit besteht darin, die Berechnung abzubrechen, sobald die Zahlenfolge konvergiert oder in einem periodischen Zyklus gefangen ist. Andere Programme nutzen aus, dass das Innere einer geschlossenen Kurve automatisch in 𝕄 liegt, wenn der Randbereits zu 𝕄 gehört.[3]

Grafisch besonders reizvoll ist die Darstellung des Randes von 𝕄 mit seinem Formenreichtum. Je stärker die gewählte Vergrößerung ist, umso komplexere Strukturen lassen sich dort finden. Mit entsprechenden Computerprogrammen lässt sich dieser Rand wie mit einem Mikroskop mit beliebiger Vergrößerung darstellen. Zur Untersuchung interessanter Strukturen sind häufig Vergrößerungen erforderlich, die mit hardwareunterstützten Datentypen aufgrund deren limitierter Genauigkeit nicht berechnet werden können. Manche Programme enthalten daher Langzahlarithmetik-Datentypen mit beliebig wählbarer Genauigkeit. Damit sind (fast) beliebige Vergrößerungsfaktoren möglich.

Interpolation und Distanzschätzung

[✐ | ✎]

Wenn der Fluchtradius r groß genug ist, kann zur Ermittlung der Fluchtzeit t anstelle der eigentlichen Folge zn+1=zn2+c mit z0=0 die vereinfachte Folge zn+1=zn2+0 mit z0=c betrachtet werden. Die ersten Folgenglieder sind dann z0=c, z1=c2, z2=c4 und z3=c8, ganz allgemein ergibt sich zn=c2n. Betrachtet man eine Iterationszahl n, bei der die Folge einen Fluchtradius r≫2 erreicht oder überschreitet, so gilt |zn|=|c|2n≥r und n=log2(ln⁡|zn|ln⁡|c|). Bestimmt man nun die Fluchtzeit t≤n aus der Interpolation |c|2t=r, so ergibt sich mit t=log2(ln⁡rln⁡|c|):[4][5]

n−t=log2(ln⁡|zn|ln⁡|c|)−log2(ln⁡rln⁡|c|)=log2(ln⁡|zn|ln⁡r).[6]

Für |zn(c)|≥r≫2 erhält man die Fluchtzeit t(c)=n−log2(ln⁡|zn(c)|ln⁡r) aus einer Korrektur (Normalisierung) der Iterationszahl n. Die äquivalente Gleichung 12nln⁡|zn(c)|=2−t(c)ln⁡r weist auf die enge Beziehung der Potentialfunktionen Φn(c)=12nln⁡|zn(c)| und Ψr(c)=2−t(c)ln⁡r hin. Häufig wird das Potential als GrenzwertV(c)=limn→∞Φn(c) definiert; die Potentialfunktion Ψe(c)=2−t(c)=e−t(c)ln⁡2 zur Eulerschen Zahl mit ln⁡e=1 wird nach George Green mit G(c) bezeichnet.[7][8]

Nähert sich c dem Rand der Menge, so wird das Potential immer kleiner und erreicht am Rand den Grenzwert null. Daher kann der kürzeste Vektor v→ vom Punkt c zum Rand näherungsweise aus der Gleichung Φn(c)+v→⋅∇Φn(c)=0durch ein Skalarprodukt mit dem Gradientenvektor u→=∇Φn(c) ermittelt werden. Man erhält so eine Lösung v→ mit der Länge |v→|=Φn(c)|∇Φn(c)|=ln⁡|zn(c)||∇ln⁡|zn(c)||. Aus ∇ln⁡|zn(c)|=1|zn(c)|∇|zn(c)| und |∇|zn(c)||=|zn′(c)| folgt die Distanzformel:[9][8]

dn(c)=ln⁡|zn(c)||∇ln⁡|zn(c)||=ln⁡|zn(c)|:|zn′(c)zn(c)|=ln⁡|zn(c)|⋅|zn(c)zn′(c)|.[10]

Die ersten Polynome sind z0(c)=0, z1(c)=c, z2(c)=c2+c und z3(c)=(c2+c)2+c, die zugehörigen Ableitungensind z0′(c)=0, z1′(c)=1, z2′(c)=2c+1 und z3′(c)=2(c2+c)(2c+1)+1. Alle weiteren Folgenglieder ergeben sich aus der Iterationsvorschrift zn+1(c)=zn2(c)+c und der Ableitungsregel zn+1′(c)=2zn(c)zn′(c)+1.

Um die Distanzformel einzusehen, kann wieder die vereinfachte Folge zn+1=zn2+0 mit z0=c betrachtet werden. Die zugehörige Julia-Menge ist genau der Rand des Einheitskreises, und mit zn=c2n und zn′=2nc2n−1 ergibt sich

dn=ln⁡|c2n|⋅|c2n2nc2n−1|=2nln⁡|c|⋅|c2n|=ln⁡|c|⋅|c|,

was in der Nähe des Einheitskreises eine gute Näherung für den Abstand d=|c|−1 zum Rand ist: |c|=1,1 ergibt dn=ln⁡(1,1)⋅1,1≈0,1 und |c|=1,01 ergibt dn=ln⁡(1,01)⋅1,01≈0,01. Wenn der wirkliche Abstand zum Rand gleich d ist, so ergibt die Distanzformel den Wert

dn=ln⁡|zn|⋅|znzn′|≈ln⁡(1+d)⋅(1+d)≈d.

Es stimmt aber nicht, dass der Grenzwert limn→∞dn gegen den wirklichen Abstand d konvergiert, tatsächlich gelten nur schwächere Ungleichungen. Die Abschätzung kann mithilfe der lambertschen W-Funktion jedoch etwas verbessern werden, und mit W(dn)≈ln⁡(1+d) erhält man:[11][12]

dn≈ln⁡(1+d)eln⁡(1+d)⟺d≈eW(dn)−1.

Deep Zoom und Störungsrechnung

[✐ | ✎]
Vergleich der Blockartefakte mit dem Original (beide Bilder haben dieselbe Pixelanzahl)[A 1]

Prozessoren unterstützen in Hardware die Berechnung mit typischerweise 32-bit- und 64-bit-Gleitkommazahlen. Dies ermöglicht es, in die Mandelbrot-Menge etwa um den Faktor 1012 bis 1013 hineinzuzoomen, bevor benachbarte Pixel keine unterschiedlichen Startwerte c mehr annehmen können (und damit Fehler durch Blockartefakte offensichtlich werden).

Ab diesem Punkt reicht die Genauigkeit der in Hardware implementierten Arithmetik nicht mehr aus. Man ist gezwungen, auf in Software implementierte Routinen für hochgenaue Arithmetik auszuweichen, was bei aktuellen Prozessoren zu einem immensen Geschwindigkeitseinbruch führt.

Man kann diesen deutlich durch Nutzen von Störungsrechnung reduzieren. Diese Methode wurde 2013 von Kevin Martin beschrieben und 2021 von Zhuoran Yu um eine automatische Fehlerkorrektur erweitert.[13][14]

Dazu wird ein (möglichst nicht divergenter) Referenzpunkt c in hochgenauer Arithmetik durchgerechnet und die zugehörige Referenzserie zn in einfacher oder doppelter Genauigkeit aufgezeichnet:[15]

z0, z1, z2, z3,…,zn.

Für in der direkten Nähe liegende Punkte c′=c+δ würde sich die Serie zn′ ergeben:

z0′, z1′, z2′, z3′,…,zn′.

Man will nun die Abweichung εn=zn′−zn indirekt ermitteln, um die direkte Berechnung der Serie zn′ zu vermeiden. Dabei gilt:

zn+1=zn2 +c  für die Berechnung des Referenzpunktes und
zn′+1′=zn′2+c′  mit zn′+1′=zn+1+εn+1 und zn′=zn+εn für die Berechnung des Nachbarpunktes.

Setzt man ein, ergibt sich

zn+1+εn+1=zn′+1′=zn′2+c′=zn′2+(c+δ)=(zn+εn)2+(c+δ).

Man betrachtet die beiden äußeren Terme

zn+1+εn+1=(zn+εn)2+(c+δ)  und multipliziert aus
zn+1+εn+1=(zn2+2znεn+εn2)+(c+δ)  und setzt zn+1=zn2+c
zn2 +c+εn+1=(zn2+2znεn+εn2)+(c+δ)  und löst die Klammern auf und kürzt
zn2+c+εn+1=zn2+2znεn+εn2+c+δ  und erhält
εn+1=2znεn+εn2+δ.

Wegen z0=0 und z0′=0 ist auch ε0=z0′−z0=0. Mit der abgespeicherten Referenzserie zn können die Abweichungen εn der Reihe nach berechnet werden:

ε1=2z0ε0+ε02+δ=δ,
ε2=2z1ε1+ε12+δ,
ε3=2z2ε2+ε22+δ,
 ⋮
εn=2zn−1εn−1+εn−12+δ.

Solange diese Terme klein bleiben, verhält sich zn′=zn+εn ähnlich wie zn. Insbesondere bleibt die Serie zn′beschränkt, wenn die Referenzserie zn und die Abweichungen εn beschränkt sind. Wenn die Abweichungen jedoch zu groß werden, kann das zu Fehlern in der Darstellung (Glitches) führen. Im Prinzip kann man dann auf einen günstigeren Referenzpunkt innerhalb der Referenzserie ausweichen: Liegt ein Punkt z=zn+εn näher am Referenzpunkt zm als am aktuellen Referenzpunkt zn, so kann er auch durch z=zm+εm dargestellt und die Abweichung aus der Differenz εm=z−zm berechnet werden. Allerdings verliert man bei einer solchen Subtraktion aufgrund der Auslöschung die notwendige Genauigkeit. Nur beim ersten Referenzpunkt zm=z0=0 passiert das nicht, und die Abweichung ergibt sich zu εm=z−0=z. Man kann somit die Referenzserie zurücksetzen, wenn |z|<|εn| gilt, d. h. wenn der Abstand von z zu z0 kleiner als der Abstand von z zu zn ist. Dieses gelegentliche Zurücksetzen der Referenzserie (Rebasing) hält die Abweichungen so klein wie möglich.

Praktische Anwendung

Das Programm „Kalles Fraktaler“ basiert auf diesem Ansatz, und die bilineare Approximation ermöglicht noch leistungsfähigere Fraktalgeneratoren. Die Iterationsvorschrift εn+1=(2zn+εn)⋅εn+δ lässt sich linearisieren, wenn |εn|≪|zn| gilt, d. h. wenn εn viel kleiner als zn ist und man εn in der Summe 2zn+εn vernachlässigen kann.[16]Benachbarte Linearisierungen εn+1=2znεn+δ, εn+2=2zn+1εn+1+δ, …, εn+k=2zn+k−1εn+k−1+δ lassen sich zur bilinearen Gleichung εn+k=an,kεn+bn,kδ zusammenfassen.[17] Die Koeffizienten an,k und bn,k werden vorab berechnet und dienen während der Iteration als Abkürzung, um viele Iterationen zu überspringen, wenn |εn|⋘min⁡{|zn|,|zn+1|,…,|zn+k−1|} gilt, d. h. wenn εn sehr viel kleiner als zn, zn+1, …, zn+k−1 ist. Häufig können über 90 % der Iterationen übersprungen werden, was die Berechnung extrem beschleunigt.[18][19]

Probleme
  1. Der verwendete Referenzpunkt sollte möglichst innerhalb der zu untersuchenden Iterationen nicht divergieren, da die Nachbarpunkte maximal bis zu dem Abbruch der Referenzserie untersucht werden können. Alle Punkte mit einer größeren Iterationszahl müssen erneut berechnet werden. Die Auswahl und das Verwerfen von sich als ungeeignet herausgestellten Referenzpunkten stellt eine Herausforderung dar.
  2. Für die Berechnung der Abweichungen εn wird keine hohe Genauigkeit benötigt, allerdings ist der Wertebereich von 64-bit-Gleitkommazahlen arg limitiert. Ab etwa 10300 muss man leider mit eigenen Mathematikroutinen arbeiten, die zwar nur eine 52/64 bit-Mantisse benötigen, aber deutlich langsamer als hartkodierte Gleitkomma-Operationen sind (die aber wesentlich schneller als Berechnungen mit langen Mantissen sind).[20][21]
  3. Man benötigt Speicherbandbreite für das Lesen der Referenzserie zn. Die erste Verlangsamung gibt es, wenn diese nicht mehr in den L2-Cache passt, sehr viel langsamer wird es, wenn der L3-Cache nicht mehr ausreicht und auf den RAM zugegriffen werden muss.
  4. Es gibt Abweichungen zwischen der nativen Iteration mit c′ und der Störungsrechnung basierend auf c′=c+δ.Sieht man sich das ganze genauer an, ist die Berechnung basierend auf c′=c+δ meistens genauer, wenn die Referenzpunktberechnung hinreichend genau war (was mit Langzahlarithmetik für diesen einen Wert aber problemlos machbar ist).

Berechnungsgeschwindigkeit

[✐ | ✎]

Berechnungen nahmen beim Stand der Technik Ende der 1980er Jahre viel Zeit in Anspruch. Vergleichsweise zeigt dies eine Aufstellung durch die Anzahl der Iterationen, die verschiedene CPUs pro Sekunde durchführen konnten.

CPU Jahr Genauigkeit (Software) Geschwindigkeit

in Iterationen/sec

Rechendauer für

8,8 Mrd. Iterationen

Z80 @1,75 MHz 1987 32 bit Gleitkomma (1.) 9 31 Jahre
Z80 @2,45 MHz 32 bit Integer (2.) 280 01 Jahr
80386 SX/20 +

IIT 3C87SX/20

1992 32 bit Integer (3.) 130.000 19 Stunden
80 bit Gleitkomma (FPU) (3.) 75.000 33 Stunden
80 bit Gleitkomma (Emulation Borland) (3.) 2.000 51 Tage
Pentium 90 1994 32 bit Integer (3.) 1.450.000 01 Stunde 40 Minuten
80 bit Gleitkomma (3.) 2.900.000 50 Minuten
Xeon E5-2623 v3

× 2 (Dual Socket)

2015 32 bit Gleitkomma (4.) 50.000.000.000 0,177 Sekunden
64 bit Gleitkomma (4.) 25.000.000.000 0,35 Sekunden
Eingesetzte Software
  1. BASIC-Interpreter des KC 85/3
  2. Selbst geschriebener Assemblercode[22]
  3. Borland C++ mit integriertem Assembler, die Gleitkomma-Emulation dieses Compilers war vergleichsweise langsam[23]
  4. Visual Studio C++ mit Intel Intrinsics, Nutzung von AVX2 und Fused multiply-add, multithreaded, 2 Threads pro Core
Eingesetzte Prozessoren
  • Z80: 8-Bit-Prozessor ohne Hardware-Multiplikation
  • 80386: 32-Bit-Prozessor mit Hardware-Multiplikation und Gleitkomma-Koprozessor
  • Pentium: 32-Bit-Prozessor mit Hardware-Multiplikation und mit eingebautem Gleitkomma-Koprozessor
  • Xeon E5-2623: Vektorbefehle, 4 Kerne/8 Threads pro Sockel
  1. ↑ Robert P. Munafo: Escape Radius. In: mrob.com. 1997; (englisch).
  2. ↑ Robert P. Munafo: Equipotential Lines. In: mrob.com. 2023; (englisch).
  3. ↑ Dieser Zusammenhang ergibt sich aus dem Maximumprinzip: Wenn jeder Randpunkt |zn|≤2 erfüllt, dann müssen auch alle inneren Punkte |zn|≤2 erfüllen.
  4. ↑ Inigo Quilez: Continuous iteration count. In: iquilezles.org. 2007; (englisch).
  5. ↑ Jussi Härkönen: On Smooth Fractal Coloring Techniques. (PDF; 14 MB) The Smooth Iteration Count Coloring. In: jussiharkonen.com. 2007, S. 14–26, archiviert vom Original (nicht mehr online verfügbar) am 18. Juni 2014; (englisch).
  6. ↑ Die Folge zn+1=zn2+c wächst für |zn|≥r≫2 wie eine einfache Folge zn′+1′=zn′2+0 mit |z0′|=|zn|1/2n. Der genaue Anfangswert z0′=c′ verschwindet jedoch aus der Differenz n−t und ist daher ohne Bedeutung.
  7. ↑ Arnaud Chéritat: Mandelbrot set. The potential. In: math.univ-toulouse.fr. 2016; (englisch).
  8. ↑ a b Kees van den Doel: Notes on Mandelbrot set (Draft). (PDF; 0,2 MB) Basics. In: persianney.com. 2018, S. 1–2; (englisch).
  9. ↑ Inigo Quilez: Computing the SDF of fractals. In: iquilezles.org. 2004; (englisch).
  10. ↑ Die Division durch zn(c) und zn′(c) ist im Außen­bereich |zn|>2 immer möglich, da alle Nullstellen von zn und zn′ im Innen­bereich |zn|≤2 liegen (vgl. die Sätze von Gauß-Lucas und Jensen).
  11. ↑ Mikael Hvidtfeldt Christensen: Distance Estimated 3D Fractals (V): The Mandelbulb & Different DE Approximations. The potential gradient approximation. In: blog.hvidtfeldts.net. 2011; (englisch).
  12. ↑ Yumei Dang, Louis Kauffman, Daniel Sandin: Hypercomplex Iterations, Distance Estimation and Higher Dimensional Fractals. (PDF; 4,1 MB) Distance Estimation in Complex Space. In: evl.uic.edu. 2002, S. 13–29; (englisch).
  13. ↑ Phil Thompson: Perturbation Theory and the Mandelbrot set. In: philthompson.me. 2022; (englisch).
  14. ↑ Robert P. Munafo: Perturbation Methods. In: mrob.com. 2023; (englisch).
  15. ↑ Robert P. Munafo: Derivative Extrapolation. In: mrob.com. 2023; (englisch).
  16. ↑ Liegt der Quotient |εn|/|2zn| unterhalb der Maschinengenauigkeit, dann ist der Rundungsfehler bei der Addition von εn genauso groß wie der Fehler durch die Linearisierung.
  17. ↑ Diese Idee lässt sich auf die Ableitung zn+1′=2znzn′+1 mit zn′+1′+εn′+1′=2(zn+εn)(zn′+εn′)+1 übertragen. Für |εn|≪|zn| erhält man εn′+1′=2znεn′ und εn′+k′=an,kεn′ (Programmbeispiel).
  18. ↑ Claude Heiland-Allen: Kalles Fraktaler 2 +. In: mathr.co.uk. 2022; (englisch).
  19. ↑ Robert P. Munafo: Bivariate Linear Approximation. In: mrob.com. 2023; (englisch).
  20. ↑ Geoffroy Billotey: Fractalshades: Extended range floating points. In: github.io. 2023; (englisch).
  21. ↑ Robert P. Munafo: Floatexp. In: mrob.com. 2023; (englisch).
  22. ↑ der allerdings noch nicht das theoretische Limit darstellte, die verwendet Multiplikation war schnell, es gibt aber noch schnellere, siehe Multiplication 32 x 32 bit, base case
  23. ↑ Compiler, die direkte Bibliotheksaufrufe erzeugten und bei Vorhandensein einer 32-bit-CPU 32-bit-Befehle nutzten, waren deutlich schneller. Keine Messwerte mehr verfügbar.


Referenzfehler: <ref>-Tags existieren für die Gruppe A, jedoch wurde kein dazugehöriges <references group="A" />-Tag gefunden.