Die merkwürdige Anziehungskraft der Logistikkarte

21

Der Zweck der Herausforderung besteht darin, den Attraktor der logistischen Karte als Funktion seines Parameters r (auch als Bifurkationsdiagramm bezeichnet ) oder eines Teilbereichs davon ungefähr zu zeichnen . Das Aussehen des Graphen ist auf dem folgenden Bild von Wikipedia zu sehen:

Bildbeschreibung hier eingeben

Hintergrund

Die logistische Abbildung ist eine mathematische Funktion, die eine Eingabe x k auf eine Ausgabe x k + 1 abbildet, die als definiert ist

             x k + 1 = r x k (1 - x k )

Dabei ist r der Parameter der Karte, der im Intervall [0, 4] liegen soll.

Bei gegebenem r in [0,4] und einem Anfangswert x 0 im Intervall [0,1] ist es interessant, die Funktion wiederholt für eine große Anzahl N von Iterationen anzuwenden , wodurch ein Endwert x N erzeugt wird . Beachten Sie, dass x N notwendigerweise auch in [0,1] liegt.

Als Beispiel sei r = 3,2, N = 1000 angenommen. Der Anfangswert x 0 = 0,01 ergibt x 1000 = 0,5130. Für x 0 = 0,02 ist das Ergebnis x 0 = 0,7995. Für alle anderen Anfangswerte x 0 liegen die Endwerte x 1000 extrem nahe an 0,5130 oder 0,7995. Dies ist in der Grafik als die Höhe der beiden Linien bei horizontaler Position r = 3,2 zu sehen.

Dies bedeutet nicht , dass für r = 3,2 jede Sequenz zu einem dieser beiden Werte konvergiert. Tatsächlich sind für die beiden oben betrachteten Anfangswerte die Sequenzen (beachte das oszillierende Verhalten):

             x 0 = 0,01, ..., x 1000 = 0,5130, x 1001 = 0,7995, x 1002 = 0,5130, ...
             x 0 = 0,02, ..., x 1000 = 0,7995, x 1001 = 0,5130, x 1002 = 0,7995 , ...

Was ist wahr , dass für hinreichend große N , und für fast alle Anfangswerte x 0 , der Begriff x N schließen sein wird, eines der Elemente der Menge {0,5130, 0,7995}. Diese Menge wird der Attraktor für dieses spezifische r genannt .

Bei anderen Werten des Parameters r ändert sich die Größe des Atraktorsatzes oder seiner Elemente. Das Diagramm zeigt die Elemente im Attraktor für jedes r .

Der Attraktor für ein bestimmtes r kann geschätzt werden durch

  1. Testen eines weiten Bereichs von Anfangswerten x 0 ;
  2. Entwickeln lassen des Systems für eine große Anzahl N von Iterationen; und
  3. Kenntnis nehmend von den Endwerte x N , die erhalten werden.

Die Herausforderung

Eingänge

  • N : Anzahl der Iterationen.

  • r 1 , r 2 und s . Diese definieren die Menge R von Werten von r , nämlich R = { r 1 , r 1 + s , r 1 + 2 s , ..., r 2 }.

Verfahren

Die Menge X der Anfangswerte x 0 ist fest: X = {0,01, 0,02, ..., 0,99}. Optional können auch 0 und 1 in X enthalten sein .

Für jedes r in R und jedes x 0 in X iteriere die logistische Abbildung N- mal, um x N zu erzeugen . Notiere die erhaltenen Tupel ( r , x N ).

Ausgabe

Zeichnen Sie jedes Tupel ( r , x N ) als Punkt in der Ebene mit r als horizontale Achse und x N als vertikale Achse. Die Ausgabe sollte grafisch sein (keine ASCII-Grafik).

