Processing math: 100%

Box-Muller transformation

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

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

U1,U2U(0,1) 일 때,

X1=2logU1cos(2πU2)N(0,1)

X2=2logU1sin(2πU2)N(0,1)

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

먼저 X1,X2N(0,1) 이라고 가정합니다. X1,X2 를 좌표에 놓고 극좌표법으로 좌표를 구하면 (X1,X2)=(R,θ) 이고

R2=X21+X22 θ=arctanX2X1

이 됩니다.

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

R2=X21+X22χ2(2)Exp(12)2logU

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

f(X1,X2)=12πexp((X21+X22)2)=12πexp(X212)12πexp(X222)=f(X1)f(X2) P(Rr0)=x21+x22r2012πexp((x21+x22)2)dx1dx2=12π2π0r00exp(r22)rdθdr=r00exp(r22)rdr=r2020exp(z)dz=1exp(r202)=F(r20|λ=12)

위의 식을 통해 X1,X2는 서로 독립이라는 것과 P(Rr0) 은 지수분포의 누적분포함수라는 것을 확인 할 수 있습니다(r20>=0 이므로). 이때 λ=12 입니다.

이제 위 식을 아래에서 위로 반대로 거슬러보면, 2logU를 구하여서 이 값을 통해 두 표준 정규 난수의 제곱의 합을 알 수 있습니다. 그런데 x1,x2의 제곱의 합이 같은 경우는 무수히 많고(원에 대한 방정식 x21+x22=r2 와 같습니다) 모두 정규분포를 따릅니다.

그러므로 이때 반지름이 정해진 경우 θ0θ<2π 범위에서 아무거나 공평하게 고르면 됩니다. 따라서 θ=2πU2, U2U(0,1) 로 정합니다.

따라서

X1=Rcos(θ)=2logU1cos(2πU2)N(0,1)X2=Rsin(θ)=2logU1sin(2πU2)N(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)

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