C ++ TR1: come utilizzare il normal_distribution?
-
12-09-2019 - |
Domanda
che sto cercando di utilizzare le C ++ STD TechnicalReport1 le estensioni per generare numeri a seguito di una distribuzione normale, ma questo codice (adattato da questo articolo ):
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;
}
stampa solo 1 "Generazione ..." log dei messaggi, quindi non esce dal ciclo for ! Se uso la distribuzione ho commentato invece fuori, termina, quindi mi chiedo che cosa sto facendo male. Qualche idea?
Grazie mille!
Soluzione
Questo sicuramente non sarebbe appendere il programma. Ma, non so se davvero soddisfa le vostre esigenze.
#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);
}
Altri suggerimenti
Ho avuto lo stesso problema con il codice originariamente pubblicato e studiato l'implementazione GNU di
Per prima alcune osservazioni: con g ++ - 4.4 e utilizzando il codice si blocca, con g ++ - 4.5 e utilizzando -std = C ++ 0x (vale a dire non TR1, ma la cosa vera) di cui sopra codice lavori
secondo me, c'è stato un cambiamento tra il TR1 e C ++ 0x per quanto riguarda gli adattatori tra generazione di numeri casuali e il consumo di numeri casuali - mt19937 produce interi, normal_distribution consuma doppie
il C ++ 0x utilizza adattamento automatico, il codice TR1 g ++ non
al fine di ottenere il codice di lavoro con g ++ - 4.4 e TR1, effettuare le seguenti operazioni
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();
Se la vostra applicazione TR1 generazione di numeri casuali è bacato, è possibile evitare TR1 scrivendo il proprio generatore normale come segue.
Genera due uniformi (0, 1) campioni casuali U e V utilizzando qualsiasi generatore casuale di fiducia. Poi lasciate r = sqrt (-2 log (u)) e ritorno x = r sin (2 pi v). (Questo è chiamato il metodo di Box-Mueller.)
Se avete bisogno di campioni normali campioni con media mu e deviazione standard sigma, tornare sigma * x + mu invece di solo x.
Anche se questo sembra essere un bug, una conferma rapida sarebbe quella di passare il valore predefinito 0.0, 1.0 parametri. normal_distribution<double>::normal_distribution()
deve essere uguale normal_distribution<double>::normal_distribution(0.0, 1.0)