Box-Muller transformation

Box-Muller transformation으로 정규 난수 생성하기

박스-뮬러 변환은 가장 간단한 정규 난수 발생법 중 하나입니다. Box와 Muller에 의해 1958년 발표되었습니다.

$U_1, U_2 \sim \mathrm{U}(0,1)$ 일 때,

$X_1 = \sqrt{-2logU_1}cos(2\pi U_2) \sim \mathrm{N(0,1)}$

$X_2 = \sqrt{-2logU_1}sin(2\pi U_2) \sim \mathrm{N(0,1)}$

이 되어 서로 독립이고 같은 분포를 가지는(iid) 2개의 표준 정규 난수를 발생시키게 됩니다.

먼저 $X_1, X_2 \sim \mathrm{N(0,1)}$ 이라고 가정합니다. $X_1, X_2$ 를 좌표에 놓고 극좌표법으로 좌표를 구하면 $(X_1, X_2) = (R, \theta)$ 이고

이 됩니다.

$R^2$을 보면 $X_1^2$과 $X_2^2$의 합으로 이루어져 있고, 표준 정규 난수의 제곱은 카이제곱 분포 $\chi^2(1)$를 따르고, 카이제곱 분포는 지수 분포로 표현할 수 있으며, 지수분포는 역변환법(Inverse transformation)에 의해 $\mathrm{U}(0,1)$의 꼴로 표현할 수 있습니다. 이를 식으로 표현하면 다음과 같습니다.

다른 방법으로 R의 누적분포함수를 직접 구하면 다음과 같습니다.

위의 식을 통해 $X_1, X_2$는 서로 독립이라는 것과 $P \left(R \leq r_0 \right)$ 은 지수분포의 누적분포함수라는 것을 확인 할 수 있습니다($r_0^2 >= 0$ 이므로). 이때 $ \lambda = \frac{1}{2}$ 입니다.

이제 위 식을 아래에서 위로 반대로 거슬러보면, $-2log \mathrm{U}$를 구하여서 이 값을 통해 두 표준 정규 난수의 제곱의 합을 알 수 있습니다. 그런데 $x_1, x_2$의 제곱의 합이 같은 경우는 무수히 많고(원에 대한 방정식 $x_1^2+x_2^2 = r^2$ 와 같습니다) 모두 정규분포를 따릅니다.

그러므로 이때 반지름이 정해진 경우 $\theta$는 $0 \leq \theta < 2\pi$ 범위에서 아무거나 공평하게 고르면 됩니다. 따라서 $ \theta = 2\pi U_2$, $ U_2 \sim \mathrm{U}(0,1) $ 로 정합니다.

따라서

가 성립합니다.

아래는 박스-뮬러 변환법을 R 코드로 구현한 것입니다.

rnorm.boxmuller = function(n, mean=0, sd=1){
  U1 = runif(ceiling(n/2))
  U2 = runif(ceiling(n/2))
  Z1 = sqrt(-2*log(U1))*cos(2*pi*U2)
  Z2 = sqrt(-2*log(U1))*sin(2*pi*U2)
  c(Z1, Z2)[1:n] * sd + mean
}

rnorm.boxmuller(100)

꽤 간단하게 작성 가능합니다.