티바이트



http://tibyte.kr/218 에서 이어집니다.




주의) Matlab에서는 특정 분포를 하는 다양한 난수생성을 지원합니다.

이 포스트는 코드를 간단히 구현해 보기 위한 목적으로 matlab을 사용합니다.



정규난수를(normal random variable)얻기 위해 박스-뮬러 변환(Box-Muller Transform) 을 쓸 수 있지만


연산과정에 삼각함수가 들어 있기 때문에

이 복잡성을 해결하기 위해 George Marsaglia가 고안한 극좌표법(polar method)을 쓸 수 있다.




박스뮬러 방법에서 균일랜덤변수 u를 사용하여  sin(2pi*u)와 cos(2pi*u)로 나타냈던 것을

극좌표법에서는 원 위에 무작위로 점(u1, u2)을 찍어서 cos이 밑변/빗변,

sin이 높이/빗변인 것을 이용하여  삼각함수를 대체한다. 


박스뮬러 방법에서의 U1이 거리제곱(sq)으로 대체되고,

삼각함수 대신 제곱과 제곱근연산이 들어가게 된다.

[그림 1]





매틀랩 코드로 구현한 결과이다. 표준편차가 1이고 평균이 0인 정규분포를 생성. 


N = 1000000;

u1 = zeros(1,N);

u2 = zeros(1,N);

wsq = zeros(1,N);

for i=1:N

   sq = 2;

   while sq>1

      r1 = rand;

      r2 = rand;

      sq = r1.*r1 + r2.*r2;

   end

   u1(i) = r1;

   u2(i) = r2;

   wsq(i) = sq;

end

s = 1;

m = 0;

x = m+s*sqrt(-2*log(wsq)).*u1./(wsq.^0.5);

y = -1.*(m+s*sqrt(-2*log(wsq)).*u2./(wsq.^0.5));

n = horzcat(x,y);

hist(n, 50);



히스토그램 결과.


[그림 2]





이 방법의 단점은 [그림 1]과 코드에서 볼 수 있듯이

점이 원 밖에 찍혔을 경우 평균적으로 1.27배 만큼 난수를 다시 뽑아야 한다는 것이다.

(1.27배는 기하분포의 급수로 계산)









 


  1. 테스트

댓글을 다는 공간입니다. (로그인하지 않아도 댓글을 남길 수 있습니다.)



게시판 목록은 좌측상단에 있습니다.

Statistics Graph