
元少年の自由研究:数式が紡ぎだす生命の模様 〜ティューリングパターンで解き明かす自然界のデザイン〜🧬✨
宇宙好きの皆さん、こんにちは!元少年です。今回の記事では、ただ遥か彼方の星々だけでなく、身近な自然界にも広がる神秘の模様―ティューリングパターン―に挑戦してみました。シマウマの縞模様、ヒョウの斑点、さらには植物の繊細な葉模様…これらの美しいデザインは、実はシンプルな数式と反応拡散現象という不思議な物理法則から生み出されているのです。この記事を通して、宇宙の神秘と同じくらい魅力的な自然のデザインの裏側に迫ってみましょう!
ティューリングパターンとは?

ティューリングパターンは、数学者アラン・ティューリングによって提唱された反応拡散系の理論に基づくもので、シンプルな化学反応と拡散の相互作用が、予想外の複雑な空間パターンを自発的に生み出す現象を示しています。ティューリングは、自然界に見られる動物の皮膚模様やその他の生体パターンの形成メカニズムにこの理論を適用し、物理化学的プロセスが自己組織化の根底にあることを示唆しました。ここで興味深いのは、非線形な反応項と拡散項が相互作用することで、一見ランダムに見える現象から秩序が生じるという点です。
グレイースコットモデルとは?

今回のシミュレーションでは、反応拡散系の代表的なモデルのひとつであるグレイースコットモデルを採用しました。このモデルは、単純な局所反応と物質の拡散が相互に作用することで、自然界に見られるような複雑で秩序あるパターンがどのようにして創発されるのか、そのメカニズムを解明するための強力なツールとなっています。
グレイースコットモデルでは、化学物質 $${u}$$ と $${v}$$ の濃度の時間変化が、次のような非線形偏微分方程式によって記述されます。
$${\frac{\partial u}{\partial t} = D_u \nabla^2 u - u v^2 + f(1-u)}$$
$${\frac{\partial v}{\partial t} = D_v \nabla^2 v + u v^2 - (f+k)v}$$
ここで、
$${D_u}$$ と $${D_v}$$ は、それぞれ $${u}$$と $${v}$$ の拡散係数を示し、空間内での物質の広がりの速さを定量化します。
$${f}$$ はフィード率を意味し、外部から系に供給される物質の量を表現します。
$${k}$$ は除去率として、系内での物質の消失や反応による除去効果を担います。
これらのパラメータは、局所的な反応項と拡散項のバランスを決定し、初期条件に微小な揺らぎがあった場合に、どのようなパターンが創発するかを大きく左右します。特に、反応項に含まれる非線形な $${-u v^2}$$ および $${u v^2}$$ の項は、局所的な濃度変化を劇的に増幅させ、システムがティューリング不安定性に陥る条件を作り出します。この不安定性こそが、単一の均一状態から複雑で多様なパターンへの転移を引き起こす根源となっています。

シミュレーションを通じて、パラメータ $${f}$$ や $${k}$$ の微妙な変化が、生成されるパターンの形状や周期、さらには動的な変遷にまでどのように影響するのかを検証することは、自己組織化現象の本質を理解する上で非常に重要です。また、これらの現象は単に数学的な興味に留まらず、実際に生物の皮膚模様、動植物の成長パターン、さらには材料科学やエコシステムにおける分布パターンなど、多岐にわたる自然現象のモデル化にも応用されています。
このように、グレイースコットモデルは、反応と拡散という二つの基本的なプロセスがどのように連動して複雑なパターンを生成するかを直感的かつ定量的に示してくれる理論的枠組みです。本記事では、これらの数理モデルを通して、自己組織化のメカニズムと、その普遍性についてさらに深く掘り下げていきます。
シミュレーション概要

