3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

一様分布、正規分布、指数分布、ポアソン分布の乱数を生成する方法 (Scala)

Last updated at Posted at 2020-01-08

乱数を生成するサンプルコードです。一様分布の乱数から特定の分布に従う乱数を生成する方法のメモです。

サンプルコードの言語はScalaです。

一様分布

一様分布の乱数を生成するRandomクラスをそのまま使います。

import scala.util.Random;

// 0からwidthまでの一様な分布の乱数
def randomUniform(width: Double, size: Int): IndexedSeq[Double] = (0 until size).map { _ =>
  width * Random.nextDouble();
}

正規分布

正規分布の乱数を一様分布の乱数から生成します。2個ずつ生成できるので、ループの回数を半分にしています。

import scala.util.Random;

// 平均mu、標準偏差sigmaの正規分布に従う乱数
def randomNormal(mu: Double, sigma: Double, size: Int): IndexedSeq[Double] = {
  val pi2 = 2 * Math.PI;
  (0 until (size + 1) / 2).flatMap { _ =>
    val rnd_a = Random.nextDouble();
    val rnd_b = Random.nextDouble();
    val rnd_a2 = Math.sqrt(-2 * Math.log(rnd_a));
    val rnd_b2 = pi2 * rnd_b;
    val random_1 = mu + sigma * rnd_a2 * Math.sin(rnd_b2);
    val random_2 = mu + sigma * rnd_a2 * Math.cos(rnd_b2);
    List(random_1, random_2);
  }.take(size);
}

2つの0~1の乱数から2つの正規分布の乱数を生成する式です。

\begin{align}
r_1 =& \sqrt{-2\log{a}} \sin{2\pi b} \\
r_2 =& \sqrt{-2\log{a}} \cos{2\pi b} \\
\end{align}

1000個作ったときのヒストグラム。

image.png

※Scalaであれば、Random.nextGaussian()というメソッドを使えます。この記事は一様分布から他の分布を生成する方法です。

指数分布

指数分布の乱数を一様分布の乱数から生成します。パラメータとしてlambdaが必要です。

import scala.util.Random;

// 平均1.0/lambdaの指数分布に従う乱数
def randomExponential(lambda: Double, size: Int): IndexedSeq[Double] = {
  val lambda1 = -1.0 / lambda;
  (0 until size).map { _ =>
    val x = Random.nextDouble();
    lambda1 * Math.log(x);
  }
}

lambda=1.0で1000個作ったときのヒストグラム。

image.png

ポアソン分布

ポアソン分布の乱数を一様分布の乱数から生成します。パラメータとしてlambdaが必要です。ポアソン分布の乱数は0以上の整数です。

import scala.util.Random;

// 平均lambdaのポアソン分布に従う乱数
def randomPoisson(lambda: Double, size: Int): IndexedSeq[Int] = {
  val exp_lambda1 = Math.exp(-lambda);
  (0 until size).map { _ =>
    var r: Int = 0;
    var d: Double = Random.nextDouble();
    while (d >= exp_lambda1) {
      val x = Random.nextDouble();
      d = d * x;
      r = r + 1;
    }
    r;
  }
}

以上。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?