이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

난수 스트림을 만들고 제어하기

RandStream 클래스를 사용하면 난수 스트림을 만들 수 있습니다. 이 클래스는 여러 이유로 유용합니다. 예를 들어, 전역 스트림의 상태에 영향을 미치지 않고 난수 값을 생성하고자 할 수 있습니다. 시뮬레이션에서 임의성을 주는 별도의 원천이 필요할 수 있습니다. 또는, MATLAB®이 시작 시에 사용하는 알고리즘과 다른 생성기 알고리즘을 사용해야 할 수 있습니다. RandStream 생성자를 통해 자신만의 스트림을 만들고, 쓰기 가능한 속성을 설정하며, 이를 사용하여 난수를 생성할 수 있습니다. 전역 스트림을 제어하는 것과 동일한 방식으로, 사용자가 만든 스트림을 제어할 수 있습니다. 전역 스트림을 사용자가 만든 스트림으로 교체할 수도 있습니다.

스트림을 만들려면 RandStream 생성자를 사용하십시오.

myStream=RandStream('mlfg6331_64');
rand(myStream,1,5)

ans =

    0.6530    0.8147    0.7167    0.8615    0.0764

난수 스트림 myStream은 전역 스트림과 별개로 동작합니다. 함수 rand, randn, randi는 계속해서 전역 스트림에서 값을 추출하고, myStream에 적용되는 RandStream 메서드 rand, randn, randi의 결과에 영향을 미치지 않습니다.

RandStream.setGlobalStream 메서드를 사용하여 myStream을 전역 스트림으로 만들 수 있습니다.

RandStream.setGlobalStream(myStream)
RandStream.getGlobalStream

ans = 

mlfg6331_64 random stream (current global stream)
             Seed: 0
  NormalTransform: Ziggurat

RandStream.getGlobalStream==myStream

ans =

     1

서브스트림

사용자는 시뮬레이션의 이전 부분으로 돌아가고자 할 경우가 있을 수 있습니다. 서브스트림이라고 불리는 정해진 검사 지점으로 난수 스트림을 이동하도록 하는 방식으로 제어할 수 있습니다. Substream 속성을 사용하면 여러 서브스트림 사이를 이동할 수 있습니다. Substream 속성을 사용하려면 서브스트림을 지원하는 생성기를 사용하여 스트림을 만드십시오. 생성기 알고리즘과 해당 속성에 대한 목록은 난수 생성기 선택하기 항목을 참조하십시오.

stream=RandStream('mlfg6331_64');
RandStream.setGlobalStream(stream)

Substream의 초기값은 1입니다.

stream.Substream

ans =

     1

서브스트림은 직렬 계산에 유용합니다. 서브스트림은 스트림 내 특정 검사 지점으로 돌아가 시뮬레이션 전체나 일부를 다시 만들 수 있습니다. 예를 들어, 루프에서 서브스트림을 사용할 수 있습니다.

for i=1:5
    stream.Substream=i;
    rand(1,i)
end

ans =
    0.6530

ans =
    0.3364    0.8265

ans =
    0.9539    0.6446    0.4913

ans =
    0.0244    0.5134    0.6305    0.6534

ans =
    0.3323    0.9296    0.5767    0.1233    0.6934

이러한 각각의 서브스트림은 자신의 루프 반복을 다시 생성해 낼 수 있습니다. 예를 들어, 사용자는 원한다면 5번째 서브스트림으로 돌아갈 수 있습니다. 그리고 그 결과는 위에 나와 있는 5번째 출력값과 동일한 값을 반환합니다.

stream.Substream=5;
rand(1,5)

ans =

    0.3323    0.9296    0.5767    0.1233    0.6934

난수 생성기 선택하기

MATLAB은 여러 가지 생성기 알고리즘 옵션을 제공합니다. 다음 표에는 사용 가능한 생성기 알고리즘의 주요 속성과 이를 만드는 데 사용되는 키워드가 요약되어 있습니다. 사용 가능한 생성기 알고리즘의 전체 목록을 반환하려면 RandStream.list 메서드를 사용하십시오.