本記事では、グレイ‐スコットモデルという反応拡散系を用いて、時間発展するティューリングパターンの生成過程に迫ります。Python を活用し、離散化した空間上で局所的な反応と物質の拡散をシミュレーションすることで、自然界に見られる複雑な模様がどのようにして自発的に形成されるのか、そのメカニズムを直感的に体験していただける内容となっています。
従来はシンプルな Euler 法による数値計算が一般的でしたが、今回はより高い精度と安定性が求められるため、4次 Runge-Kutta (RK4) 法を採用しています。RK4 法の導入により、初期の微小な摂動がどのようにして増幅し、ティューリング不安定性を経て豊かなパターンが生み出されるのかを、より詳細に追跡することが可能となりました。
さらに、Matplotlib の FuncAnimation を利用することで、各タイムステップで変化する基質 $${u}$$ と反応物 $${v}$$ の濃度分布をリアルタイムに可視化。左右のサブプロットに分けて表示することで、反応と拡散という局所現象がどのように協調して全体としてのパターンを形成するのか、そのダイナミクスを視覚的に理解していただける設計としています。
このシミュレーションは、単に美しい模様の生成を示すだけでなく、自己組織化現象の背後にある普遍的な原理—すなわち、シンプルなルールから複雑性が創発するという自然の驚異—に気づいていただくための試みです。プログラミングや数理モデルに興味をお持ちの皆さんにとって、身近なツールで複雑な現象を再現できるという事実は、大変エキサイティングなものになるはずです。
シミュレーション結果
それでは、実際にコードを動かして得られた結果を見てみましょう。ここでは 4 つのフレーム(Frame 0, Frame 50, Frame 100, Frame 150)をピックアップして、パターンがどのように変化していくのかを追いかけます。

