L'étrange attraction de la carte logistique

21

Le défi a pour objectif de tracer approximativement l' attracteur de la carte logistique en fonction de son paramètre r (également appelé diagramme de bifurcation ), ou d'une sous-région de celui-ci. L'aspect du graphique peut être vu dans l'image suivante de Wikipedia:

entrez la description de l'image ici

Contexte

La carte logistique est une fonction mathématique qui prend une entrée x k et la met en correspondance avec une sortie x k + 1 définie comme

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

r est le paramètre de la carte, supposé se situer dans l'intervalle [0, 4].

Compte tenu de r dans [0,4], et une valeur initiale x 0 dans l'intervalle [0,1], il est intéressant d' appliquer de façon répétée la fonction d'un grand nombre N d'itérations, en produisant une valeur finale x N . Notez que x N se situera nécessairement aussi dans [0,1].

À titre d'exemple, considérons r = 3,2, N = 1000. La valeur initiale x 0 = 0,01 donne x 1000 = 0,5130. Pour x 0 = 0,02, le résultat est x 0 = 0,7995. Pour toute autre valeur initiale x 0, les valeurs finales x 1000 sont extrêmement proches de 0,5130 ou 0,7995. Ceci est vu dans le graphique comme la hauteur des deux lignes à la position horizontale r = 3,2.

Cela ne signifie pas que pour r = 3,2, chaque séquence converge vers l'une de ces deux valeurs. En fait, pour les deux valeurs initiales considérées ci-dessus, les séquences sont (notez le comportement oscillant):

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

Ce qui est vrai, c'est que pour N suffisamment grand , et pour presque toutes les valeurs initiales x 0 , le terme x N sera proche de l'un des éléments de l'ensemble {0.5130, 0.7995}. Cet ensemble est appelé l' attracteur pour ce r spécifique .

Pour les autres valeurs du paramètre r, la taille de l'ensemble d'attracteurs ou de ses éléments changera. Le graphique trace les éléments de l'attracteur pour chaque r .

L'attracteur pour un r spécifique peut être estimé par

  1. tester une large gamme de valeurs initiales x 0 ;
  2. laisser le système évoluer pour un grand nombre N d'itérations; et
  3. prendre note des valeurs finales x N obtenues.

Le défi

Contributions

  • N : nombre d'itérations.

  • r 1 , r 2 et s . Celles-ci définissent l'ensemble R des valeurs de r , à savoir R = { r 1 , r 1 + s , r 1 + 2 s , ..., r 2 }.

Procédure

L'ensemble X des valeurs initiales x 0 est fixe: X = {0,01, 0,02, ..., 0,99}. En option, 0 et 1 peuvent également être inclus dans X .

Pour chaque r dans R et chaque x 0 dans X , Itérer la carte logistique N fois pour produire x N . Enregistrez les tuples obtenus ( r , x N ).

Production

Tracez chaque tuple ( r , x N ) comme un point dans le plan avec r comme axe horizontal et x N comme axe vertical. La sortie doit être graphique (pas art ASCII).

