Optimierung meines Mandelbrot-Explorers



  • Hallo, ich muss mich für meinen provokanten Post entschuldigen.

    @titan99_ Du hast recht, das will ich bestimmt nicht. Ich hoffe jedoch, dass mehr als Einer was sinnvolles beizutragen hat.

    @zeropage Ich hab das Programm noch mit C++Builder5 begonnen, und mühsam nach C++Builder2009 portiert, was wegen der LMD-Tools nicht gleich funktionierte. Damals gab es ja noch nicht mal HD! Zur Zeit arbeite ich mit immer noch 2009er und 2k + 1k Bildschirm. Skalierung war damals nicht nötig. Schon deshalb sollte die Benutzeroberfläche neu erstellt werden. Ich schaff das mit meinen 71Jahren wohl nicht mehr.

    @hustbaer Oh, ich bin sehr interessiert, und ich möchte nicht weiter im eigenem Saft schmoren. Deshalb hab ich vor kurzem fast alles auf https://github.com/RudiMBM/DeepChaos als Opensource bereitgestellt. Dort kann man eigenhändig ausprobieren welche Bilder die, hier besprochenen Skripts liefern, wenn man mit den Variablen mal variiert.

    Hier noch Script 3 als Pseudocode:

    
    struct	RV { float=ci, float=cr, int=ic, float=zq }   // zq = ci² + cr²  war für Script 1 u. 2
    Rv	r, rref;
    float	epsylon = 0.000001;
    
    rref.ci = rref.cr = 4;
    rref.ic = 0;
    
    loop	x, y
       loop	Itermax
    	{
    	r = iterate_1mal(x,y);
    	if ( abs(( r.ci - rref.ci ) + ( r.cr - rref.cr )) < epsylon ) return;  //Iterloop ende
    	if ( r.ic == rref.ic ) {
    		rref.ci = r.ci;
    		rref.cr = r.cr;
    		rref.ic *= 2;	
    	if ( iterate_end() ) return;
    	}
    

  • Gesperrt

    Dieser Beitrag wurde gelöscht!


  • @RudiMBM sagte in Optimierung meines Mandelbrot-Explorers:

    if ( abs(( r.ci - rref.ci ) + ( r.cr - rref.cr )) < epsylon ) return;

    Also falls das in deinem Programm auch so vorkommt: das ist falsch.
    Es müsste heissen

    if ( (abs( r.ci - rref.ci ) + abs( r.cr - rref.cr )) < epsylon ) return;
    


  • Hallo, ach du scheiße.... ich hab es nicht richtig beschrieben:

    tatsächlich habe ich programmiert:

    if ( abs( (abs( r.ci - rref.ci ) + abs( r.cr - rref.cr ))) < epsylon ) return;
    

    ist nicht falsch, aber Deine Version genügt und spart Rechenzeit. Die Bilder funktionieren aber mit beiden Versionen, deshalb hab ich nicht gezweifelt. Ich danke, dass Du mich zum zweifeln gebracht hast und zur Optimierung beigetragen hast.



  • Bitte 🙂



  • Lieb...
    ich geb es zu, ich hatte bedenken, dass Du zwecks mathematischer Genauigkeit fordern könntest:

    if ( sqrt( (r.ci - rref.ci )² + ( r.cr - rref.cr )²) < epsylon ) return;
    

    Das würde wegen des begrenzen Zahlenraumes im Computer die Genauigkeit halbieren und ausserdem viel Rechenzeit benötigen. Ohne dies ist es nur eine akzeptable Annäherung.



  • Jetzt bin ich verwirrt. Die Manhatten-Distance (abs(dx) + abs(dy)) zu verwenden war doch genau einer meiner Vorschläge. Siehe https://www.c-plusplus.net/forum/topic/351050/optimierung-meines-mandelbrot-explorers/21



  • Hallo. Ja war es. Zum Zeitpunkt der Diskussion war mir nicht klar wie das anzuwenden wäre. Ich war in Version 1 und 2 fixiert auf den Ansatz:

    if ( abs( r.zq - rref.zq )) < epsylon ) return;  //Iterloop ende
    

    Das ist die Differnz der Strecken r.c -> (0.0,0.0) mit rref.c->(0,0,0.0). Dies lässt aber die Argumente der Vektoren unberücksichtigt. Version 3 dagegen ermittelt, ob sich die Spirale des Iterationsverlaufes den späteren Ziel-Konvergenzkoordinaten nähert. Deshalb entstehen die, nur leicht welligen, Kreise in den Bildern, die die Iterationsnummern repräsentieren, bei der Abgebrochen wird. Ich vermute mit:

    if ( sqrt( (r.ci - rref.ci )² + ( r.cr - rref.cr )²) < epsylon ) return;
    

    verschwindet auch die Welligkeit, das ist es mir aber nicht wert.



  • Wenn du die Welligkeit auch noch wegbekommen willst könntest du es auch so machen:

    if ( (abs( r.ci - rref.ci ) + abs( r.cr - rref.cr )) < two_epsylon ) {
        if ( (( r.ci - rref.ci )² + ( r.cr - rref.cr )²) < epsylon_squared ) return;
    }
    

    Also die schnelle Variante als Vortest verwenden und dann den genauen Test zusätzlich machen.

    Ich kann jetzt nicht gut abschätzen wie viel das zusätzlich kosten würde, da ich nicht weiss wie schnell das am Ende konvergiert. Ich vermute aber dass es vermutlich relativ viel kosten würde, weil die meisten Dinge erst schnell und dann immer langsamer konvergieren. Könnte also leicht sein dass du bei sehr vielen Werten den 2. aufwendigeren Test machen musst.



  • Im Prinzip ja. Ich hab aber noch nicht getestet, wie sich der Vers3-Algo auf Iterationsverläufe auswirkt, die erst sehr spät divergieren (i>~100k). Könnte sein, sowas wird der M zugerechnet.
    Und im Computer, mit begrenztem Zahlenraum, kommt es zu einem Effekt, den ich als Pseudo-Konvergenz bezeichne. Ich werde in den nächsten Wochen(?) eine Doku.pdf auf GitHub einstellen, wo man dies findet.
    Kurzbeschreibung: Wenn die Genauigkeit des Zahlenraumes der Variablen nach vielen Iterationen ausgeschöpft ist, springt sie in einem Zyclus zurück, um immer wieder diesen Zyclus durchzurechnen. Dabei findet keine Konvergenz mehr statt, rechnet aber ewig. Ich hab den Vers.3-Algo noch nicht getestet, ob er diesen Effekt überlebt. Ich vermute, wenn Epsylon allzuklein gewählt ist, tritt dieser Fall ein.
    Ich wünschte mir, jemand hat Zeit und Lust mir beim Testen zu helfen.


Anmelden zum Antworten