基本的な話になるが、モンテカルロ法で正規分布に従う乱数、つまり正規乱数を生成する必要があるが、それにはいろんな方法がある。
いったん一様乱数を生成してから、それをもとに正規乱数を求めることになる。この、一様乱数から正規乱数を求める方法がいろいろある。
教科書によく出てくるのはBox-Muller法だが、これは一様乱数2つを正規乱数2つに変換するもので、学生がよく使っている。初等関数のみの式で、プログラミングも簡単だからだ。しかし、実務では分布の裾の精度が必ずしもよろしくないため、あまり使わない。
逆関数法も教科書によく出てくる。一様乱数は0から1の値をとるため、確率と考えることができ、その確率に対応する正規分布のパーセンタイル点を使う、というものだ。これは正規分布の累積分布関数の逆関数を作用させていることに対応する。
ところがこの累積分布関数自体が初等関数で表すことができず、その逆関数になると当然ながら解析的には出ない。しかしながら、先人たちがこの逆関数の近似解をいろいろと発明している。
実務でよく用いる近似解は、Moroの方法、というやつだ。これは、逆関数の近似解のうち、分布の裾の精度が良いと言われており、実務で好んで使われている。
QuantLibでは、以下にMoroInverseCumulativeNormalというクラスがあり、このクラスのインスタンスを生成し、関数オブジェクトとして用いればよい。
QuantLib/ql/math/distributions/normaldistribution.hpp
ところで、みんな大好きExcelで一様乱数から正規乱数に変換するには、NormSInv()を用いる。その名の通り逆関数法によるもので、誰かの作ったシートのセルの中に入っているのをよく見かける。
VBAから呼び出すには確か、Application.NormSInv()を呼べばよいが、これがやたらと遅い。ループで何回も呼び出してみるとわかるが、とにかく遅いのだ。Moroの方法をコーディングするのがめんどくさいのであれば、最悪、Box-Muller法を自前実装した方がいいだろう。
—–