Règles supplémentaires

  • La procédure indiquée définit le résultat requis, mais n'est pas appliquée. Toute autre procédure qui procède au même ensemble de ( r , x N ) tuples peut être utilisée.
  • L'entrée est flexible comme d'habitude.
  • Les erreurs en virgule flottante ne seront pas retenues contre le répondeur.
  • Une sortie graphique est requise, dans tous les formats acceptés . En particulier, la sortie peut être affichée à l'écran, ou un fichier graphique peut être produit, ou un tableau de valeurs RVB peut être sorti. Si vous affichez un fichier ou un tableau, veuillez publier un exemple de ce à quoi il ressemble lorsqu'il est affiché.
  • Les graphiques peuvent être vectoriels ou raster. Pour les graphiques raster, la taille de l'image doit être d'au moins 400 × 400 pixels.
  • Chaque point doit être affiché comme un seul pixel, ou comme une marque avec une taille de l'ordre d'un pixel (sinon le graphique s'encombre rapidement).
  • La plage des axes doit être [0,4] pour r (axe horizontal) et [0,1] pour x N (axe vertical); ou il peut être plus petit tant qu'il comprend tous les points obtenus.
  • Les échelles des axes sont arbitraires. En particulier, l'échelle n'a pas besoin d'être la même pour les deux axes.
  • Les lignes de quadrillage, les étiquettes d'axe, les couleurs et les éléments similaires sont acceptables, mais pas obligatoires.
  • Le code le plus court en octets gagne.

Cas de test

Cliquez sur chaque image pour une version haute résolution.

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

entrez la description de l'image ici

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

entrez la description de l'image ici

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

entrez la description de l'image ici

Reconnaissance

Merci à @FryAmTheEggman et @AndrasDeak pour leurs commentaires utiles pendant que le défi était dans le bac à sable.

Luis Mendo
la source
Quelle solution sans python?!
@Lembik J'ai une implémentation de référence en Python (et en Matlab), mais je ne veux pas me répondre
Luis Mendo
Vous êtes autorisé à répondre à vos propres questions sur PPCG (peut-être de manière surprenante).
@Lembik Je sais, mais je préfère avoir les réponses des autres
Luis Mendo

Réponses:

13

MATL, 32 30 28 27 octets

4 octets économisés grâce à @Luis

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

Le format d'entrée est r1, s, r2etN

Essayez-le sur MATL Online

entrez la description de l'image ici

Explication

        % 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
la source
8

Mathematica, 65 octets

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

Fonction pure prenant les arguments N, r1, r2, s dans cet ordre. Nest[r#(1-#)&,x,N]itère la fonction logistique r#(1-#)&un total de Nfois à partir de x; ici, le premier argument de la fonction ( #) est celui Nen question; Point@{r,...}produit un Pointqui Graphicssera heureux de tracer. Table[...,{x,0,1,.01},{r,##2}]crée tout un tas de ces points, la xvaleur allant de 0à 1par incréments de .01; le ##2in {r,##2}indique tous les arguments de la fonction d'origine à partir du second, et se {r,##2}développe donc pour définir {r,r1,r2,s}correctement la plage et l'incrément pour r.

Exemple de sortie, sur le deuxième cas de test: l'entrée

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

donne les graphiques ci-dessous.

entrez la description de l'image ici

Greg Martin
la source
1
59 octets ListPlot @ Table [{r, Nest [r # (1 - #) &, x, #]}, {x, 0,1, .01}, {r, ## 2}] &
J42161217
J'ai précisé dans le défi que la procédure indiquée est destinée à définir le résultat requis, mais la procédure elle-même n'est pas appliquée. Vous pouvez utiliser toute autre procédure qui donne le même résultat. Désolé si ce n'était pas clair au début
Luis Mendo
Pas de problème, nous avons plusieurs bonnes réponses!
Greg Martin
1
Tu ne vas pas utiliser ces -6 octets. Pensez-vous que somathing est mal avec cette solution?
J42161217
Oh, je pensais que votre réponse était l'affichage (d'une version de) du code de votre commentaire ....
Greg Martin
5

Mathematica, 65 octets

J'ai utilisé quelques astuces de Greg Martin et ceci est ma version sans utiliser Graphics

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

contribution

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

production

entrez la description de l'image ici

contribution

[2000, 3.4, 3.8, 0.0002]

production

entrez la description de l'image ici

J42161217
la source
1
Première réponse qui choisit d'éviter les valeurs initiales 0 ou 1 (et la ligne x = 0 qu'elles génèrent) :-)
Luis Mendo
Vous devez ajouter une explication de ce que fait votre code, car il ne suit pas réellement la procédure spécifiée. L'OP peut décider si le résultat précis justifie la méthode alternative.
Greg Martin
La procédure spécifiée n'est pas appliquée. Tout ce qui donne le même résultat, par tout autre moyen, est autorisé (je vais clarifier cela). Quoi qu'il en soit, je suis curieux de voir l'explication
Luis Mendo
Les points que vous devez tracer pour chaque r existent déjà dans chaque "Nest". c'est du code original et c'était ma première approche (il y a quelque temps) pour tracer ce diagramme.
J42161217
@Luis Mendo J'ai une version encore plus courte (ce qui fait un record pour Mathemica) .58 octets mais vous ne devez entrer que 3 entrées [N, r1, r2]. Cela prend du temps mais cela fonctionne.Plot [Table [NestList [# ( 1 - #) r &, 5, #] [[- i]], {i, 99}], {r, ## 2}] &
J42161217
2

TI-Basic, 85 octets

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

Un programme TI-Basic complet qui prend les entrées dans l'ordre r1,r2,s,Net affiche ensuite les sorties en temps réel sur l'écran graphique. Notez que cela a tendance à être incroyablement lent .

Voici un exemple de sortie incomplète générée après environ 2,5 heures pour l'entrée 3,4,0.01,100:

entrez la description de l'image ici

R. Kap
la source
Vous n'avez pas besoin des *signes.
lirtosiast
1

Processing.js, 125 123 120 octets

Merci à Kritixi Lithos pour avoir économisé 3 octets.

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

Essayez-le en ligne! Appeler en utilisantf(N, r_1, r_2, s);

ASCII uniquement
la source
Je pense que vous pouvez remplacer voidpar varparce que c'est Processing JS
Kritixi Lithos
Et x*=p*(1-x)peut devenirx*=p-p*x
Kritixi Lithos
En réorganisant la boucle for, j'arrive 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;}à 119 octets
Kritixi Lithos
1

GEL , 158 octets

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

Ce n'est peut-être pas le plus court, mais il dessine en temps réel, bien qu'il puisse être incroyablement lent avec des entrées énormes. Quoi qu'il en soit, il s'agit d'une fonction anonyme qui prend une entrée au format (N,r1,r2,s)et sort le tracé dans une nouvelle fenêtre. Notez que cela doit être exécuté avec la version GNOME de Genius.

Exemple de sortie

R. Kap
la source
1

R, 159 147 octets

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

Qui produit la fonction

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,...)crée un canevas vide qui a les bonnes dimensions. qest la fonction qui fait l'itération. Il prend une valeur de r, puis effectue des nitérations pour tous les points de départ entre 0.01et 0.99. Il retourne ensuite le vecteur résultant.

La boucle for applique la fonction qde la séquence aà l' bétape s. Au lieu de renvoyer les valeurs, il les ajoute en tant que points au tracé. Si le point d'attraction est une valeur, tous les points se chevauchent et apparaissent comme un seul point. cex=.1est un ajout nécessaire pour rendre les points aussi petits que possible.

entrez la description de l'image ici

JAD
la source