![]() |
(1) |
32ビット整数(我々が使っているinteger)では,混合合同法をもちいると
program random implicit none integer :: i,j double precision :: ran do j = 1, 100 i = 843314861 * i + 453816693 if( i .lt. 0 ) i = ( I + 2147483647 ) + 1 ran = dfloat(i) * 4.656612873D-10 write(*,*) j,ran enddo end program randomをつかうことで[0,1)に規格化された乱数をつくることができる.ここでμ=2147483648(2の32乗)となっており,意図的に取り扱える整数の上限をオーバーさせることでmod(μ)の計算(割り算は時間がかかる)を回避している.また,4.656612873D-10は2147483648の逆数.
この動画は,牛乳に含まれる脂肪の粒子の運動を示しています.脂肪の粒子は周囲の水分子が絶え間なく衝突してくることで振動し,徐々に移動します.この運動はブラウン運動と呼ばれています.
気体や液体を構成する原子や分子においても同様の現象はおこり,拡散とよばれます.二次元平面を考えて,ある粒子の単位面積あたりの個数をnとすると,拡散は次の拡散方程式によって記述されます.
![]() |
(2) |
拡散方程式は偏微分方程式ですが,微分を無理矢理割り算で置き換えると
![]() |
(4) |
と書くことができます.ここでLは球が存在している範囲の距離.これをtについて解くと
![]() |
(5) |
となり,拡散した距離Lは時間の平方根に比例することがわかります.つまり,等速で運動するよりもはるかに遅い.
一辺が長さ1(整数)の正方形からできている碁盤の目を考える.原点(0,0)にn個の球が置いてある.乱数を発生させ,上下左右に存在する隣の格子点にそれぞれ確率1/4で移動する.n回乱数を発生させ,n個全ての球を一回移動させると1ステップが終了する.
このようなプロセスは「ランダムウォーク」(酔歩)と呼ばれます.分子の拡散,熱の伝導など地球科学においても非常に重要なプロセスを表現しています.
ランダムウォークのプログラムを作成しようとすると,球の数nの大きさの配列を複数用意する必要があります.たとえばi番目の球のx座標,y座標.100個の場合なら
integer :: x(100),y(100)さらに,それぞれの球の原点からの距離も必要であれば dis(100) などが追加されます. 配列のサイズを変化させる場合に複数箇所の数字を変化させる必要が発生し,書き間違いが起こります.このような場合はparamtere文が便利.parameter文は,ある文字列をその数字として読み替える,ということを指示します.つまりプログラム中でその文字列が登場すると,parameter文で定義された数値にコンパイル時におきかわります.parameter文で定義された変数は,プログラム中で別の値を代入はできません. 例:
integer, parameter :: n=1000 integer :: x(n),y(n)
n個の球が上下左右にランダムウォークするプログラムを作成する.始めはすべて原点に球は存在する.確率 1/4 = 0.25D0 で上下左右に1(整数)だけ移動する.まずはn=10でプログラムを実行する.1000ステップ計算を実行すること.
implicit none integer, parameter :: n = 10 ! 球の数 integer :: x(n), y(n) ! など他の変数も宣言する 初期値の格納 時間ステップのループ開始 球に関するループ開始 乱数を発生させ,球を移動させる write(1,*) x(i), y(i) ! アニメのための出力 練習問題5では消す 球に関するループ終了 write(1,*) ! 異なる時間ステップを区別するため空白行を入れる 時間ステップのループ終了 プログラム終了
set xrange [-100:100] set yrange [-100:100] if (k>1000) exit plot "ファイル名" every 1:1::k::k with points pt 7 ps 2 pause 0.05 k=k+1 rereadgnuplot上で
gnuplot> k=1 gnuplot> load 'anim.txt'とすることでアニメーションを観察すること.
前述したとおり,ランダムウォークはあっちにいったりこっちに行ったりするので,等速直線運動よりははるかにゆっくりと位置が変わります.そこで,粒子の平均移動距離がどう時間とともに増加するのかを調べます.
write(1,*) ステップ数 平均値 標準偏差などとする.n=10000とする.なお,アニメを観察するための write(1,*) x(i), y(i)は削除すること. 巨大なファイルが作成されてしまうため.
set log plot 'fort.1','fort.1' u 1:3, x**0.5として平均値と標準偏差を重ねてプロットする(もしファイル名を指定している場合は,上のfort.1をそのファイル名でおきかえる).x**0.5 と一緒にプロットすることで,時間の1/2乗に比例して平均距離が増加することを確かめる.
練習問題5のプログラム,および時刻ー平均距離ー距離の標準偏差のデータファイルを送付すること.
先ほどの問題において,平均値と標準偏差はほぼ平行であるものの平均値の方がいくぶん大きかった.この差がどこから来るのか考える.
拡散方程式(式2)のこの場合の解(t=0で原点に粒子が集中している場合)は
とかける.ここで r=(x**2 + y**2 )**0.5である.D=1とすると,t=1, 2, 4の各時刻における粒子の分布はgnuplotにおいて上の式を使って
plot exp(-x**2/4)/(4*pi),exp(-x**2/8)/(8*pi),exp(-x**2/16)/(16*pi)とすると描くことができる.時間とともに分布が広がっていくことがわかる.
課題1: n(r,t)の式から,rの平均値とrの2乗の平均値をもとめ,(rの2乗の平均値-rの平均値の2乗)**0.5 から標準偏差を求めよ.rのn乗の平均値は以下の式で求めることができる.
![]() |
![]() |
![]() |
(7) |
課題2: rの平均値 / rの標準偏差 はある定数となる.その定数をもとめ,本日の宿題として提出したファイルを使って(この例ではファイル名はfort.1)
plot 'fort.1','fort.1' u 1:($3*その定数)とプロットすると二つの結果がほぼ重なるはずである. 課題2の定数を送付すること.