Lección 9: Cuadrículas y difusión
Construye en Python el patrón «Patrones de Turing» y aprende por el camino:
- arrays 2D como una cuadrícula de celdas
- np.roll para los vecinos, con bordes que dan la vuelta
- el laplaciano: una celda frente a sus vecinas
- actualizar toda una cuadrícula en una línea
- mostrar un array con plt.imshow
Míralo primero
Se reproduce desde YouTube tras hacer clic.
"""Turing patterns: the Gray-Scott reaction-diffusion rule on a 128 x 128 grid.
Run: python turing-patterns.py (needs: pip install numpy matplotlib; takes a few seconds)
"""
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("dark_background")
size, steps = 128, 6000
f, k = 0.0545, 0.062 # feed and kill rates: coral
DA, DB = 1.0, 0.5 # A spreads twice as fast as B
A, B = np.ones((size, size)), np.zeros((size, size))
rng = np.random.default_rng()
for y, x in rng.integers(10, size - 18, (6, 2)):
B[y : y + 8, x : x + 8] = 1.0 # six drops of B
def laplacian(Z):
"""Each cell against its neighbours: 0.2 for the four sides, 0.05 for the corners (Karl Sims)"""
sides = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)
corners = (np.roll(np.roll(Z, 1, 0), 1, 1) + np.roll(np.roll(Z, 1, 0), -1, 1)
+ np.roll(np.roll(Z, -1, 0), 1, 1) + np.roll(np.roll(Z, -1, 0), -1, 1))
return 0.2 * sides + 0.05 * corners - Z
for _ in range(steps):
reaction = A * B * B # one A and two B make three B
A += DA * laplacian(A) - reaction + f * (1 - A)
B += DB * laplacian(B) + reaction - (f + k) * B
plt.figure(figsize=(6, 6))
plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)
plt.axis("off")
plt.show()
# Try: f, k = 0.039, 0.058 (a cell net) or 0.034, 0.063 (spots) -> the same rule, another pattern
¿No tienes Python en este equipo? El cuaderno ejecuta el mismo script, los ejercicios y las respuestas en tu navegador, en Google Colab. El cuaderno está en inglés.
Línea a línea
A, B = np.ones((size, size)), np.zeros((size, size))Dos cuadrículas de 128 × 128: el alimento A en todas partes, todavía nada de B.
B[y : y + 8, x : x + 8] = 1.0Una gota de B: un cuadrado de 8 × 8 de la cuadrícula, asignado de una vez mediante slicing.
def laplacian(Z):Cuánto se diferencia una celda de sus vecinas: positivo donde las vecinas tienen más, así que la difusión la rellena.
sides = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)np.roll desplaza toda la cuadrícula una celda hacia arriba, abajo, la izquierda o la derecha; los bordes dan la vuelta, así que la placa no tiene borde.
reaction = A * B * BLa reacción, una A y dos B dan tres B, para todas las celdas a la vez.
A += DA * laplacian(A) - reaction + f * (1 - A)La regla de Gray-Scott para A: se extiende, se consume y se repone hacia 1 al ritmo f.
plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)La cuadrícula de B como imagen, un píxel por celda.
Pruébalo tú
Prueba f, k = 0.034, 0.063.
Pista
Una línea cerca del principio.
Respuesta
Manchas: zonas redondas de B, separadas por igual, en lugar de las líneas sinuosas del coral.
Haz que B se extienda tan deprisa como A: DB = 1.0. ¿Qué pasa?
Pista
DA, DB = 1.0, 1.0.
Respuesta
No aparece ningún patrón: las gotas se desvanecen hasta desaparecer. Si A no se extiende más deprisa que B, nada mantiene separadas las manchas. Esa es la idea de Turing.
Usa una sola gota en el centro en lugar de seis.
Pista
Sustituye el bucle por B[60:68, 60:68] = 1.0.
Respuesta
El coral crece hacia fuera desde la única gota con una simetría cuádruple que copia la gota cuadrada: una sola semilla da un patrón ordenado; seis gotas al azar, uno de aspecto natural.
Cuestionario
Tarjetas de repaso
Lee el anverso, di el reverso para ti y luego abre la tarjeta.
np.roll(Z, shift, axis)
Desplaza un array a lo largo de un eje; lo que sale por un extremo vuelve por el otro.
Laplaciano
Las vecinas de una celda menos la propia celda: hacia dónde la moverá la difusión.
Gray-Scott
A se añade a ritmo f, B se elimina a ritmo f + k, y A + 2B → 3B.
Inestabilidad de Turing
La difusión rompe una mezcla uniforme en un patrón cuando una sustancia se extiende más deprisa.
plt.imshow(grid)
Muestra un array 2D como una imagen, un píxel por celda.
Has construido los nueve. Si el curso te ha servido, al canal le encantaría saberlo. Apoya el canal →