Zusätzliche Regeln

  • Die angegebene Prozedur definiert das erforderliche Ergebnis, wird jedoch nicht erzwungen. Es kann jede andere Prozedur verwendet werden, die dieselbe Menge von ( r , x N ) Tupeln enthält.
  • Die Eingabe ist wie gewohnt flexibel.
  • Gleitkommafehler werden nicht gegen den Antwortenden gehalten.
  • Eine Grafikausgabe ist in jedem der akzeptierten Formate erforderlich . Insbesondere kann die Ausgabe auf dem Bildschirm angezeigt werden, oder es kann eine Grafikdatei erzeugt werden, oder es kann ein Array von RGB-Werten ausgegeben werden. Wenn Sie eine Datei oder ein Array ausgeben, veröffentlichen Sie bitte ein Beispiel dafür, wie es bei der Anzeige aussieht.
  • Grafiken können Vektoren oder Raster sein. Für Rastergrafiken sollte die Bildgröße mindestens 400 × 400 Pixel betragen.
  • Jeder Punkt sollte als einzelnes Pixel oder als Markierung mit einer Größe in der Größenordnung von einem Pixel angezeigt werden (andernfalls wird das Diagramm schnell unübersichtlich).
  • Der Achsenbereich sollte für r (horizontale Achse) [0,4] und für x N (vertikale Achse) [0,1] betragen . oder es kann kleiner sein, solange es alle erhaltenen Punkte enthält.
  • Achsenskalen sind beliebig. Insbesondere muss der Maßstab nicht für beide Achsen gleich sein.
  • Rasterlinien, Achsenbeschriftungen, Farben und ähnliche Elemente sind zulässig, jedoch nicht erforderlich.
  • Kürzester Code in Bytes gewinnt.

Testfälle

Klicken Sie auf jedes Bild, um eine hochauflösende Version zu erhalten.

N = 1000; r1 = 2.4; r2 = 4; s = 0.001;

Bildbeschreibung hier eingeben

N = 2000; r1 = 3.4; r2 = 3.8; s = 0.0002;

Bildbeschreibung hier eingeben

N = 10000; r1 = 3.56; r2 = 3.59; s = 0.00002;

Bildbeschreibung hier eingeben

Wissen

Vielen Dank an @FryAmTheEggman und @AndrasDeak für ihre hilfreichen Kommentare, während die Herausforderung im Sandkasten lag.

Luis Mendo
quelle
Was keine Python-Lösung ?!
@Lembik Ich habe eine Referenzimplementierung in Python (und in Matlab), aber ich möchte nicht selbst antworten
Luis Mendo
Sie dürfen Ihre eigenen Fragen zu PPCG beantworten (vielleicht überraschend).
@Lembik Ich weiß, aber ich hätte lieber die Antworten anderer
Luis Mendo

Antworten:

13

MATL, 32 30 28 27 Bytes

4 Bytes gespart dank @Luis

3$:0:.01:1!i:"tU-y*]'.'3$XG

Das Eingabeformat ist r1, s, r2undN

Probieren Sie es bei MATL Online aus

Bildbeschreibung hier eingeben

Erläuterung

        % Implicitly grab the first three inputs
3$:     % Take these three inputs and create the array [r1, r1+s, ...]
0:.01:1 % [0, 0.01, 0.02, ... 1]
!       % Transpose this array
i       % Implicitly grab the input, N
:"      % For each iteration
  tU    % Duplicate and square the X matrix
  -     % Subtract from the X matrix (X - X^2) == x * (1 - x)
  y     % Make a copy of R array
  *     % Multiply the R array by the (X - X^2) matrix to yield the new X matrix
]       % End of for loop
'.'    % Push the string literal '.' to the stack (specifies that we want
        % dots as markers)
3$XG    % Call the 3-input version of PLOT to create the dot plot
Suever
quelle
8

Mathematica, 65 Bytes