初期状態(Frame 0)
一番左上の画像が、シミュレーション開始時点(Frame 0)の状態です。
背景はややピンクがかった色合いで塗りつぶされていますが、中央付近だけ四角形の領域が濃い緑色になっています。これはコード上で与えた「摂動(乱れ)」によるもので、均一な状態に小さな揺らぎを加えることで、後に現れるパターンの“種”となる部分を作っています。
ポイント
グリッド全体を最初は「u = 1, v = 0」という均質な状態にし、そこに小さな領域だけ「u と v の値を変える」ことで揺らぎを与えています。 この「ほんの少しの違い」が、後に複雑な模様を生み出す原動力となるのが、ティューリングパターンの面白いところです。
変化の兆し(Frame 50)
Frame 50 になると、中央の四角形は濃淡がやや薄まり、背景との境界があいまいになり始めています。色合いもピンクから淡いベージュ系にシフトし、全体的にやわらかいトーンになっているのがわかります。
これは、拡散と反応によって局所的な化学種(u と v)が移動し、初期の“角ばった”形状が徐々に崩れてきたことを示しています。まだ模様としてはシンプルですが、今後どのように成長・変化していくのか期待が高まります。
ポイント
コードでは 4 次の Runge-Kutta 法 (RK4) を用いて数値更新しており、高い精度で反応拡散プロセスを追跡できるため、こうした細かな差異も時間とともに自然に変化していきます。
拡散と反応の進行(Frame 100)
Frame 100 では、中央に残っていた緑の四角形がほとんどわからないくらい淡い色味に溶け込み、背景に吸収されつつあります。遠目にはピンク一色に近い印象ですが、よく見ると中心付近だけ微妙に色の濃淡が残っています。
これこそが「均一にはなりきらず、まだ何かを作りかけている状態」です。ティューリングパターンでは、一定の条件が揃うと微小な揺らぎが拡散によって増幅され、やがて斑点や縞模様などの秩序あるパターンを形作ります。今回の設定(フィード率 f と除去率 k)や摂動の与え方によっては、ここからさらに別の模様が出現するケースも考えられます。
ポイント
ティューリング不安定性が起こる条件では、一見して「ほとんど消えた」と思った揺らぎが、別の位相で再び際立つようになることがあります。 このコード例では f と k を動的に変化させているので、時間とともに模様が移り変わりやすいという特徴があります。
カラーシフトと収束(Frame 150)
Frame 150 では、画面全体がピンク系の優しい色味で埋め尽くされ、中央の四角形や模様らしいものはほとんど見えなくなっています。
一見、「もうパターンは消えてしまったのでは?」と感じるかもしれません。ですが、実は裏側で化学種(u, v)はまだ微妙に変動しており、パラメータ (f, k) が再び値を変えれば、新たな斑点や縞模様が立ち上がることもあります。今回はタイミング的に、このフレーム時点では色相の変化が収束気味になり、大きな模様が見えづらい状態になっているのです。
ポイント
このシミュレーションでは、色相 (Hue) を v の値に応じて動的に変えており、さらに時間変化によるオフセットが加わっているため、単色に見えるフレームでも厳密には色値が微妙に移り変わっています。 一定時間後に別のフレームを抜き出すと、また異なる模様や色彩が出現していることが多いので、動画で連続再生してみると「消えたと思った模様がまた浮かび上がってくる瞬間」に出会えることもしばしばです。
コードの解説
1. ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
numpy
数値計算を高速に行うためのライブラリです。行列や配列を扱うことで、シミュレーションの計算処理を効率化します。matplotlib
データの可視化を行うためのライブラリです。グラフや画像としてシミュレーション結果を描画します。matplotlib.animation
シミュレーションの時間発展をアニメーションとして表示するために利用しています。
2. 初期状態の設定
シミュレーションの最初の状態では、グリッド全体を基質 u が 1、反応物 v が 0 に設定されています。
その後、グリッドの中央部分に小さな乱れ(摂動)を与えます。
この摂動が、後にパターンの「種」となり、時間経過とともに複雑な模様が広がっていきます。
def initialize_fields(size, perturbation_radius):
u = np.ones((size, size))
v = np.zeros((size, size))
center = size // 2
u[center - perturbation_radius:center + perturbation_radius,
center - perturbation_radius:center + perturbation_radius] = 0.50
v[center - perturbation_radius:center + perturbation_radius,
center - perturbation_radius:center + perturbation_radius] = 0.25
return u, v
3. ラプラシアンの計算
拡散現象を再現するために、グリッド上の各セルについてラプラシアンを計算します。
ここでは、周期境界条件を用いることで、グリッドの端と端が連続しているかのように扱っています。
そのため、np.roll 関数を用いて隣接セルの値を取得し、以下の式でラプラシアンを求めます:
$$
\nabla^2 Z_{i,j} \approx Z_{i+1,j} + Z_{i-1,j} + Z_{i,j+1} + Z_{i,j-1} - 4Z_{i,j}
$$
def laplacian(Z):
return (np.roll(Z, 1, axis=0) + np.roll(Z, -1, axis=0) +
np.roll(Z, 1, axis=1) + np.roll(Z, -1, axis=1) - 4 * Z)
4. 反応拡散項の計算
グレイ‐スコットモデルの方程式に基づき、基質 u と反応物 v の反応・拡散項を計算します。
それぞれの時間変化は、以下の数式で表されます:
$$
\frac{\partial u}{\partial t} = D_u \nabla^2 u - u\,v^2 + f(1-u)
\\
\frac{\partial v}{\partial t} = D_v \nabla^2 v + u\,v^2 - (f+k)
$$
ここでは、拡散係数 DuD_uDu と DvD_vDv、フィード率 fff、除去率 kkk をパラメータとして用いています。
def compute_derivatives(u, v, Du, Dv, f, k):
Lu = laplacian(u)
Lv = laplacian(v)
uvv = u * v**2
du = Du * Lu - uvv + f * (1 - u)
dv = Dv * Lv + uvv - (f + k) * v
return du, dv
5. 数値更新:4次Runge–Kutta (RK4) 法
シミュレーションでは、4次Runge–Kutta (RK4) 法を用いて、1 タイムステップごとに u と v の状態を更新しています。
RK4 法は、以下の4段階のステップで次の状態を高精度に求める手法です:
k1: 現在の状態での導関数を計算
k2: k1 を用いて中間状態の導関数を計算
k3: k2 を用いてさらに中間状態の導関数を計算
k4: k3 を用いて最終状態の導関数を計算
これらを加重平均することで、新たな状態 u_new と v_new を求めます。
def rk4_step(u, v, dt, Du, Dv, f, k):
du1, dv1 = compute_derivatives(u, v, Du, Dv, f, k)
du2, dv2 = compute_derivatives(u + dt * du1 / 2, v + dt * dv1 / 2, Du, Dv, f, k)
du3, dv3 = compute_derivatives(u + dt * du2 / 2, v + dt * dv2 / 2, Du, Dv, f, k)
du4, dv4 = compute_derivatives(u + dt * du3, v + dt * dv3, Du, Dv, f, k)
u_new = u + (dt / 6) * (du1 + 2 * du2 + 2 * du3 + du4)
v_new = v + (dt / 6) * (dv1 + 2 * dv2 + 2 * dv3 + dv4)
return u_new, v_new
6. アニメーションの作成
matplotlib.animation.FuncAnimation を用いて、シミュレーションの進行状況をリアルタイムでアニメーション表示します。
update 関数では、毎フレームごとに RK4 法で u と v を更新し、その結果を画像に反映させています。
これにより、初期の微小な乱れからどのようにして複雑なパターンが生み出されるのかを、動的に視覚体験することができます。
ani = animation.FuncAnimation(fig, update, frames=10000, interval=1, blit=True)
まとめと今後の展望
このシミュレーションコードは、以下の流れで構成されています。
ライブラリのインポート
数値計算(numpy)と描画(matplotlib、animation)のためのライブラリを読み込みます。初期状態の設定
グリッド全体を $${u=1}$$、$${v=0}$$ に初期化し、中央部に小さな乱れを加え、パターンの「種」を設定します。ラプラシアンの計算
周期境界条件を用いて、各セルの隣接セルとの値の差分からラプラシアンを計算し、拡散の効果を再現します。反応拡散項の計算
グレイ‐スコットモデルの数式に基づき、非線形な反応項と拡散項を計算し、系の時間変化を表現します。数値更新(RK4 法)
4次Runge–Kutta法を用いて、高精度に $${u}$$ と $${v}$$ の値をタイムステップごとに更新します。アニメーションの作成
FuncAnimation を利用して、シミュレーションの進行をリアルタイムで描画し、動的なティューリングパターンを体験できます。
今回の結果では、初期の四角形が徐々に拡散されて色の境界があいまいになり、最終的にはほとんど目立つ模様が消えかけた状態を確認しました。しかし、ティューリングパターンの醍醐味は、微小な乱れが思いがけない形状へと発展するその“プロセス”にこそあります。
実際にコードを少し改変してみると、まだら模様が現れたり、縞のようなパターンが出現したり、あるいは渦巻き状の構造がくっきりと浮かんできたりと、さまざまな可能性が広がります。
たとえば、フィード率 (f) と除去率 (k) を固定して長い時間シミュレーションを回すと、パターンが再び浮かんでくる場合があります。
拡散係数 (Du, Dv) を変化させてみると、肌理 (きめ) の細かい模様が生まれることもあります。
カラーリングのアルゴリズムをカスタマイズすれば、また違ったアート作品のようなビジュアルを楽しむこともできるでしょう。
もし気に入ったフレームがあれば、コード中に示したように画像として保存して、壁紙にしたり SNS で共有してみたりすると、「自然界の不思議なアートをプログラムで再現したんだ!」とちょっとした話題になりそうです。ぜひいろいろ試していただき、思いもよらない「生命のように動き続けるパターン」の世界を味わってみてください。
ワンポイントアドバイス
「ずっと単調なピンクばかりになる…」という場合は、パラメータ f や k の値を大きく揺らしてみるのがおすすめです。さらにランダムな初期分布を与えると、あちこちで模様が生成される様子を観察できます。 シミュレーションサイズ(配列の大きさ)を大きくしすぎると処理が重くなり、描画や保存に時間がかかってしまいます。最初は小さめのサイズで試し、慣れてきたら少しずつ拡張するとよいでしょう。
コード全文
以下は、有料記事にて掲載しているティューリングパターンシミュレーションの完全コードです。
コード全文と詳細な解説をぜひご覧ください!
ここから先は
この記事が参加している募集
この記事が気に入ったらチップで応援してみませんか?