Avançado · Padrões de Turing

Lição 9: Malhas e difusão

Construa em Python o padrão “Padrões de Turing” e aprenda pelo caminho:

  • arrays 2D como uma malha de células
  • np.roll para os vizinhos, com bordas que dão a volta
  • o laplaciano: uma célula comparada com os seus vizinhos
  • atualizar uma malha inteira numa só linha
  • mostrar um array com plt.imshow

Veja-o primeiro

É reproduzido a partir do YouTube depois de um clique.

turing-patterns.py
"""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

Não tem Python neste computador? O notebook executa o mesmo script, os exercícios e as respostas no navegador, no Google Colab. O notebook está em inglês.

Linha a linha

  1. A, B = np.ones((size, size)), np.zeros((size, size))

    Duas malhas de 128 × 128: o alimento A em todas as células, ainda nenhum B.

  2. B[y : y + 8, x : x + 8] = 1.0

    Uma gota de B: um quadrado de 8 × 8 da malha, definido de uma vez por fatiamento.

  3. def laplacian(Z):

    Quanto uma célula difere dos seus vizinhos: positivo onde os vizinhos têm mais, e então a difusão enche-a.

  4. sides = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)

    np.roll desloca a malha inteira uma célula para cima, para baixo, para a esquerda ou para a direita; as bordas dão a volta, por isso a placa não tem margem.

  5. reaction = A * B * B

    A reação, um A e dois B dão três B, para todas as células de uma vez.

  6. A += DA * laplacian(A) - reaction + f * (1 - A)

    A regra de Gray–Scott para A: espalha-se, é consumido e é reposto em direção a 1 à taxa f.

  7. plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)

    A malha de B como imagem, um pixel por célula.

Experimente

  1. Experimente f, k = 0.034, 0.063.

    Pista

    Uma linha perto do início.

    Resposta

    Manchas: zonas redondas de B, a distâncias iguais, em vez das linhas sinuosas do coral.

  2. Faça B espalhar-se tão depressa como A: DB = 1.0. O que acontece?

    Pista

    DA, DB = 1.0, 1.0.

    Resposta

    Nenhum padrão: as gotas desvanecem-se até desaparecer. Se A não se espalhar mais depressa do que B, nada mantém as zonas separadas. É esta a ideia de Turing.

  3. Use uma só gota no meio em vez de seis.

    Pista

    Substitua o loop por B[60:68, 60:68] = 1.0.

    Resposta

    O coral cresce para fora a partir da única gota com uma simetria de ordem quatro que copia a gota quadrada: uma só semente dá um padrão ordenado, seis gotas ao acaso um padrão que parece natural.

Quiz

1. O que faz np.roll(Z, 1, 0)?
2. O que mede o laplaciano de uma célula?
3. Por que razão não há nenhum loop pelas células?
4. O que mostrou Turing em 1952?
5. O que muda do coral para as manchas?

Flashcards

Leia a frente, tente recordar o verso e só depois abra o cartão.

  • np.roll(Z, shift, axis)

    Desloca um array ao longo de um eixo; o que sai por uma ponta volta pela outra.

  • Laplaciano

    Os vizinhos de uma célula menos a própria célula: para onde a difusão a vai levar.

  • Gray–Scott

    A é adicionado à taxa f, B é removido à taxa f + k, e A + 2B → 3B.

  • Instabilidade de Turing

    A difusão transforma uma mistura uniforme num padrão quando uma substância se espalha mais depressa.

  • plt.imshow(grid)

    Mostra um array 2D como imagem, um pixel por célula.

Estes flashcards numa página à parte →

Construiu os nove. Se o curso ajudou, o canal gostaria muito de saber. Apoiar o canal →