Graphics@Table[Point@{r,Nest[r#(1-#)&,x,#]},{x,0,1,.01},{r,##2}]&

Reine Funktion mit den Argumenten N, r1, r2, s in dieser Reihenfolge. Nest[r#(1-#)&,x,N]iteriert die logistische Funktion r#(1-#)&insgesamt Nab x; hier ist das erste Argument für die Funktion ( #) das Nfragliche; Point@{r,...}produziert eine Point, Graphicsdie gerne plotten wird. Table[...,{x,0,1,.01},{r,##2}]erstellt eine ganze Reihe dieser Punkte, wobei der xWert von 0bis 1in Schritten von .01; Das ##2in {r,##2}bezeichnet alle ursprünglichen Funktionsargumente, beginnend mit dem zweiten, und {r,##2}erweitert sich, {r,r1,r2,s}wodurch der Bereich und das Inkrement für korrekt festgelegt werden r.

Beispielausgabe für den zweiten Testfall: die Eingabe

Graphics@Table[Point@{r,Nest[r#(1-#)&,x,#]},{x,0,1,.01},{r,##2}]&[2000,3.4,3.8,0.0002]

ergibt die Grafik unten.

Bildbeschreibung hier eingeben

Greg Martin
quelle
1
59 Bytes ListPlot @ Table [{r, Nest [r # (1 - #) &, x, #]}, {x, 0,1, .01}, {r,
##

Ich habe in der Aufforderung klargestellt, dass das angegebene Verfahren das erforderliche Ergebnis definieren soll, das Verfahren selbst jedoch nicht erzwungen wird. Sie können jedes andere Verfahren anwenden, das das gleiche Ergebnis liefert. Entschuldigung, wenn das zuerst nicht klar war
Luis Mendo

Kein Problem, wir haben mehrere gute Antworten!
Greg Martin

1
Wirst du diese -6 Bytes nicht benutzen? Denken Sie, dass mit dieser Lösung etwas nicht stimmt?
J42161217

Oh, ich dachte, Ihre Antwort wäre die Veröffentlichung (einer Version) des Codes aus Ihrem Kommentar ....
Greg Martin

5

Mathematica, 65 Bytes

Ich habe einige von Greg Martins Tricks benutzt und dies ist meine Version ohne Grafik

ListPlot@Table[{r,NestList[#(1-#)r&,.5,#][[-i]]},{i,99},{r,##2}]&

Eingang

[1000, 2,4, 4, 0,001]

Ausgabe

Bildbeschreibung hier eingeben

Eingang

[2000, 3.4, 3.8, 0.0002]

Ausgabe

Bildbeschreibung hier eingeben


1
Erste Antwort, die anfängliche Werte 0 oder 1 (und die x = 0-Linie, die sie erzeugen) zu vermeiden wählt :-)
Luis Mendo

Sie sollten eine Erläuterung der Funktionsweise Ihres Codes hinzufügen, da dieser nicht der angegebenen Prozedur entspricht. Das OP kann entscheiden, ob das genau aussehende Ergebnis die alternative Methode rechtfertigt.
Greg Martin

Die angegebene Prozedur wird nicht erzwungen. Alles, was auf andere Weise zum selben Ergebnis führt, ist erlaubt (ich werde das klarstellen). Unabhängig davon bin ich gespannt auf die Erklärung
Luis Mendo

Die Punkte, die Sie für jedes r zeichnen müssen, sind bereits in jedem "Nest" vorhanden. Dies ist der Originalcode und es war meine erste Vorgehensweise (vor einiger Zeit) beim Zeichnen dieses Diagramms.
J42161217

@ Luis Mendo Ich habe eine noch kürzere Version (die eine Aufzeichnung für Mathematica macht) .58 Bytes, aber Sie müssen nur 3 Eingänge eingeben [N, r1, r2]. Es braucht Zeit, aber es funktioniert.Plot [Tabelle [NestList [# ( 1 - #) r &, 5, #] [[- i]], {i, 99}], {r,
##
2

TI-Basic, 85 Bytes

Prompt P,Q,S,N
P→Xmin:Q→Xmax
0→Ymin:1→Ymax
For(W,.01,1,.01
For(R,P,Q,S
W→X
For(U,1,N
R*X*(1-X→X
End
Pt-On(R,X
End
End

Ein vollständiges TI-Basic-Programm, das Eingaben in der Reihenfolge vornimmt r1,r2,s,Nund die Ausgabe dann in Echtzeit auf dem Grafikbildschirm anzeigt. Beachten Sie, dass dies in der Regel unglaublich langsam ist .

Hier ist eine unvollständige Beispielausgabe, die nach ca. 2,5 Stunden für die Eingabe generiert wurde 3,4,0.01,100:

Bildbeschreibung hier eingeben

R. Kap
quelle
Du brauchst die *Schilder nicht.
Lirtosiast
1

ProcessingJS, 125 123 120 Bytes

Vielen Dank an Kritixi Lithos für die Einsparung von 3 Bytes.

var f(n,q,r,s){size(4e3,1e3);for(i=0;i<1;i+=.01)for(p=q;p<=r;p+=s){x=i;for(j=0;j<n;j++)x*=p-p*x;point(p*1e3,1e3-x*1e3)}}

Probieren Sie es online! Mit anrufenf(N, r_1, r_2, s);

Nur ASCII
quelle
Ich glaube , Sie ersetzen voidmit , varweil es die Verarbeitung JS
Kritixi Lithos
Und x*=p*(1-x)kann werdenx*=p-p*x
Kritixi Lithos
Wenn ich die for-Schleife neu var f(n,q,r,s){size(4e3,1e3);for(i=0;i<1;i+=.01)for(p=q;x=i,p<=r;point(p*1e3,1e3-x*1e3),p+=s)for(j=0;j<n;j++)x*=p-p*x;}
anordne
1

GEL , 158 Bytes

`(N,r,t,s)=(LinePlotWindow=[r,t,0,1];for i=r to t by s do(p=.;for w=0to 1by 0.01do(x=w;for a=0to N do(x=i*x*(1-x););p=[p;q=[i,x]];);LinePlotDrawPoints(p);););

Es ist vielleicht nicht das kürzeste, aber es zeichnet in Echtzeit, obwohl es mit großen Eingaben unglaublich langsam sein kann. Auf jeden Fall handelt es sich hierbei um eine anonyme Funktion, die Eingaben in das Format entgegennimmt (N,r1,r2,s)und das Diagramm in einem neuen Fenster ausgibt. Beachten Sie, dass dies muss mit der GNOME - Version von Genius ausgeführt werden.

Beispielausgabe

R. Kap
quelle
1

R 159 147 Bytes

pryr::f({plot(NA,xlim=c(a,b),ylim=0:1);q=function(r,n,x=1:99/100){for(i in 1:n)x=r*x*(1-x);x};for(i in seq(a,b,s))points(rep(i,99),q(i,n),cex=.1)})

Welches Produkt die Funktion

function (a, b, n, s) 
{
    plot(NA, xlim = c(a, b), ylim = 0:1)
    q = function(r, n, x = 1:99/100) {
        for (i in 1:n) x = r * x * (1 - x)
        x
    }
    for (i in seq(a, b, s)) points(rep(i, 99), q(i, n), cex = 0.1)
}

plot(NA,...)Erstellt eine leere Leinwand mit den richtigen Abmessungen. qist die Funktion, die die Iteration ausführt. Es nimmt einen Wert von ran und führt dann nIterationen für alle Startpunkte zwischen 0.01und aus 0.99. Es gibt dann den resultierenden Vektor zurück.

Die for-Schleife wendet die Funktion qauf die Sequenz azu bSchritt s. Anstatt die Werte zurückzugeben, werden sie als Punkte zum Plot hinzugefügt. Wenn der Anziehungspunkt ein Wert ist, überlappen sich alle Punkte und werden als ein Punkt angezeigt. cex=.1ist eine notwendige Ergänzung, um die Punkte so klein wie möglich zu machen.

Bildbeschreibung hier eingeben

JAD
quelle