La extraña atracción del mapa logístico

21

El propósito del desafío es trazar aproximadamente el atractor del mapa logístico en función de su parámetro r (también llamado diagrama de bifurcación ), o una subregión del mismo. La apariencia del gráfico se puede ver en la siguiente imagen de Wikipedia:

ingrese la descripción de la imagen aquí

Fondo

El mapa logístico es una función matemática que toma una entrada x k y lo asigna a una salida x k + 1 define como

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

donde r es el parámetro del mapa, se supone que se encuentra en el intervalo [0, 4].

Dada r en [0,4], y un valor inicial x 0 en el intervalo [0,1], es interesante para aplicar repetidamente la función para un número grande N de iteraciones, produciendo un valor final x N . Tenga en cuenta que x N necesariamente estará en [0,1] también.

Como ejemplo, considere r = 3.2, N = 1000. El valor inicial x 0 = 0.01 da x 1000 = 0.5130. Para x 0 = 0.02 el resultado es x 0 = 0.7995. Para cualquier otro valor inicial x 0, los valores finales x 1000 son extremadamente cercanos a 0.5130 o 0.7995. Esto se ve en el gráfico como la altura de las dos líneas en la posición horizontal r = 3.2.

Esto no significa que para r = 3.2 cada secuencia converja a uno de esos dos valores. De hecho, para los dos valores iniciales considerados anteriormente, las secuencias son (tenga en cuenta el comportamiento oscilante):

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

Lo que es cierto es que para N suficientemente grande , y para casi todos los valores iniciales x 0 , el término x N estará cerca de uno de los elementos del conjunto {0.5130, 0.7995}. Este conjunto se llama atractor para este r específico .

Para otros valores del parámetro r, el tamaño del conjunto de atractor, o sus elementos, cambiará. El gráfico traza los elementos en el atractor para cada r .

El atractor para un r específico se puede estimar por

  1. probar un amplio rango de valores iniciales x 0 ;
  2. dejando que el sistema evolucione para un gran número N de iteraciones; y
  3. tomando nota de los valores finales x N que se obtienen.

El reto

Entradas

  • N : número de iteraciones.

  • r 1 , r 2 y s . Estos definen el conjunto R de valores de r , es decir, R = { r 1 , r 1 + s , r 1 + 2 s , ..., r 2 }.

Procedimiento

El conjunto X de valores iniciales x 0 es fijo: X = {0.01, 0.02, ..., 0,99}. Opcionalmente, 0 y 1 también pueden incluirse en X .

Para cada r en R y cada x 0 en X , Iterar los logísticos mapa N veces para producir x N . Registre las tuplas obtenidas ( r , x N ).

Salida

Grafica cada tupla ( r , x N ) como un punto en el plano con r como eje horizontal y x N como eje vertical. La salida debe ser gráfica (no arte ASCII).

Reglas adicionales

  • El procedimiento indicado define el resultado requerido, pero no se aplica. Se puede utilizar cualquier otro procedimiento que genere el mismo conjunto de tuplas ( r , x N ).
  • La entrada es flexible como de costumbre.
  • Los errores de coma flotante no se mantendrán contra el respondedor.
  • Se requiere salida gráfica, en cualquiera de los formatos aceptados . En particular, la salida puede mostrarse en la pantalla, o puede producirse un archivo de gráficos, o puede enviarse una matriz de valores RGB. Si genera un archivo o una matriz, publique un ejemplo de cómo se ve cuando se muestra.
  • Los gráficos pueden ser vectoriales o de trama. Para gráficos ráster, el tamaño de la imagen debe ser de al menos 400 × 400 píxeles.
  • Cada punto debe mostrarse como un solo píxel, o como una marca con un tamaño del orden de un píxel (de lo contrario, el gráfico se abarrotará rápidamente).
  • El rango del eje debe ser [0,4] para r (eje horizontal) y [0,1] para x N (eje vertical); o puede ser más pequeño siempre que incluya todos los puntos obtenidos.
  • Las escalas del eje son arbitrarias. En particular, la escala no necesita ser la misma para ambos ejes.
  • Las líneas de cuadrícula, etiquetas de eje, colores y elementos similares son aceptables, pero no obligatorios.
  • El código más corto en bytes gana.

Casos de prueba

Haga clic en cada imagen para obtener una versión de alta resolución.

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

Reconocimiento

Gracias a @FryAmTheEggman y @AndrasDeak por sus útiles comentarios mientras el desafío estaba en el cajón de arena.

Luis Mendo
fuente
¿Qué no hay solución de Python?
@Lembik Tengo una implementación de referencia en Python (y en Matlab), pero no quiero responderme a mí mismo
Luis Mendo
Se le permite responder sus propias preguntas sobre PPCG (quizás sorprendentemente).
@Lembik Lo sé, pero prefiero tener las respuestas de otros
Luis Mendo

Respuestas:

13

MATL, 32 30 28 27 bytes

4 bytes guardados gracias a @Luis

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

El formato de entrada es r1, s, r2, yN

Pruébalo en MATL Online

ingrese la descripción de la imagen aquí

