오늘은 IDL에서 RANDOMU 함수를 사용하여 난수(Random Number)를 생성하는 방법에 대하여 알아보고자 합니다. 이 함수의 사용법은 기본적으로 다음과 같습니다.
result = RANDOMU(seed, 차원별 크기, 기타 키워드들)
여기서 간단한 부분부터 얘기한다면, 차원별 크기라는 항목은 난수들을 어떤 형태의 배열로 생성할 것인가를 결정합니다. 단 하나의 값일 수도 있고 1000개의 값일 수도 있고 100X100의 2차원 형태의 값들이 될 수도 있습니다. 유저의 선택에 따라 1 또는 1000 또는 100, 100과 같은 방식으로 설정하면 됩니다. 그리고 첫번째 항목으로 되어 있는 seed라는 것을 주목해볼 필요가 있는데요. IDL 도움말에서 RANDOMU 함수에 관한 내용을 찾아보면 이 항목에 대하여 적잖은 양의 설명이 있습니다. 일단은 아래와 같은 문구의 설명이 있고 그 밑으로 내용이 좀 더 있습니다.
A variable or constant used to initialize the random sequence on input, and in which the state of the random number generator is saved on output.
대략적으로만 얘기한다면, 생성할 난수들의 순서(Sequence)를 초기화하는데 사용되는 값입니다. 실제 사용에 있어서는 사전에 정의되지 않은 변수를 주거나 정수 고정값을 주는 방식 정도면 충분합니다. 예를 들어 단 하나의 난수를 생성해야 할 경우에는 다음과 같은 방식으로 RANDOMU 함수를 사용하면 됩니다.
IDL> PRINT, RANDOMU(seed, 1)
0.789035
IDL> PRINT, RANDOMU(seed, 1)
0.526321
IDL> PRINT, RANDOMU(seed, 1)
0.780004
여기서 seed라는 이름의 변수는 사전에 값을 정의하지 않은 채로 사용하였습니다. 이런 경우에는 위에서 보는 바와 같이 생성되는 난수의 값이 매번 변합니다. 그런데 이 seed 위치에 고정값을 넣고 사용하는 경우도 있습니다. 즉, 다음과 같이 특정한 정수값을 투입할 경우에 어떤 결과가 나오는지 봅시다.
IDL> PRINT, RANDOMU(10, 1)
0.771321
IDL> PRINT, RANDOMU(10, 1)
0.771321
IDL> PRINT, RANDOMU(10, 1)
0.771321
위의 경우와 다른 점은 생성된 난수값 자체가 계속 고정된다는 것입니다. 물론 그 값을 바꾸면 생성되는 난수값도 바뀌지만 그 값 자체는 계속 고정됩니다.
IDL> PRINT, RANDOMU(-10, 1)
0.860600
IDL> PRINT, RANDOMU(-10, 1)
0.860600
IDL> PRINT, RANDOMU(-10, 1)
0.860600
따라서 난수를 생성할 때 매번 변화무쌍한 값을 얻고자 할 경우인지 또는 생성된 난수값 자체를 고정시킬 것인지에 따라서 seed 자리에 변수를 투입하느냐 아니면 고정된 값을 투입하느냐를 결정하면 됩니다. 이 seed 항목에 관한 좀 더 자세한 내용은 IDL 도움말에서 RANDOMU 함수에 관한 내용을 참조하시기 바랍니다. 이 내용을 보면 난수 생성에 있어서 사용된 수치 알고리즘에 관한 언급도 있으므로 참조해볼만 합니다.
위의 예제에서는 난수를 하나만 생성했었는데 이번에는 좀 더 많은 갯수의 난수들을 한꺼번에 생성해봅시다. 다음과 같이 1000개의 난수들을 생성하면, data라는 배열은 1000개의 난수 실수값들로 구성된 배열의 형태로 얻어집니다.
IDL> data = RANDOMU(seed, 1000)
IDL> HELP, data
DATA FLOAT = Array[1000]
IDL> PRINT, MIN(data), MAX(data)
0.00187018 0.999151
그런데 data 배열에 관한 기본적인 정보를 조회해본 결과 위와 같이 최소 및 최대 값이 나타나는 것을 볼 수 있습니다. 물론 여기서 사용된 seed는 사전에 값이 정의되지 않은 변수이기 때문에 여러분이 위의 작업을 직접 해보실 경우에는 세부적인 최소, 최대값들이 약간 다르게 나올 수는 있습니다. 하지만 기본적으로는 RANDOMU 함수는 0과 1 사이의 범위에 해당되는 난수값들을 생성합니다. 만약 다음과 같이 100을 곱해줄 경우에는 0과 100 사이의 범위에 해당되는 난수값들을 얻을 수도 있습니다.
IDL> data = RANDOMU(seed, 1000)*100
IDL> HELP, data
DATA FLOAT = Array[1000]
IDL> PRINT, MIN(data), MAX(data)
0.0738755 99.8411
그리고 더 중요한 것은 이 1000개의 값들의 분포 형태입니다. 이를 살펴보기 위하여 다음과 같이 히스토그램의 형태로 분포도를 그려 봅시다. 그 대상은 바로 위에서 얻은 것과 같은 0과 100 사이의 범위에 있는 1000개의 난수값들로 하겠습니다. 이를 위하여 다음과 같은 예제 코드를 작성해 볼 수 있습니다. 이 내용은 제가 예전에 한번 올렸던 히스토그램 그리는 방법에 관한 게시물의 내용과 연관이 있다는 점 참조하시기 바랍니다.
data = RANDOMU(seed, 1000)*100 & str = 'Uniform Distribution'
HELP, data
PRINT, MIN(data), MAX(data)
bsz = 1
hist = HISTOGRAM(data, MIN=0, MAX=100, BINSIZE=bsz, LOCATIONS=xh)
win = WINDOW(DIMENSIONS=[600, 500])
pl = BARPLOT(xh+bsz/2., hist, XRANGE=[0, 100], YRANGE=[0, 30], $
YMINOR=0, YTICKLEN=0, FILL_COLOR='orange', TITLE=str, $
XTITLE='Value', YTITLE='Count', /CURRENT)
어쨌든 이렇게 얻은 히스토그램의 모습은 다음 그림과 같습니다.
이 그림을 보면, 생성된 난수값들의 분포 형태가 보입니다. 바로 균일 분포(Uniform Distribution)의 형태입니다. 따라서 여기서 사용하고 있는 RANDOMU 함수는 0과 1 사이의 범위 내에서 균일 분포를 하는 난수값들을 생성하는 역할을 한다고 보면 됩니다. 물론 균일 분포 외에도 다른 형태의 분포를 하는 난수들을 생성하는 것도 가능합니다. 이에 관한 내용은 바로 이어질 게시물에서 계속해서 진행하기로 하겠습니다.
'IDL > Math' 카테고리의 다른 글
| 정규 분포(Normal Distribution) 함수의 테스트 (0) | 2016.10.31 |
|---|---|
| RANDOMU 함수를 사용한 난수 생성 (Part 2) (0) | 2016.08.01 |
| TRIANGULATE 프로시저 및 TRIGRID 함수의 이해 [2] (0) | 2016.05.19 |
| TRIANGULATE 프로시저 및 TRIGRID 함수의 이해 [1] (0) | 2016.05.04 |
| MPFITELLIPSE 함수를 이용한 타원형 궤적 근사 (0) | 2016.04.25 |