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.
La clase RandStream
le permite crear una secuencia de números aleatorios. Esto resulta útil por varias razones. Por ejemplo, si quiere generar valores aleatorios sin que afecte al estado de la secuencia global. Puede que en una simulación le interese separar las fuentes de aleatoriedad. O puede que necesite utilizar un algoritmo de generación diferente al que utiliza el software de MATLAB® al iniciarse. Con el constructor RandStream
puede crear su propia secuencia, establecer las propiedades grabables y utilizarlas para generar números aleatorios. Puede controlar la secuencia que cree de la misma manera que controla la secuencia global. Incluso puede sustituir la secuencia global por 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 myStream
actúa de forma independiente a la secuencia global. Las funciones rand
, randn
y randi
seguirán extrayendo de la secuencia global y no afectarán a los resultados de los métodos RandStream
rand
, randn
y randi
aplicados a myStream
.
Puede hacer que myStream
sea la secuencia global con el método RandStream.setGlobalStream
.
RandStream.setGlobalStream(myStream) RandStream.getGlobalStream ans = mlfg6331_64 random stream (current global stream) Seed: 0 NormalTransform: Ziggurat RandStream.getGlobalStream==myStream ans = 1
Puede que desee volver a una parte anterior de una simulación. Una secuencia aleatoria se puede controlar haciendo que salte a puntos de control fijos, llamados subsecuencias. La propiedad Substream
le permite saltar hacia delante y hacia atrás entre subsecuencias múltiples. Para utilizar la propiedad Substream
, cree una secuencia con un generador que admita subsecuencias. (Consulte Elegir un generador de números aleatorios para obtener una lista de algoritmos de generación y sus propiedades).
stream=RandStream('mlfg6331_64'); RandStream.setGlobalStream(stream)
El valor inicial de Substream
es 1.
stream.Substream ans = 1
Las subsecuencias son útiles en cálculos de serie. Las subsecuencias pueden recrear una simulación completa o parte de ella regresando a un punto de control particular de una 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 quinta subsecuencia. El resultado devolverá los mismos valores que la quinta salida anterior.
stream.Substream=5; rand(1,5) ans = 0.3323 0.9296 0.5767 0.1233 0.6934
MATLAB ofrece varias opciones de algoritmos de generación. La siguiente tabla resume las propiedades esenciales de los algoritmos de generación y las palabras clave que se usan para crearlos. Para recuperar una lista de todos los algoritmos de generación disponibles, utilice el método RandStream.list
.
Palabra clave | Generador | Soporte de secuencias y subsecuencias múltiples | Periodo aproximado con plena precisión |
---|---|---|---|
mt19937ar | Mersenne twister (se utiliza de forma predeterminada al iniciar MATLAB) | No | 219937-1 |
dsfmt19937 | Mersenne twister rápido orientado a SIMD | No | 219937-1 |
mcg16807 | Generador congruencial multiplicativo | No | 231-2 |
mlfg6331_64 | Generador de Fibonacci retardado multiplicativo | Sí | 2124 (251 secuencias de longitud 272) |
mrg32k3a | Generador combinado múltiple recursivo | Sí | 2191 (263 secuencias de longitud 2127) |
philox4x32_10 | Generador Philox 4x32 con 10 rondas | Sí | 2193 (264 secuencias de longitud 2129) |
threefry4x64_20 | Generador Threefry 4x64 con 20 rondas | Sí | 2514 (2256 secuencias de longitud 2258) |
shr3cong | Generador de registro de desplazamientos sumado a un generador lineal congruencial | No | 264 |
swb2712 | Generador modificado de resta con préstamo | No | 21492 |
Los generadores mcg16807
, shr3cong
y swb2712
son compatibles con versiones anteriores de MATLAB. mt19937ar
y dsfmt19937
están diseñados principalmente para aplicaciones secuenciales. Los generadores restantes proporcionan soporte específico para la generación de números aleatorios paralela.
Según la aplicación, puede que ciertos generadores sean más rápidos o devuelvan valores con mayor precisión. Todos los generadores de números seudoaleatorios se basan en algoritmos deterministas y todos fallarán en una prueba suficientemente específica de aleatoriedad. Una forma de comprobar los resultados de la simulación Monte Carlo es volver a ejecutar la simulación con dos o más algoritmos de generación; la oferta de generadores que le ofrece MATLAB le permite hacerlo. Aunque al usar generadores diferentes es poco probable que los resultados difieran en más de un error de muestra de Monte Carlo, en la literatura hay ejemplos en los que este tipo de validación ha dado lugar a fallos en un algoritmo de generación concreto (consulte [13] para obtener un ejemplo).
mt19937ar
El Mersenne twister, como se describe en [11], tiene periodo y cada valor U(0,1) se crea con números enteros de 32 bits. Los posibles valores son múltiplos de en el intervalo (0,1). Este generador no es compatible con secuencias ni subsecuencias múltiples. El algoritmo randn
que se utiliza de forma predeterminada para las secuencias mt19937ar
es el algoritmo zigurat [7], pero con el generador mt19937ar
debajo. Nota: Este generador es idéntico al que utiliza la función rand
a partir de la Versión 7 de MATLAB, que se activa con rand('twister',s)
.
dsfmt19937
El Mersenne twister rápido orientado a SIMD de precisión doble, como se describe en [12], es una implementación más rápida del algoritmo Mersenne twister. El periodo es y los posibles valores son múltiplos de en el intervalo (0,1). De forma nativa, el generador produce valores de precisión doble en [1,2), que se transforman para crear valores U(0,1). Este generador no es compatible con secuencias ni subsecuencias múltiples.
mcg16807
Un generador congruencial multiplicativo de 32 bits, como se describe en [14], con multiplicador , módulo . Este generador tiene un periodo de y no admite secuencias ni subsecuencias múltiples. Cada valor U(0,1)
se crea con un número entero de 32 bits a partir del generador, los valores posibles son múltiplos de estrictamente dentro del intervalo (0,1)
. El algoritmo randn
que se utiliza de forma predeterminada para las secuencias mcg16807
es el algoritmo polar (que se describe en [1]). Nota: Este generador es idéntico al que usan las funciones rand
y randn
a partir de la Versión 4 de MATLAB, que se activa con rand('seed',s)
o con randn('seed',s)
.
mlfg6331_64
Un generador de Fibonacci retardado multiplicativo de 64 bits, como se describe en [10], con retardos , . Este generador es similar al MLFG implementado en el paquete SPRNG. Tiene un periodo de aproximadamente . Admite hasta secuencias paralelas, a través de la parametrización, y subsecuencias, cada una de longitud . Cada valor U(0,1)
se crea con un número entero de 64 bits a partir del generador; los valores posibles son múltiplos de estrictamente dentro del intervalo (0,1). El algoritmo randn
que se utiliza de forma predeterminada para las secuencias mlfg6331_64
es el algoritmo zigurat [7], pero con el generador mlfg6331_64
debajo.
mrg32k3a
Un generador combinado múltiple recursivo de 32 bits, como se describe en [2]. Este generador es similar a CMRG implementado en el paquete RngStreams. Tiene un periodo de hasta y admite hasta secuencias paralelas, a través de la parametrización, cada una de longitud . También admite subsecuencias, cada una de una longitud . Cada valor U(0,1)
se crea con dos números enteros de 32 bits a partir del generador; los valores posibles son múltiplos de estrictamente dentro del intervalo (0,1). El algoritmo randn
que se utiliza de forma predeterminada para las secuencias mrg32k3a
es el algoritmo zigurat [7], pero con el generador mrg32k3a
debajo.
philox4x32_10
Un generador 4 por 32 con 10 rondas, como se describe en [15]. Este generador utiliza una red Feistel y multiplicación de números enteros, y está específicamente diseñado para alto rendimiento en sistemas altamente paralelos como las GPU. Tiene un periodo de 2193 (264 secuencias de longitud 2129).
threefry4x64_20
Un generador 4 por 64 con 20 rondas, como se describe en [15]. Este generador es una adaptación no criptográfica del cifrado de bloque Threefish a partir de la función hash Skein. Tiene un periodo de 2514 (2256 secuencias de longitud 2258).
shr3cong
El generador SHR3 de Marsaglia de registro de desplazamientos sumado a un generador lineal congruencial con multiplicador , sumando y módulo . SHR3 es un generador de registro de 3 desplazamientos definido como , donde es el operador de identidad, es el operador de desplazamiento hacia la izquierda y R es el operador de desplazamiento hacia la derecha. El generador combinado (la parte SHR3 se describe en [7]) tiene un periodo de aproximadamente . Este generador no es compatible con secuencias ni subsecuencias múltiples. Cada valor U(0,1) se crea con el número entero de 32 bits del generador; los valores posibles son todos los múltiplos de estrictamente dentro del intervalo (0,1). El algoritmo randn
que se utiliza por defecto para las secuencias shr3cong
es la forma más temprana del algoritmo zigurat [9], pero con el generador shr3cong
debajo. Este generador es idéntico al que utiliza la función randn
a partir de la Versión 5 de MATLAB, que se activa con randn('state',s)
.
swb2712
Un generador modificado de resta con préstamo, como se describe en [8]. Este generador es similar a un generador de Fibonacci retardado sumativo con retardos 27 y 12, pero está modificado para que tenga un periodo mucho más largo de aproximadamente . El generador funciona de forma nativa con precisión doble para crear valores U(0,1) y son posibles todos los valores en el intervalo abierto (0,1). El algoritmo randn
que se utiliza de forma predeterminada para las secuencias swb2712
es el algoritmo zigurat [7], pero con el generador swb2712
debajo. Nota: Este generador es idéntico al que utiliza la función rand a partir de la Versión 5 de MATLAB, que se activa con rand('state',s)
.
Inversion
Computa una variación aleatoria normal aplicando la función de distribución acumulativa inversa normal estándar a una variación aleatoria uniforme. Cada valor normal consume exactamente un valor uniforme.
Polar
El algoritmo polar de rechazo, como se describe en [1]. De media, cada valor normal consume aproximadamente 1,27 valores uniformes.
Ziggurat
El algoritmo zigurat, como se describe en [7]. De media, cada valor normal consume aproximadamente 2,02 valores uniformes.
[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.