Explicación

        % 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
fuente
8

Mathematica, 65 bytes

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

Función pura tomando los argumentos N, r1, r2, s en ese orden. Nest[r#(1-#)&,x,N]itera la función logística r#(1-#)&un total de Nveces comenzando en x; aquí el primer argumento para la función ( #) es el Nen cuestión; Point@{r,...}produce un Pointque Graphicsserá feliz de trazar. Table[...,{x,0,1,.01},{r,##2}]crea un montón de estos puntos, con el xvalor que va de 0a 1en incrementos de .01; el ##2in {r,##2}denota todos los argumentos de la función original comenzando por el segundo, y se {r,##2}expande a lo {r,r1,r2,s}que establece correctamente el rango y el incremento para r.

Salida de muestra, en el segundo caso de prueba: la entrada

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

produce los gráficos a continuación.

ingrese la descripción de la imagen aquí

Greg Martin
fuente
1
59 bytes ListPlot @ Table [{r, Nest [r # (1 - #) &, x, #]}, {x, 0,1, .01}, {r, ## 2}] &
J42161217
He aclarado en el desafío que el procedimiento indicado está destinado a definir el resultado requerido, pero el procedimiento en sí no se aplica. Puede usar cualquier otro procedimiento que dé el mismo resultado. Lo siento si eso no era claro en un primer momento
Luis Mendo
¡No hay problema, tenemos varias buenas respuestas!
Greg Martin
1
¿No vas a usar esos -6 bytes? ¿Crees que somathing está mal con esta solución?
J42161217
Oh, pensé que tu respuesta era la publicación de (una versión de) el código de tu comentario ...
Greg Martin
5

Mathematica, 65 bytes

Usé algunos de los trucos de Greg Martin y esta es mi versión sin usar gráficos

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

entrada

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

salida

ingrese la descripción de la imagen aquí

entrada

[2000, 3.4, 3.8, 0.0002]

salida

ingrese la descripción de la imagen aquí

J42161217
fuente
1
Primera respuesta que elige evitar los valores iniciales 0 o 1 (y la línea x = 0 que generan) :-)
Luis Mendo
Debe agregar una explicación de lo que hace su código, ya que en realidad no sigue el procedimiento especificado. El OP puede decidir si el resultado exacto justifica el método alternativo.
Greg Martin
El procedimiento especificado no se aplica. Todo lo que dé el mismo resultado, por cualquier otro medio, está permitido (lo aclararé). Independientemente de esto, tengo curiosidad por ver la explicación
Luis Mendo
Los puntos que necesita trazar para cada r, ya existen en cada "Nido". Este es el código original y fue mi primer enfoque (hace un tiempo) al trazar este diagrama.
J42161217
@Luis Mendo tengo una versión aún más corta (que hace un registro para Mathica) .58 bytes pero debe ingresar solo 3 entradas [N, r1, r2]. Toma tiempo pero funciona. Parcela [Tabla [NestList [# ( 1 - #) r &,. 5, #] [[- i]], {i, 99}], {r, ## 2}] y
J42161217
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

Un programa TI-Basic completo que toma la entrada en el orden r1,r2,s,Ny luego muestra la salida en tiempo real en la pantalla gráfica. Tenga en cuenta que esto tiende a ser increíblemente lento .

Aquí hay una salida de muestra incompleta generada después de aproximadamente 2.5 horas para la entrada 3,4,0.01,100:

ingrese la descripción de la imagen aquí

R. Kap
fuente
No necesitas las *señales.
lirtosiast
1

Procesamiento JS, 125 123 120 bytes

Gracias a Kritixi Lithos por guardar 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)}}

Pruébalo en línea! Llamar usandof(N, r_1, r_2, s);

Solo ASCII
fuente
Creo que se puede sustituir voidcon varporque de Procesamiento de JS
Kritixi Lithos
Y x*=p*(1-x)puede llegar a serx*=p-p*x
Kritixi Lithos
Al reorganizar el bucle for, obtengo 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 bytes
Kritixi Lithos
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);););

Puede que no sea el más corto, pero se dibuja en tiempo real, aunque puede ser increíblemente lento con grandes entradas. De todos modos, esta es una función anónima que toma la entrada en el formato (N,r1,r2,s)y genera la trama en una nueva ventana. Tenga en cuenta que esto debe ejecutarse con la versión GNOME de Genius.

Salida de muestra

R. Kap
fuente
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)})

Que produce la función

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,...)crea un lienzo vacío que tiene las dimensiones correctas. qes la función que hace la iteración. Toma un valor de r, y luego realiza niteraciones para todos los puntos de partida entre 0.01y 0.99. Luego devuelve el vector resultante.

El bucle de aplica la función qa la secuencia aa bcon el paso s. En lugar de devolver los valores, los agrega como puntos a la gráfica. Si el punto de atracción es un valor, todos los puntos se superpondrían y se mostrarían como un solo punto. cex=.1es una adición necesaria para hacer que los puntos sean lo más pequeños posible.

ingrese la descripción de la imagen aquí

JAD
fuente