Dziwna atrakcja mapy logistycznej

21

Celem tej próby jest w przybliżeniu wykreślić attractor na mapie logistycznego w funkcji jego parametr r (zwany także schemat rozwidlenia ), lub w subregionie niego. Wygląd wykresu można zobaczyć na następującym obrazku z Wikipedii:

wprowadź opis zdjęcia tutaj

tło

Odwzorowanie logistyczne jest matematyczną funkcją, która zajmuje wejście x k i mapuje je do wyjścia x k + 1 zdefiniowanego jako

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

gdzie r jest parametrem mapy, przy założeniu, że leży w przedziale [0, 4].

Biorąc pod uwagę, R w [0,4], a wartość początkowa x 0 w przedziale [0,1] Interesujące jest wielokrotnie stosuje się funkcję do dużej liczby N iteracji, tworząc końcową wartość x N . Zauważ, że x N musi koniecznie znajdować się w [0,1].

Jako przykład rozważmy r = 3,2, N = 1000. Wartość początkowa x 0 = 0,01 daje x 1000 = 0,5130. Dla x 0 = 0,02 wynikiem jest x 0 = 0,7995. Dla każdej innej wartości początkowej x 0 końcowe wartości x 1000 są bardzo zbliżone do 0,5130 lub 0,7995. Jest to widoczne na wykresie jako wysokość dwóch linii w pozycji poziomej r = 3,2.

Ten sposób nie oznacza to, że dla R = 3,2 Każda sekwencja jest zbieżny do jednej z tych dwóch wartości. W rzeczywistości dla dwóch rozważanych powyżej wartości początkowych sekwencje są (zwróć uwagę na zachowanie oscylacyjne):

             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 , ...

Co jest prawdą, że dla dostatecznie dużych N , a dla prawie wszystkich wartości początkowych x 0 , termin x N będzie zbliżony do jednego z elementów zbioru {0.5130, 0,7995}. Ten zestaw nazywa się atraktorem dla tego konkretnego r .

Dla innych wartości parametru r zmieni się rozmiar zestawu atraktora lub jego elementów. Wykres przedstawia elementy w atraktorze dla każdego r .

Atraktor dla określonego r można oszacować za pomocą

  1. testowanie szerokiego zakresu wartości początkowych x 0 ;
  2. pozwalając, aby system ewoluował dla dużej liczby N iteracji; i
  3. zwracając uwagę na końcowe wartości x N , które są uzyskiwane.

Wyzwanie

Wejścia

  • N : liczba iteracji.

  • r 1 , r 2 i s . Definiują one zbiór R wartości r , a mianowicie R = { r 1 , r 1 + s , r 1 + 2 s , ..., r 2 }.

Procedura

Zbiór X wartości początkowych x 0 jest stały: X = {0,01, 0,02, ..., 0,99}. Ewentualnie, od 0 do 1 mogą być także zawarte w X .

Dla każdego badania w R i każdy x 0 w X , iteracyjne logistyczne mapę N razy do produkcji x N . Zapisz uzyskane krotki ( r , x N ).

Wydajność

Narysuj każdą krotkę ( r , x N ) jako punkt w płaszczyźnie z r jako osią poziomą i x N jako osią pionową. Dane wyjściowe powinny być grafiki (nie sztuki ASCII).

