2013-04-14 6 views
10

ho deciso di conoscere C++ 11 <random> meglio, così ho scritto un tale codice:std :: piecewise_linear_distribution non funziona con VS2012?

std::mt19937 gen(10); 
std::piecewise_linear_distribution<> d(Range.begin(), Range.end(), 
             RangeValues.begin()); 

std::map<int, unsigned int> hist; 
for (int n = 0; ++n != iterations;) 
    ++hist[std::round(d(gen))]; 

for (auto p : hist) 
    std::cout << std::setw(2) << p.first << ": " 
      << std::string(p.second/(iterations/200), '*') << '\n'; 

Per qualche ragione std::random_device sembra non funzionare su Coliru, così mi è entrato un seme di esempio const invece. Presumo, che sia UB quindi IIRC è basato pesantemente sull'hardware, ed è per questo che non è supportato su Coliru (correggimi se sbaglio). Su Ideone funziona comunque.

Poi ho portato a girare su VS2012, l'unica differenza è una propria implementazione di std::round:

return number < 0.0 ? std::ceil(number - 0.5) : std::floor(number + 0.5); 

Funziona perfettamente corretta Coliru, ma quando ho compilare ed eseguire su VS2012, the output is just wrong.

Qualche idea su come correggere questo e, cosa più importante, perché succede? Sto facendo qualcosa di ritardato, o VS2012 non è quello intelligente qui?

+1

[ 'std :: round'] (http://en.cppreference.com/w/cpp/numeric/math/round) è dichiarato nell'intestazione '', FYI. Presumo che sia per questo che hai scritto la tua versione (il compilatore non è riuscito a trovarla). –

+0

No. Anche quando includo '', viene visualizzato un errore: 'round': non è un membro di' std'. – Wierzba

risposta

7

Sembra che questo sia un problema di Visual Studio. Ho provato il programma seguente (adattato dall'OP) e l'output generato da GCC 4.7.2, Clang 3.2 e Intel 13.1.0 è molto ragionevole mentre quello generato da Visual Studio Nov 2012 CTP è completamente diverso.

La densità di probabilità è lineare a tratti e definita dagli array x e p nel modo seguente. Una funzione lineare a tratti che collega i punti (x [i], p [i]) per i = 0, ..., N (dove N = x.size() - 1) è costruito. Quindi questa funzione è normalizzata (dividendolo per il suo integrale) per ottenere la densità di probabilità.

#include <iostream> 
#include <iomanip> 
#include <string> 
#include <random> 
#include <array> 

int main() { 

    std::mt19937 gen(10); 

    std::array<double, 3> x = {{0, 20, 40}}; 
    std::array<double, 3> p = {{0, 1, 0}}; 
    std::piecewise_linear_distribution<> dist(x.begin(), x.end(), p.begin()); 

    std::array<int, 40> hist = {{0}}; 

    for (size_t i = 0; i < 200000; ++i) 
     ++hist[static_cast<size_t>(dist(gen))]; 

    for (size_t n = 0; n < hist.size(); ++n) 
     std::cout << std::setfill('0') << std::setw(2) << n << ' ' << 
      std::string(hist[n]/200, '*') << std::endl; 

    std::cout << "\nValues in interval [20, 21[ : " << hist[20] << std::endl; 
} 

Nel nostro esempio, la funzione poligonale comunicazione (0, 0), (20, 1) e (40, 0). Quindi, la sua forma è un triangolo isoscele con base 40 e altezza 1 che produce un'area di 20. Pertanto, la densità di probabilità f collega (0, 0), (20, 1/20) e (40, 0). Ciò implica che nell'intervallo [20, 21 [potremmo aspettarci intorno a f (20) * (21 - 20) = 1/20 * 1 = 1/20 risultati del sorteggio. In totale peschiamo 200.000 valori e quindi possiamo aspettarci circa 10.000 punti in [20, 21 [.

GCC, clang e Intel rapporto 9734 punti in [20, 21 [e visualizzare un modello che è molto simile a un triangolo isoscele:

00 * 
01 *** 
02 ***** 
03 ******** 
04 *********** 
05 ************** 
06 *************** 
07 ****************** 
08 ******************** 
09 ************************ 
10 ************************** 
11 **************************** 
12 ******************************* 
13 ********************************* 
14 *********************************** 
15 *************************************** 
16 ***************************************** 
17 ****************************************** 
18 ********************************************** 
19 ************************************************ 
20 ************************************************ 
21 ********************************************* 
22 ******************************************* 
23 ***************************************** 
24 ************************************** 
25 ************************************ 
26 ********************************** 
27 ****************************** 
28 **************************** 
29 ************************** 
30 *********************** 
31 ******************** 
32 ****************** 
33 **************** 
34 ************* 
35 *********** 
36 ********* 
37 ****** 
38 *** 
39 * 

Values in interval [20, 21[ : 9734 

Purtroppo, Visual Studio Nov 2012 CTP dà questo:

00 ********************************************** [truncated] 
01 ********************************************** 
02 *********************************** 
03 ***************************** 
04 ************************** 
05 *********************** 
06 ********************* 
07 ******************** 
08 ******************* 
09 ****************** 
10 ***************** 
11 **************** 
12 *************** 
13 ************** 
14 ************** 
15 ************** 
16 ************* 
17 ************* 
18 ************* 
19 ************ 
20 ************ 
21 ************* 
22 ************* 
23 ************* 
24 ************* 
25 ************** 
26 *************** 
27 *************** 
28 **************** 
29 ***************** 
30 ****************** 
31 ******************* 
32 ******************* 
33 ********************* 
34 *********************** 
35 ************************** 
36 ***************************** 
37 *********************************** 
38 ********************************************** 
39 ********************************************** [truncated] 

Values in interval [20, 21[ : 2496 

Note:

  1. ho troncato Visual Studio uscita per una migliore visualizzazione.
  2. Una stima migliore per il numero di punti in [20, 21 [è 200.000 * (0,5 * (f (20) + f (21))) * (21 - 20) = 100.000 * (1/20 + 1/20 - 1/400) = 10.000 - 250 = 9750.
+3

Ironico che l'output visivo del programma venga interrotto nell'output dell'unica toolchain che pretende di avere qualcosa a che fare con la "visione" di qualsiasi tipo! –

+2

Aha, quindi bug della biblioteca. Questo dovrebbe essere presentato alla SM. –

+0

Beh, questo stabilisce che non sono una persona cattiva, cattiva. Sìì. Gonna code C++ 11 cose su gcc solo da ora in poi. inoltrato a Microsoft. – Wierzba

Problemi correlati