키워드생성기다중 스트림 및 서브스트림 지원 여부최대 정밀도의 근사 주기
mt19937ar메르센 트위스터(Mersenne Twister)(MATLAB 시작 시 디폴트 스트림에서 사용)아니요219937-1
dsfmt19937SIMD 기반 고속 메르센 트위스터 아니요219937-1
mcg16807승산식 합동법 생성기아니요231-2
mlfg6331_64시차 피보나치 수열 생성기2124(길이가 272인 251개의 스트림)
mrg32k3a결합 다중 재귀적 생성기2191(길이가 2127인 263개의 스트림)
philox4x32_1010회 라운드의 Philox 4x32 생성기2193(길이가 2129인 264개의 스트림)
threefry4x64_2020회 라운드의 Threefry 4x64 생성기2514(길이가 2258인 2256개의 스트림)
shr3cong선형 합동법 생성기로 계산된 시프트 레지스터 생성기아니요264
swb2712수정된 자리 내림을 사용하는 뺄셈 생성기아니요21492

생성기 mcg16807, shr3cong, swb2712는 이전 MATLAB 버전과의 호환성을 위해 제공됩니다. mt19937ardsfmt19937은 기본적으로 순차적인 응용 프로그램을 위해 설계되었습니다. 나머지 생성기는 병렬 난수 생성에 대한 명시적인 지원을 제공합니다.

일부 생성기는 응용 프로그램에 따라 속도가 더 빠르거나 더욱 정밀한 값을 반환할 수 있습니다. 모든 의사 난수 생성기는 결정론적 알고리즘을 바탕으로 하며, 이러한 생성기는 모두 충분히 구체적인 통계적 임의성 검정에 실패합니다. 몬테 카를로(Monte Carlo) 시뮬레이션의 결과를 확인하는 한 가지 방법은 두 개 이상의 각기 다른 생성기 알고리즘을 사용하여 시뮬레이션을 다시 실행하는 것이며, MATLAB이 선택하는 생성기에 따라 이를 수행하는 방법이 제공됩니다. 각기 다른 생성기를 사용하는 경우 결과가 몬테 카를로 샘플링 오차 이상으로 달라질 가능성은 낮지만, 문서에 이러한 유형의 확인(Validation)을 통해 특정 생성기 알고리즘의 결함이 확인된 예제가 나와 있습니다. 예제는 [13] 항목을 참조하십시오.

생성기 알고리즘

mt19937ar

메르센 트위스터([11]에 설명되어 있음)는 주기가 2199371이며, 각 U(0,1) 값은 2개의 32비트 정수를 사용하여 생성됩니다. 가능한 값은 구간 (0,1) 내에 있는 253의 배수입니다. 이 생성기는 다중 스트림이나 서브스트림을 지원하지 않습니다. mt19937ar 스트림에 기본적으로 사용되는 randn 알고리즘은 지구라트 알고리즘 [7]이지만, 그 기반에는 mt19937ar 생성기가 있습니다. 참고: 이 생성기는 MATLAB 버전 7부터 rand('twister',s)로 활성화되는 rand 함수에서 사용하는 생성기와 동일합니다.

dsfmt19937

배정밀도 SIMD 기반 고속 메르센 트위스터([12]에 설명되어 있음)는 메르센 트위스터 알고리즘보다 구현 속도가 더 빠릅니다. 주기는 2199371이고, 가능한 값은 구간 (0,1) 내에 있는 252의 배수입니다. 이 생성기는 기본적으로 (1,2)에 포함되는 배정밀도 값을 생성하고, 이러한 값은 U(0,1) 값을 생성하도록 변환됩니다. 이 생성기는 다중 스트림이나 서브스트림을 지원하지 않습니다.

mcg16807

승수 a=75, 모듈로 m=2311을 사용하는 32비트 승산식 합동법(Multiplicative Congruential) 생성기입니다([14]에 설명되어 있음). 이 생성기는 주기가 2312이며, 다중 스트림이나 서브스트림을 지원하지 않습니다. 각 U(0,1) 값은 생성기에서 단일 32비트 정수를 사용하여 생성됩니다. 가능한 값은 엄격하게 구간 (0,1) 내에 있는 모든 (2311)1의 배수입니다. mcg16807 스트림에 기본적으로 사용되는 randn 알고리즘은 극좌표 알고리즘입니다([1]에 설명되어 있음). 참고: 이 생성기는 MATLAB 버전 4부터 rand('seed',s)randn('seed',s)를 사용하여 활성화되는 rand 함수와 randn 함수에서 사용하는 생성기와 동일합니다.

