Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Crear y controlar un flujo de números aleatorios

La clase le permite crear una secuencia numérica aleatoria.RandStream Esto es útil por varias razones. Por ejemplo, es posible que desee generar valores aleatorios sin afectar al estado de la secuencia global. Es posible que desee fuentes separadas de aleatoriedad en una simulación. O puede que necesite usar un algoritmo de generador diferente al que utiliza un software al iniciarse.MATLAB® Con el constructor, puede crear su propia secuencia, establecer las propiedades de escritura y usarla para generar números aleatorios.RandStream Puede controlar la secuencia que crea de la misma manera que controla la secuencia global. Incluso puede reemplazar la secuencia global con la secuencia que cree.

Para crear una secuencia, utilice el constructor.RandStream

myStream=RandStream('mlfg6331_64'); rand(myStream,1,5)  ans =      0.6530    0.8147    0.7167    0.8615    0.0764

La secuencia aleatoria actúa por separado de la secuencia global.myStream Las funciones y seguirán dibujándose desde la secuencia global y no afectarán a los resultados de los métodos y se aplicarán a.randrandnrandiRandStreamrandrandnrandimyStream

Puede hacer que la secuencia global utilice el método.myStreamRandStream.setGlobalStream

RandStream.setGlobalStream(myStream) RandStream.getGlobalStream  ans =   mlfg6331_64 random stream (current global stream)              Seed: 0   NormalTransform: Ziggurat  RandStream.getGlobalStream==myStream  ans =       1

Subtransmisiones

Es posible que desee volver a una parte anterior de una simulación. Un flujo aleatorio se puede controlar haciendo que salte a puntos de control fijos, denominados subflujos. La propiedad le permite saltar de un salto a otro entre varias subsecuencias.Substream Para utilizar la propiedad, cree una secuencia utilizando un generador que admita subsecuencias.Substream (Consulte para obtener una lista de los algoritmos de generador y sus propiedades.)Elegir un generador de números aleatorios

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

El valor inicial es 1.Substream

stream.Substream  ans =       1

Los subflujos son útiles en el cómputo en serie. Las subsecuencias pueden recrear todo o parte de una simulación volviendo a un punto de control determinado en la secuencia. Por ejemplo, se pueden usar en bucles.

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

Cada una de estas subsecuencias puede reproducir su iteración de bucle. Por ejemplo, puede volver a la 5ª subsecuencia. El resultado devolverá los mismos valores que la 5ª salida anterior.

stream.Substream=5; rand(1,5)  ans =      0.3323    0.9296    0.5767    0.1233    0.6934

Elegir un generador de números aleatorios

ofrece varias opciones de algoritmo de generador.MATLAB En la tabla siguiente se resumen las propiedades clave de los algoritmos de generador disponibles y las palabras clave utilizadas para crearlas. Para devolver una lista de todos los algoritmos de generador disponibles, utilice el método.RandStream.list

Palabra claveGeneradorCompatibilidad con varias Stream y substreamPeríodo aproximado en precisión completa
mt19937arTornado de Mersenne (utilizado por el flujo predeterminado al inicio)MATLABNo219937-1
dsfmt19937SIMD orientado rápido Twister Mersenne No219937-1
mcg16807Generador congruencial multiplicativoNo231-2
mlfg6331_64Multiplicativo rezagado generador de Fibonacci2124 (251 arroyos de longitud 272)
mrg32k3aEl generador recursivo combinado múltiple2191 (263 arroyos de longitud 2127)
philox4x32_10Generador philox 4x32 con 10 rondas2193 (264 arroyos de longitud 2129)
threefry4x64_20Threefry 4x64 generador con 20 rondas2514 (2256 arroyos de longitud 2258)
shr3congGenerador de registro de mayúsculas sumado con generador congruencial linealNo264
swb2712Resta modificado con el generador de préstamoNo21492

Los generadores, y proporcionan compatibilidad con versiones anteriores de. y están diseñados principalmente para aplicaciones secuenciales.mcg16807shr3congswb2712MATLABmt19937ardsfmt19937 Los generadores restantes proporcionan compatibilidad explícita para la generación de números aleatorios paralelos.

Dependiendo de la aplicación, algunos generadores pueden ser más rápidos o devolver valores con más precisión. Todos los generadores de números pseudoaleatorios se basan en algoritmos deterministas, y todos fallarán una prueba estadística suficientemente específica para la aleatoriedad. Una forma de comprobar los resultados de una simulación de Montecarlo es volver a ejecutar la simulación con dos o más algoritmos de generador diferentes, y la elección del software de generadores le proporcionará los medios para hacerlo.MATLAB Aunque es poco probable que sus resultados difieran por más que el error de muestreo de Montecarlo cuando se utilizan diferentes generadores, hay ejemplos en la literatura donde este tipo de validación ha convertido en defectos en un algoritmo de generador en particular (ver para un ejemplo).[13]

Algoritmos de generador

mt19937ar

El Mersenne Twister, como se describe en, tiene período[11] 2199371 y cada valor U (0, 1) se crea utilizando enteros de 2 32 bits. Los valores posibles son múltiplos de 253 en el intervalo (0,1). Este generador no admite varias secuencias o subsecuencias. El algoritmo utilizado por defecto para las transmisiones es el algoritmo zigurat, pero con el generador debajo.randnmt19937ar[7]mt19937ar Nota: Este generador es idéntico al utilizado por la función a partir de la versión 7, activada por.randMATLABrand('twister',s)

