1次元のRandomWalk
ショックだ。便利な関数NormやTotal等は5.0からの新関数だったなんて。これ以前のバージョンではたかがベクトルのノルムを計算するだけでも面倒だったんだなぁ。
ランダムウォーク
酔歩とも言う。左へ右へ動き回るランダムな運動の事。考える次元やランダムにする変数などは様々に選べる。ここでは1次元の問題で、左右等確率で動くモデルを考える。
Mathematicaによる計算
これだけの事もMathematicaブックによればたった2行で実装できると言う*1。以下のコードは200ステップのランダムウォークをプロットする。
RandomWalk[n_] := NestList[(# + (-1)^Random[Integer]) &, 0, n] ListPlot[RandomWalk[200], PlotJoined -> True]
一目見ただけでは理解できないので今日はこれを理解してみたい。
(-1)^Random[Integer]
Random[Integer]は確率1/2で0か1を生成する。つまりこの式で-1か1を等確率で取る変数を作る事が出来る。
NestList
NestList[f, expr, n]は,式exprにfを0からn回適用した結果を,リスト形式にして与える。例えば
NestList[f, x, 3]→{x, f[x], f[f[x]], f[f[f[x]]]}
の様になる。さて、今の場合には純関数の変数#も使われている。Mathematicaでは1回しか使わない関数には名前を付けなくても良い事になっている。純関数を使わない形に書き換えると理解しやすいだろうか。
f[x_] := x + (-1)^Random[Integer]; x = 0; RandomWalk[n_] := NestList[f, x, n] ListPlot[RandomWalk[200], PlotJoined -> True]
後ろに付いている"&"はおまじないのような物で、これが無いと"#"が純関数の変数として認識されない。純関数を上手く使うととてもコンパクトに書ける事が分かった。ちなみにこのグラフを10個重ねた結果を表示するには下の様にすれば良い。
pp = Table[ ListPlot[RandomWalk[200], PlotJoined -> True, DisplayFunction -> Identity], {10}]; Show[pp, DisplayFunction -> $DisplayFunction];
まとめ
純関数とNestListを組み合わせると各ステップの積み重ねが簡単に書ける事が分かった。
- http://documents.wolfram.com/mathematica/functions/Random
- http://documents.wolfram.com/mathematica/functions/NestList
- http://documents.wolfram.com/mathematica/functions/ListPlot
- http://documents.wolfram.com/mathematica/functions/Function
- http://documents.wolfram.co.jp/v4-ja/RefGuide/DisplayFunction_ex.html