9강: 격자와 확산
Python으로 “튜링 패턴” 패턴을 만들면서 배워요:
- 칸으로 이루어진 격자로서의 2차원 배열
- 가장자리가 한 바퀴 이어지는 np.roll로 이웃 찾기
- 라플라시안: 칸 하나와 그 이웃의 비교
- 한 줄로 격자 전체 갱신하기
- plt.imshow로 배열 보여 주기
먼저 보기
클릭하면 YouTube에서 재생돼요.
"""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
이 컴퓨터에 Python이 없나요? 노트북으로 같은 스크립트와 연습 문제, 정답을 브라우저의 Google Colab에서 실행할 수 있어요. 노트북은 영어로 되어 있어요.
한 줄씩
A, B = np.ones((size, size)), np.zeros((size, size))128 × 128 격자 두 개: 먹이 A는 모든 곳에, B는 아직 없어요.
B[y : y + 8, x : x + 8] = 1.0B 방울 하나예요. 격자의 8 × 8 정사각형을 슬라이싱으로 한 번에 정해요.
def laplacian(Z):칸 하나가 이웃과 얼마나 다른지예요. 이웃이 더 많이 가진 곳에서는 양수가 되어, 확산이 그 칸을 채워요.
sides = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)np.roll은 격자 전체를 위, 아래, 왼쪽, 오른쪽으로 한 칸 밀어요. 가장자리는 반대편으로 이어지므로 접시에 경계가 없어요.
reaction = A * B * B반응이에요. A 하나와 B 둘이 B 셋이 되는 일이 모든 칸에서 한 번에 일어나요.
A += DA * laplacian(A) - reaction + f * (1 - A)A에 대한 그레이–스콧 규칙이에요. A는 퍼지고, 먹히고, 속도 f로 1을 향해 다시 채워져요.
plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)B의 격자를 그림으로, 칸 하나에 픽셀 하나예요.
직접 해 보기
f, k = 0.034, 0.063으로 해 보세요.
힌트
위쪽 가까이에 있는 한 줄이에요.
정답
반점이에요. 산호의 구불구불한 선 대신 고르게 떨어진 둥근 B 얼룩이 생겨요.
B가 A만큼 빨리 퍼지게 해 보세요: DB = 1.0. 무슨 일이 일어날까요?
힌트
DA, DB = 1.0, 1.0.
정답
패턴이 전혀 생기지 않아요. 방울들이 흐려지다가 사라져요. A가 B보다 빨리 퍼지지 않으면 얼룩들을 떨어뜨려 놓을 것이 없어요. 이것이 튜링이 짚은 핵심이에요.
방울 여섯 개 대신 한가운데에 방울 하나만 써 보세요.
힌트
반복문을 B[60:68, 60:68] = 1.0으로 바꾸세요.
정답
산호가 방울 하나에서 바깥으로 자라는데, 정사각형 방울을 닮은 4중 대칭을 이뤄요. 씨앗 하나는 질서 있는 패턴을, 무작위 방울 여섯 개는 자연스러워 보이는 패턴을 만들어요.
퀴즈
플래시카드
앞면을 읽고, 뒷면의 내용을 스스로 말해 본 다음 카드를 펼쳐 보세요.
np.roll(Z, shift, axis)
배열을 한 축을 따라 밀어요. 한쪽 끝에서 떨어진 것은 반대쪽 끝으로 돌아와요.
라플라시안
칸의 이웃에서 칸 자신을 뺀 것: 확산이 그 칸을 옮겨 갈 방향.
그레이–스콧
A는 f로 공급되고, B는 f + k로 제거되며, A + 2B → 3B.
튜링 불안정성
한 물질이 더 빨리 퍼지면 확산이 고른 혼합물을 패턴으로 깨뜨려요.
plt.imshow(grid)
2차원 배열을 그림으로 보여 줘요. 칸 하나에 픽셀 하나.
아홉 개를 모두 만들었어요. 강좌가 도움이 되었다면 채널에 알려 주세요. 정말 반가울 거예요. 채널 응원하기 →