2009-07-13 11 views
9

estoy tratando de utilizar los C++ ETS TechnicalReport1 extensiones para generar números siguientes de una distribución normal, pero este código (adaptado de this article): sóloC++ TR1: cómo usar la distribución_normal?

mt19937 eng; 
eng.seed(SEED); 

normal_distribution<double> dist; 
// XXX if I use the one below it exits the for loop 
// uniform_int<int> dist(1, 52); 

for (unsigned int i = 0; i < 1000; ++i) { 
    cout << "Generating " << i << "-th value" << endl; 
    cout << dist(eng) << endl; 
} 

impresiones 1 "Generar ..." mensaje de registro , entonces nunca sale del bucle for! Si utilizo la distribución que comenté en su lugar, termina, entonces me pregunto qué estoy haciendo mal. ¿Alguna idea?

¡Muchas gracias!

Respuesta

2

Esto definitivamente no colgaría el programa. Pero no estoy seguro de si realmente satisface tus necesidades.

#include <random> 
#include <iostream> 

using namespace std; 

typedef std::tr1::ranlux64_base_01 Myeng; 

typedef std::tr1::normal_distribution<double> Mydist; 

int main() 
{ 
     Myeng eng; 
     eng.seed(1000); 
     Mydist dist(1,10); 

     dist.reset(); // discard any cached values 
     for (int i = 0; i < 10; i++) 
     { 
      std::cout << "a random value == " << (int)dist(eng) << std::endl; 
     } 

return (0); 
} 
+0

gracias, funciona como un amuleto, pero me pregunto por qué con este motor funciona, y no con el otro ... – puccio

+0

Obviamente, la única diferencia es que usas el generador de números mt19937 mientras que Jagannath usa std :: tr1 :: ranlux64_base_01. Lógicamente, creo que el error puede estar en la implementación del objeto mt19937 (algo del que nunca antes había oído hablar, por ejemplo :-)) que no forma parte de la biblioteca std. –

+0

¿Es posible vectorizar un bucle for para dibujar números aleatorios? Recuerdo que no se puede vectorizar un ciclo que tiene una llamada de función. – Lindon

1

Si bien esto parece ser un error, una confirmación rápida sería pasar los parámetros predeterminados de 0.0, 1.0. normal_distribution<double>::normal_distribution() debería ser igual a normal_distribution<double>::normal_distribution(0.0, 1.0)

+0

no funciona bien , todavía permanece atascado realizando el primer cálculo ... – puccio

2

Si su aplicación TR1 generación de números aleatorios está libre de errores, puede evitar TR1 escribiendo su propio generador normal de la siguiente.

Genera dos muestras aleatorias uniformes (0, 1) uv usando cualquier generador aleatorio en el que confíes. Luego, deje r = sqrt (-2 log (u)) y devuelva x = r sin (2 pi v). (Esto se llama método Box-Mueller).

Si necesita muestras de muestras normales con media mu y desviación estándar sigma, devuelva sigma * x + mu en lugar de solo x.

+1

no use Box Muller. –

+0

Box Müller es lento – Lindon

+0

Acabo de probar esto. Funciona muy rápido - probado con muestras de 1M y presenta estadísticas casi perfectas para muestras dentro de 1-sigma, 2-sigma, etc. –

7

he tenido el mismo problema con el código originalmente publicado e investigado la implementación GNU de

primero algunas observaciones: con g ++ - 4.4 y utilizando los bloqueos de código, con g ++ - 4,5 y el uso de -std = C++ 0x (es decir, no TR1, pero la realidad) código anterior funciona

En mi humilde opinión, hubo un cambio entre TR1 y C++ 0x con respecto a los adaptadores entre la generación de números aleatorios y el consumo de números aleatorios - mt19937 produce números enteros, normal_distribution consume los dobles

el C++ 0x utiliza adaptación de forma automática, el código g ++ TR1 no se

con el fin de obtener su código de trabajo con g ++ - 4.4 y TR1, haga lo siguiente

std::tr1::mt19937 prng(seed); 
std::tr1::normal_distribution<double> normal; 
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal); 
double r = randn(); 
Cuestiones relacionadas