Dodatkowe zasady

  • Wskazana procedura określa wymagany wynik, ale nie jest egzekwowana. Można użyć dowolnej innej procedury, która ogłasza ten sam zestaw krotek ( r , x N ).
  • Dane wejściowe są jak zwykle elastyczne.
  • Błędy zmiennoprzecinkowe nie będą blokowane przez odpowiadającego.
  • Wymagany jest wydruk graficzny w dowolnym akceptowanym formacie . W szczególności dane wyjściowe mogą być wyświetlane na ekranie lub może zostać utworzony plik graficzny lub tablica wartości RGB. Jeśli wyprowadzasz plik lub tablicę, zamieść przykład tego, jak to wygląda po wyświetleniu.
  • Grafika może być wektorowa lub rastrowa. W przypadku grafiki rastrowej rozmiar obrazu powinien wynosić co najmniej 400 × 400 pikseli.
  • Każdy punkt powinien być pokazany jako pojedynczy piksel lub jako znak wielkości rzędu jednego piksela (w przeciwnym razie wykres szybko się zaśmieci).
  • Zakres osi powinien wynosić [0,4] dla r (oś pozioma) i [0,1] dla x N (oś pionowa); lub może być mniejszy, o ile zawiera wszystkie uzyskane punkty.
  • Skale osi są dowolne. W szczególności skala nie musi być taka sama dla obu osi.
  • Linie siatki, etykiety osi, kolory i podobne elementy są dopuszczalne, ale nie wymagane.
  • Najkrótszy kod w bajtach wygrywa.

Przypadki testowe

Kliknij każdy obraz, aby wyświetlić wersję w wysokiej rozdzielczości.

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

wprowadź opis zdjęcia tutaj

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

wprowadź opis zdjęcia tutaj

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

wprowadź opis zdjęcia tutaj

Potwierdzenie

Dzięki @FryAmTheEggman i @AndrasDeak za ich pomocne komentarze, gdy wyzwanie było w piaskownicy.

Luis Mendo
źródło
Co nie ma rozwiązania python ?!
@Lembik Mam implementację referencyjną w Pythonie (i Matlabie), ale nie chcę sobie odpowiadać
Luis Mendo
Możesz odpowiedzieć na własne pytania dotyczące PPCG (być może zaskakujące).
@Lembik Wiem, ale wolę mieć odpowiedzi innych
Luis Mendo

Odpowiedzi:

13

MATL, 32 30 28 27 bajtów

4 bajty zapisane dzięki @Luis

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

Format wejściowy jest r1, s, r2, iN

Wypróbuj w MATL Online

wprowadź opis zdjęcia tutaj

Wyjaśnienie

        % 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
źródło
8

Mathematica, 65 bajtów

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