mlfg6331_64

지연값(lags) l=63, k=31을 사용하는 64비트 시차 피보나치 수열(Multiplicative Lagged Fibonacci) 생성기입니다([10]에 설명되어 있음). 이 생성기는 SPRNG 패키지에 구현된 MLFG와 유사합니다. 이 생성기는 주기가 대략적으로 2124입니다. 또한, 파라미터화를 통해 최대 261개의 병렬 스트림을 지원하고, 각각 길이가 272251개의 서브스트림을 지원합니다. 각 U(0,1) 값은 생성기에서 64비트 정수 하나를 사용하여 생성됩니다. 가능한 값은 엄격하게 구간 (0,1) 내에 있는 의 모든 배수입니다. mlfg6331_64 스트림에 기본적으로 사용되는 randn 알고리즘은 지구라트 알고리즘 [7]이지만, 그 기반에는 mlfg6331_64 생성기가 있습니다.

mrg32k3a

32비트 결합 다중 재귀적(Combined Multiple Recursive) 생성기입니다([2]에 설명되어 있음). 이 생성기는 RngStreams 패키지에 구현된 CMRG와 유사합니다. 이 생성기는 주기가 2191이며, 수열 분할을 통해 각각 길이가 2127인 최대 263개의 병렬 스트림을 지원합니다. 또한, 각각 길이가 276251개의 서브스트림도 지원합니다. 각 U(0,1) 값은 생성기에서 2개의 32비트 정수를 사용하여 생성됩니다. 가능한 값은 엄격하게 구간 (0,1) 내에 있는 253의 배수입니다. mrg32k3a 스트림에 기본적으로 사용되는 randn 알고리즘은 지구라트 알고리즘 [7]이지만, 그 기반에는 mrg32k3a 생성기가 있습니다.

philox4x32_10

10회 라운드의 4x32 생성기입니다([15]에 설명되어 있음). 이 생성기는 파이스텔 구조(Feistel Network)와 정수 곱셈을 사용하며, GPU 같은 고도 병렬 시스템의 고성능을 지원하기 위해 특별히 설계되었습니다. 주기는 2193(길이가 2129인 264개 스트림)입니다.

threefry4x64_20

20회 라운드의 4x64 생성기입니다([15]에 설명되어 있음). 이 생성기는 스케인 해시 함수(Skein Hash Function)에서 스리피시 블록 암호(Threefish Block Cipher)를 비암호화 방식으로 조정한 것입니다. 주기는 2514(길이가 2258인 2256개 스트림)입니다.

shr3cong

승수(Multiplier) a=69069, 가수(Addend) b=1234567, 법수(Modulus) 232을 사용하여 선형 합동법 생성기로 계산된, 마르사글리아(Marsaglia)의 SHR3 시프트 레지스터 생성기입니다. SHR3은 u=u(I+L13)(I+R17)(I+L5)으로 정의되는 3 시프트 레지스터 생성기입니다. 여기서 I는 단위 연산자이고, L은 왼쪽 시프트 연산자이며, R은 오른쪽 시프트 연산자입니다. 결합 생성기(SHR3 부분은 [7]에 설명되어 있음)는 주기가 대략적으로 264입니다. 이 생성기는 다중 스트림이나 서브스트림을 지원하지 않습니다. 각 U(0,1) 값은 생성기에서 32비트 정수 하나를 사용하여 생성됩니다. 가능한 값은 엄격하게 구간 (0,1) 내에 있는 232의 모든 배수입니다. shr3cong 스트림에 기본적으로 사용되는 randn 알고리즘은 이전 형식의 지구라트 알고리즘 [9]이지만, 그 기반에는 shr3cong 생성기가 있습니다. 이 생성기는 MATLAB 버전 5부터 randn('state',s)를 사용하여 활성화되는 randn 함수에서 사용하는 생성기와 동일합니다.

참고

[6](1999년)에 사용된 SHR3 생성기는 [7](2000년)에 사용된 것과 다릅니다. MATLAB에서는 [7]에 나와 있는 가장 최신 버전의 생성기를 사용합니다.

swb2712

