ブラウン運動とは、水の中に浮かんだ小さな粒子が、目に見えない分子とぶつかりながら、予測不能に動き回る現象です。実はこの動き、物理・統計・金融など、さまざまな分野の基本として活用されています。この記事では、「ランダムに動く粒子をプログラムで描いてみる」ことを目標に、Pythonを使ってブラウン運動をシンプルに再現してみましょう。
MacOS 15.5 arm64-arm-64bit, jupyter notebook 7.2.1
Pythonで学ぶ偏微分方程式の数値シミュレーションの技術書を販売中
計算方法、グラフやアニメーションの作成方法、計算ログの残し方を惜しみなく解説しています!
理論と実装の溝を埋めてくれる良書です!
ブラウン運動ってなに?
まずはブラウン運動のイメージから。たとえば水に浮かんだ花粉を顕微鏡で見ると、フラフラと不規則に動いているのが分かります。この動きが「ブラウン運動」です。
シミュレーション : Pythonでブラウン運動を描く
実装:Pythonでランダムな動きを計算する
ここからは、実際にPythonを使ってブラウン運動の動きを作っていきます。必要な設定(どれくらい長く動かすか、どのくらい細かく時間を分けるかなど)をしたあと、コンピュータにランダムな動きを計算してもらいます。
import numpy as np
rng = np.random.default_rng()
dimension = 2 # 動く方向の数(ここでは上下 + 左右の2方向)
time = 1.0 # 動かす時間の長さ
steps = 100000 # 動きを何回に分けて計算するか
# 時間を細かく分けた点を作成
time_points = np.linspace( start=0.0, stop=time, num=steps + 1, endpoint=True
)
# ランダムな動きのもとになる数字を作成
random_increments = rng.normal(loc=0.0, scale=1.0, size=(steps, dimension))
# ブラウン運動の軌跡を格納する配列を用意
brownian_path = np.empty([steps + 1, dimension])
brownian_path[0, :] = 0.0 # 初期位置は原点
# ランダムな動きを少しずつ足しながら軌跡を作る(ウィーナー過程)
time_deltas = np.sqrt(np.diff(time_points)) # 時間刻み幅の平方根
for i in range(1, steps + 1): brownian_path[i, :] = ( brownian_path[i - 1] + time_deltas[i - 1, np.newaxis] * random_increments[i - 1, :] )
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(6, 6), dpi=300)
plt.plot(brownian_path[:, 0], brownian_path[:, 1], lw=0.1)
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True)
plt.axis("equal")
plt.show()
このコードでは、ランダムな動きを少しずつ積み重ねて、粒が動いている様子を表現しています。
💡補足:
%matplotlib inline
は、Jupyter Notebook上でグラフをノート内に表示するための特別なコマンドです。
実行結果:Jupyter Notebookで動きを可視化!
上のコードをJupyter Notebookで実行すると、粒がフラフラと動き回るようすが図で表示されます。これがまさに「コンピュータで再現したブラウン運動」です。粒子が時間とともにどのようにランダムに動くかが視覚的に確認でき、ブラウン運動を直感的に理解する助けになります。
コードの詳細解説
このコードは、2次元のランダムな動き(ブラウン運動) を以下の手順でシミュレーションしています:
- パラメータ設定(時間、次元、ステップ数)
- 正規分布に従うランダムな数の列を作る
- 時間ごとにそのランダムな変化を足していく(ウィーナー過程)
- 結果の軌跡をグラフで表示
以下、初学者にもわかりやすいように、1行ずつ丁寧に解説していきます。
1. ライブラリのインポート
import numpy as np
numpy
(ナムパイ)は、数値計算を得意とするPythonライブラリです。np
という短い名前で使えるようにしています。
rng = np.random.default_rng()
- 乱数を生成するための「ジェネレーター(乱数装置)」を作ります。
default_rng()
は新しいスタイルの乱数生成器です。
2. パラメータの設定
dimension = 2 # 動く方向の数(2次元=X方向とY方向)
time = 1.0 # シミュレーションする時間の長さ(1秒間)
steps = 100000 # 時間をどれだけ細かく分けるか(大きいほど精密)
dimension=2
により、ランダムな動きが平面上(2次元)になります。steps=100000
は、1秒間の動きを10万回に分けて計算する、という意味です。
3. 時間を小さな区間に分割
time_points = np.linspace( start=0.0, stop=time, num=steps + 1, endpoint=True
)
- 0秒から1秒までを等間隔に
steps+1
個に分割した配列を作成します。 - たとえば
steps=4
なら[0.0, 0.25, 0.5, 0.75, 1.0]
になります。
4. ランダムな動きの作成
random_increments = rng.normal(loc=0.0, scale=1.0, size=(steps, dimension))
- 平均0、標準偏差1の正規分布に従うランダムな値を作ります。
size=(steps, dimension)
によって、10万個の「2次元ベクトル」ができます。
5. ブラウン運動の結果を保存する配列
brownian_path = np.empty([steps + 1, dimension])
brownian_path[0, :] = 0.0 # 初期位置は (0, 0)
- すべての時間における位置を保存するための配列を用意。
- 最初の位置は原点(0, 0)にしています。
6. ウィーナー過程:動きを1つずつ足していく
time_deltas = np.sqrt(np.diff(time_points)) # 各時間区間の長さの平方根
- ブラウン運動は時間刻み幅の「平方根」に比例して進むため、ここで計算します。
for i in range(1, steps + 1): brownian_path[i, :] = ( brownian_path[i - 1] + time_deltas[i - 1, np.newaxis] * random_increments[i - 1, :] )
- 1ステップ前の位置に、ランダムな変化量を足して、次の位置を計算します。
- これを全ステップ分繰り返すことで、ランダムに動き回る軌跡(道筋)ができます。
7. 結果をグラフに描画
import matplotlib.pyplot as plt
%matplotlib inline
matplotlib
はグラフを描くためのライブラリです。%matplotlib inline
は Jupyter Notebook 用の命令で、ノートブック上に図を表示します(普通のPythonスクリプトでは不要です)。
plt.figure(figsize=(6, 6), dpi=300)
plt.plot(brownian_path[:, 0], brownian_path[:, 1], lw=0.1)
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True)
plt.axis("equal")
plt.show()
- 軌跡を2Dグラフとして表示。
brownian_path[:, 0]
はX方向の動き、brownian_path[:, 1]
はY方向の動きを示します。lw=0.1
は線の太さ(細く描く)。axis("equal")
により、X軸とY軸のスケールが同じになります。
まとめ・今後の展望
今回は、
- ブラウン運動ってなに?
- Pythonでの簡単な再現方法
- 動きの可視化
を紹介しました。次回は、ブラウン運動のもう一歩先――Langevin(ランジュバン)方程式を取り上げます。これは、ランダムな力に加えて「摩擦」や「外部からの力」も含めて、より現実に近い粒子の運動をモデル化したものです。
「ただのフラフラ」から「力を受けながらのフラフラ」へ。より深くランダムな運動を理解したい方は、ぜひ次回もお楽しみに!
Pythonで学ぶ偏微分方程式の数値シミュレーションの技術書を販売中
計算方法、グラフやアニメーションの作成方法、計算ログの残し方を惜しみなく解説しています!
理論と実装の溝を埋めてくれる良書です!