Czysta funkcja przyjmująca argumenty N, r1, r2, s w tej kolejności. Nest[r#(1-#)&,x,N]iteruje funkcję logistyczną r#(1-#)&łącznie Nrazy od x; tutaj pierwszym argumentem funkcji ( #) jest Npytanie; Point@{r,...}produkuje taki Point, Graphicsktóry z przyjemnością spiskuje. Table[...,{x,0,1,.01},{r,##2}]tworzy całą masę tych punktów, których xwartość zmienia się od 0do 1w krokach co .01; ##2w {r,##2}oznacza wszystkich pierwotnych argumentów funkcji, począwszy od drugiego, a więc {r,##2}powiększa się do {r,r1,r2,s}których poprawnie ustawia zakres i przyrost dla r.

Przykładowe dane wyjściowe, w drugim przypadku testowym: dane wejściowe

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

daje grafikę poniżej.

wprowadź opis zdjęcia tutaj

Greg Martin
źródło
1
59 bajtów ListPlot @ Table [{r, Nest [r # (1 - #) &, x, #]}, {x, 0,1, .01}, {r, ## 2}] i
J42161217
Wyjaśniłem w wyzwaniu, że wskazana procedura ma na celu zdefiniowanie wymaganego wyniku, ale sama procedura nie jest egzekwowana. Możesz użyć dowolnej innej procedury, która daje ten sam wynik. Przepraszam, jeśli na początku nie było to jasne
Luis Mendo
Nie ma problemu, mamy kilka dobrych odpowiedzi!
Greg Martin
1
Nie zamierzasz użyć tych -6 bajtów. Czy uważasz, że to rozwiązanie jest złe w tym rozwiązaniu?
J42161217
Och, myślałem, że twoją odpowiedzią było opublikowanie (wersji) kodu z twojego komentarza ....
Greg Martin
5

Mathematica, 65 bajtów

Użyłem niektórych sztuczek Grega Martina i to jest moja wersja bez grafiki

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

wkład

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

wydajność

wprowadź opis zdjęcia tutaj

wkład

[2000, 3,4, 3,8, 0,0002]

wydajność

wprowadź opis zdjęcia tutaj

J42161217
źródło
1
Pierwsza odpowiedź, która decyduje się na uniknięcie początkowych wartości 0 lub 1 (i generowanej linii x = 0) :-)
Luis Mendo
Powinieneś dodać wyjaśnienie tego, co robi twój kod, ponieważ tak naprawdę nie postępuje on zgodnie z określoną procedurą. PO może zdecydować, czy dokładnie wyglądający wynik uzasadnia alternatywną metodę.
Greg Martin
Podana procedura nie jest egzekwowana. Wszystko, co daje ten sam wynik, w jakikolwiek inny sposób, jest dozwolone (wyjaśnię to). Niezależnie od tego jestem ciekawy wyjaśnienia
Luis Mendo
Punkty, które musisz wykreślić dla każdego r, istnieją już w każdym „gnieździe”. to jest oryginalny kod i było to moje pierwsze podejście (jakiś czas temu) do wykreślenia tego diagramu.
J42161217
@Luis Mendo Mam jeszcze krótszą wersję (która stanowi rekord dla matematyki) .58 bajtów, ale musisz wprowadzić tylko 3 wejścia [N, r1, r2]. To zajmuje czas, ale działa. Działka [Tabela [NestList [# ( 1 - #) r &. 5, #] [[- i]], {i, 99}], {r, ## 2}] &
J42161217
2

TI-Basic, 85 bajtów

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

Kompletny program TI-Basic, który pobiera dane wejściowe w kolejności, r1,r2,s,Na następnie wyświetla dane wyjściowe w czasie rzeczywistym na ekranie wykresu. Zauważ, że jest to niezwykle powolne .

Oto niepełny przykładowy wynik wygenerowany po około 2,5 godzinach dla danych wejściowych 3,4,0.01,100:

wprowadź opis zdjęcia tutaj

R. Kap
źródło
Nie potrzebujesz *znaków.
lirtosiast
1

Przetwarzanie JS, 125 123 120 bajtów

Dzięki Kritixi Lithos za oszczędność 3 bajtów.

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)}}

Wypróbuj online! Zadzwoń za pomocąf(N, r_1, r_2, s);

Tylko ASCII
źródło
Myślę, że można zastąpić voidz varponieważ jest to tworzenie JS
Kritixi Lithos
I x*=p*(1-x)może zostaćx*=p-p*x
Kritixi Lithos
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;}
Zmieniając
1

ŻEL , 158 bajtów

`(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);););

Może nie jest najkrótszy, ale rysuje w czasie rzeczywistym, chociaż może być niezwykle powolny przy dużych nakładach. W każdym razie jest to anonimowa funkcja, która pobiera dane wejściowe w formacie (N,r1,r2,s)i wyświetla wykres w nowym oknie. Pamiętaj, że należy to uruchomić z wersją Genius GNOME.

Próbka wyjściowa

R. Kap
źródło
1

R, 159 147 bajtów

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)})

Który produkuje funkcję

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,...)tworzy puste płótno o odpowiednich wymiarach. qjest funkcją wykonującą iterację. Przyjmuje wartość r, a następnie wykonuje niteracje dla wszystkich punktów początkowych między0.01 i 0.99. Następnie zwraca wynikowy wektor.

Pętli for stosuje się funkcję qdo sekwencji ado bkroku s. Zamiast zwracać wartości, dodaje je jako punkty do wykresu. Jeśli punkt przyciągania ma jedną wartość, wszystkie punkty będą się nakładać i pokazywać jako jeden punkt. cex=.1jest niezbędnym dodatkiem, aby punkty były jak najmniejsze.

wprowadź opis zdjęcia tutaj

JAD
źródło