수정된 자리 내림을 사용하는 뺄셈(Subtract-with-Borrow) 생성기입니다([8]에 설명되어 있음). 이 생성기는 지연값(lags) 27과 12를 사용하는 가산식 시차 피보나치(Additive Lagged Fibonacci) 생성기와 유사하지만, 대략적으로 21492의 더 긴 주기를 갖도록 변형되었습니다. 이 생성기는 기본적으로 배정밀도로 동작하여 U(0,1) 값을 만들고, 열린 구간 (0,1) 내에 있는 모든 값이 가능합니다. swb2712 스트림에 기본적으로 사용되는 randn 알고리즘은 지구라트 알고리즘 [7]이지만, 그 기반에는 swb2712 생성기가 있습니다. 참고: 이 생성기는 MATLAB 버전 5부터 rand('state',s)를 사용하여 활성화되는 rand 함수에서 사용하는 생성기와 동일합니다.

변환 알고리즘

Inversion

표준 정규 역누적 분포 함수(Standard Normal Inverse Cumulative Distribution Function)를 균일 확률 변량에 적용하여 정규 확률 변량을 계산합니다. 정규 값당 정확히 하나의 균일 값이 사용됩니다.

Polar

극값 거부 알고리즘(Polar Rejection Algorithm)입니다([1]에 설명되어 있음). 평균적으로 정규 값당 대략 1.27개의 균일 값이 사용됩니다.

Ziggurat

지구라트 알고리즘입니다([7]에 설명되어 있음). 평균적으로 정규 값당 대략 2.02개의 균일 값이 사용됩니다.

참고 문헌

[1] Devroye, L. Non-Uniform Random Variate Generation, Springer-Verlag, 1986.

[2] L’Ecuyer, P. “Good Parameter Sets for Combined Multiple Recursive Random Number Generators”, Operations Research, 47(1): 159–164. 1999.

[3] L'Ecuyer, P. and S. Côté. “Implementing A Random Number Package with Splitting Facilities”, ACM Transactions on Mathematical Software, 17: 98–111. 1991.

[4] L'Ecuyer, P. and R. Simard. “TestU01: A C Library for Empirical Testing of Random Number Generators,” ACM Transactions on Mathematical Software, 33(4): Article 22. 2007.

[5] L'Ecuyer, P., R. Simard, E. J. Chen, and W. D. Kelton. “An Objected-Oriented Random-Number Package with Many Long Streams and Substreams.” Operations Research, 50(6):1073–1075. 2002.

[6] Marsaglia, G. “Random numbers for C: The END?” Usenet posting to sci.stat.math. 1999. Available online at https://groups.google.com/group/sci.crypt/browse_thread/
thread/ca8682a4658a124d/
.

[7] Marsaglia G., and W. W. Tsang. “The ziggurat method for generating random variables.” Journal of Statistical Software, 5:1–7. 2000. Available online at https://www.jstatsoft.org/v05/i08.

[8] Marsaglia, G., and A. Zaman. “A new class of random number generators.” Annals of Applied Probability 1(3):462–480. 1991.

[9] Marsaglia, G., and W. W. Tsang. “A fast, easily implemented method for sampling from decreasing or symmetric unimodal density functions.” SIAM J.Sci.Stat.Comput. 5(2):349–359. 1984.

[10] Mascagni, M., and A. Srinivasan. “Parameterizing Parallel Multiplicative Lagged-Fibonacci Generators.” Parallel Computing, 30: 899–916. 2004.

[11] Matsumoto, M., and T. Nishimura.“Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudorandom Number Generator.” ACM Transactions on Modeling and Computer Simulation, 8(1):3–30. 1998.

[12] Matsumoto, M., and M. Saito.“A PRNG Specialized in Double Precision Floating Point Numbers Using an Affine Transition.” Monte Carlo and Quasi-Monte Carlo Methods 2008, 10.1007/978-3-642-04107-5_38. 2009.

[13] Moler, C.B. Numerical Computing with MATLAB. SIAM, 2004. Available online at https://www.mathworks.com/moler

[14] Park, S.K., and K.W. Miller. “Random Number Generators: Good Ones Are Hard to Find.” Communications of the ACM, 31(10):1192–1201. 1998.

[15] Salmon, J. K., M. A. Moraes, R. O. Dror, and D. E. Shaw. "Parallel Random Numbers: As Easy as 1, 2, 3." In Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis (SC11). New York, NY: ACM, 2011.