正規分布(対数正規分布)乱数

平均μ, 標準偏差σの正規分布乱数を得るためにはBox-Muller法というのがあるそうです。

 \alpha, \beta を [0,1]の一様乱数としたとき、次の二つの数値

 \sqrt{-\ln{\alpha^{2}}} \sin{ 2\pi\beta}  \sqrt{-\ln{\alpha^{2}}} \cos{ 2\pi\beta}

は平均値0, 標準偏差1の正規分布に即した乱数になります。

[0,1]の一様乱数を二回発生することになりますが、上記の二つの数値に相関はないため、二つの正規分布乱数が得られることになります。
上記の数値にσをかけた後、μを足せば、任意の正規分布乱数の出来上がりです。
以下にC#のコード載せておきます。

        // 平均mu, 標準偏差sigmaの正規分布乱数を得る。Box-Muller法による。
        public static double NormalDistribution(double mu, double sigma)
        {
            if (Flag)
            {
                Alpha = Rn.NextDouble();
                Beta = Rn.NextDouble() * Math.PI * 2;
                BoxMuller1 = Math.Sqrt(-2 * Math.Log(Alpha));
                BoxMuller2 = Math.Sin(Beta);
            }
            else
                BoxMuller2 = Math.Cos(Beta);
            Flag = !Flag;
            return sigma * (BoxMuller1 * BoxMuller2) + mu;
        }
        static Random Rn = new Random(System.Environment.TickCount);
        static double Alpha, Beta, BoxMuller1, BoxMuller2;
        static bool Flag = false;

さらに対数正規分布乱数についてです。

対数正規分布は横軸(x軸)を対数に変換すると正規分布に従うような分布のことです。
この分布関数f(x)の平均値をm, 標準偏差をsとします。さらに、この分布関数の横軸を対数に変換した時の平均値(つまりln(x)の平均)をμ, 標準偏差(ln(x)の標準偏差)をσとすると、以下のような関係があります。

 m=\exp{(\mu + \sigma^2/2)}
 s=m^2 (\exp{(\sigma^2/2) -1})

μとσを左辺にすると
 \mu = \ln{m^2} - \cfrac{ \ln{(m^2+s^2)} }{2}

 \sigma= \sqrt{ \ln{(1+\cfrac{s^2}{m^2})} }

となります。この性質を使えば対数正規分乱数のコードは以下のようにかけます。

        // 平均mu, 標準偏差sigmaの対数正規分布乱数を得る。平均と標準偏差を変換し、Box-Muller法によるNormlDistribution関数を呼び出す。
        public static double LogNormalDistribution(double mu, double sigma)
        {
            if (mu <= 0)
                return double.NaN;
            else
                return Math.Exp(NormalDistribution(Math.Log(mu*mu) – Math.Log(mu*mu+ sigma * sigma) / 2.0, Math.Sqrt(Math.Log(1 + sigma / mu * sigma / mu))));
        }