dsfmt19937

El Fast Mersenne Twister de doble precisión orientado a SIMD, como se describe en, es una implementación más rápida del algoritmo de Mersenne Twister.[12] El período es 2199371 y los valores posibles son múltiplos de 252 en el intervalo (0,1). El generador produce valores de doble precisión en [1, 2) de forma nativa, que se transforman para crear valores U (0, 1). Este generador no admite varias secuencias o subsecuencias.

mcg16807

Un generador congruencial multiplicativo de 32 bits, como se describe en, con multiplicador[14] a=75, modulo m=2311. Este generador tiene un período de 2312 y no admite varias secuencias o subsecuencias. Cada valor se crea utilizando un único entero de 32 bits del generador; los valores posibles son múltiplos deU(0,1) (2311)1 estrictamente dentro del intervalo.(0,1) El algoritmo utilizado por defecto para las secuencias es el algoritmo polar (descrito en).randnmcg16807[1] Nota: Este generador es idéntico al que se utiliza a partir de la versión 4 por ambas funciones, activadas mediante o.MATLABrandrandnrand('seed',s)randn('seed',s)

mlfg6331_64

Un 64-bit multiplicativo retraso generador de Fibonacci, como se describe en, con retrasos[10] l=63, k=31. Este generador es similar al MLFG implementado en el paquete SPRNG. Tiene un período de aproximadamente 2124. Soporta hasta 261 secuencias paralelas, mediante parametrización y 251 subtransmisiones cada uno de longitud 272. Cada valor se crea utilizando el entero de 1 64 bits del generador; los valores posibles son múltiplos deU(0,1) estrictamente dentro del intervalo (0,1). El algoritmo utilizado por defecto para las transmisiones es el algoritmo zigurat, pero con el generador debajo.randnmlfg6331_64[7]mlfg6331_64

mrg32k3a

Un generador recursivo múltiple combinado de 32 bits, como se describe en.[2] Este generador es similar al CMRG implementado en el paquete RngStreams. Tiene un período de 2191 y soporta hasta 263 flujos paralelos a través de la división de secuencia, cada uno de longitud 2127. También es compatible con 251 subflujos, cada uno de longitud 276. Cada valor se crea utilizando enteros de 2 32 bits del generador; los valores posibles son múltiplos deU(0,1) 253 estrictamente dentro del intervalo (0,1). El algoritmo utilizado por defecto para las transmisiones es el algoritmo zigurat, pero con el generador debajo.randnmrg32k3a[7]mrg32k3a

philox4x32_10

Un generador 4x32 con 10 rondas como se describe en.[15] Este generador utiliza una red Feistel y la multiplicación de enteros, y está diseñado específicamente para un alto rendimiento en sistemas altamente paralelos como las GPU. Tiene un período de 2193 (264 arroyos de longitud 2129).

threefry4x64_20

Un generador 4x64 con 20 rondas como se describe en.[15] Este generador es una adaptación no criptográfica del sistema de cifrado de bloques Threefish de la función hash de Skein. Tiene un período de 2514 (2256 arroyos de longitud 2258).

shr3cong

El generador de registro de turnos SHR3 de Marsaglia se suma a un generador congruencial lineal con multiplicador a=69069Sumando b=1234567, y módulo 232. SHR3 es un generador de registro de 3 turnos definido como u=u(I+L13)(I+R17)(I+L5)Dónde I es el operador de identidad, L es el operador de desplazamiento a la izquierda y es el operador de desplazamiento correcto.R El generador combinado (la parte SHR3 se describe en) tiene un período de aproximadamente[7] 264. Este generador no admite varias secuencias o subsecuencias. Cada valor U (0,1) se crea utilizando un entero de 1 32 bits del generador; los valores posibles son múltiplos de 232 estrictamente dentro del intervalo (0,1). El algoritmo utilizado por defecto para las secuencias es la forma anterior del algoritmo zigurat, pero con el generador debajo.randnshr3cong[9]shr3cong Este generador es idéntico al utilizado por la función a partir de la versión 5, activada utilizando.randnMATLABrandn('state',s)

Nota

El generador SHR3 utilizado en (1999) difiere del utilizado en (2000). utiliza la versión más reciente del generador, presentada en.[6][7]MATLAB[7]

swb2712

Un generador de restar con préstamo modificado, como se describe en.[8] Este generador es similar a un aditivo rezagado generador de Fibonacci con retrasos 27 y 12, pero se modifica para tener un período mucho más largo de aproximadamente 21492. El generador funciona de forma nativa con doble precisión para crear valores U (0,1), y todos los valores en el intervalo abierto (0,1) son posibles. El algoritmo utilizado por defecto para las transmisiones es el algoritmo zigurat, pero con el generador debajo.randnswb2712[7]swb2712 Nota: Este generador es idéntico al utilizado por la función Rand a partir de la versión 5, activada utilizando.MATLABrand('state',s)

Algoritmos de transformación

Inversion

Calcula un variado aleatorio normal aplicando la función de distribución acumulativa inversa normal estándar a un variado aleatorio uniforme. Se consume exactamente un valor uniforme por valor normal.

Polar

El algoritmo de rechazo polar, como se describe en.[1] Se consumen aproximadamente 1,27 valores uniformes por valor normal, en promedio.

Ziggurat

El algoritmo zigurat, como se describe en.[7] Se consumen aproximadamente 2,02 valores uniformes por valor normal, en promedio.

Referencias

[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.