レッスン9:グリッドと拡散
Pythonで 「チューリングパターン」 を作りながら、次のことを学びます:
- マスのグリッドとしての2次元配列
- 端が折り返す、np.roll によるとなりのマス
- ラプラシアン:マスと、そのとなりのマスとの差
- グリッド全体を1行で更新する
- 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で実行できます。ノートブックは英語です。
1行ずつ
A, B = np.ones((size, size)), np.zeros((size, size))128 × 128 のグリッドが2つ。エサの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 はグリッド全体を、上、下、左、右に1マスずらします。端は折り返すので、シャーレにはふちがありません。
reaction = A * B * B反応です。Aひとつと Bふたつで、Bが3つになります。すべてのマスでいっぺんに。
A += DA * laplacian(A) - reaction + f * (1 - A)Aについてのグレイ–スコットのルールです。Aは広がり、食べられ、割合fで1に向かって補給されます。
plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)Bのグリッドを絵として表示します。1マスが1ピクセルです。
やってみよう
f, k = 0.034, 0.063 を試してみましょう。
ヒント
上のほうにある1行です。
答え
斑点になります。サンゴのうねる線の代わりに、Bの丸い塊が等間隔に並びます。
BをAと同じ速さで広がるようにしてみましょう:DB = 1.0。何が起こりますか?
ヒント
DA, DB = 1.0, 1.0。
答え
模様はまったくできません。しずくは消えて何も残りません。AがBより速く広がらなければ、塊どうしを引き離しておくものがないのです。これがチューリングの要点です。
しずくを6滴ではなく、真ん中に1滴だけにしてみましょう。
ヒント
ループを B[60:68, 60:68] = 1.0 に置き換えます。
答え
サンゴは1滴のしずくから外へ向かって育ち、正方形のしずくを写した4回対称の形になります。種がひとつなら整った模様に、でたらめな6滴なら自然に見える模様になります。
クイズ
フラッシュカード
表を読み、裏に何があるかを自分で言ってみてから、カードを開いてください。
np.roll(Z, shift, axis)
配列を軸に沿ってずらします。一方の端から落ちたものは、反対の端に戻ってきます。
ラプラシアン
マスのとなりから、そのマス自身を引いたもの。拡散がマスを動かす向き。
グレイ–スコット
Aは割合fで補給され、Bは割合 f + k で取り除かれ、A + 2B → 3B。
チューリング不安定性
一方の物質が速く広がるとき、拡散が均一な混合物を壊して模様にすること。
plt.imshow(grid)
2次元配列を絵として表示します。1マスが1ピクセル。
9つすべてを作り終えました。コースが役に立ったなら、ぜひチャンネルに聞かせてください。 チャンネルを応援 →