2013-04-14 17 views
10

私は++ 11 <random>良くcを知ってもらうことにしましたので、私はそのようなコードを書いた:std :: piecewise_linear_distributionは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'; 

何らかの理由std::random_deviceためColiruでは動作しないようですので、私が代わりにconstのサンプルシードに入りました。私はそれがURだから、IIRCであることを前提としています。それはハードウェアに大きく依存しています。それがColiruでサポートされていない理由です。イデアーンでは、しかし、それは動作します。

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

それはColiruに完全に正しい動作しますが、私は、コンパイル時にVS2012、the output is just wrong上でそれを実行します。

は、それから私は、唯一の違いは std::roundの独自の実装であること、それはVS2012上で実行するように移植しました。

これを修正する方法、さらに重要なのは、どうして起こるのか? 私は何か遅れを取っていますか、またはVS2012はここのスマートなものではありませんか?

+1

['std :: round'](http://en.cppreference.com/w/cpp/numeric/math/round)が宣言されている「」ヘッダー、FYIにあります。私はそれがあなた自身のバージョンを書いた理由です(コンパイラはそれを見つけることができませんでした)。 –

+0

''をインクルードしても、エラーが出ます: 'round':' std'のメンバーではありません。 – Wierzba

答えて

7

これはVisual Studioの問題と思われます。私は以下のプログラムを試してみました(OPから適合しました).GCC 4.7.2、Clang 3.2、Intel 13.1.0で生成された出力は非常に妥当ですが、Visual Studio 11 2012 CTPで生成された出力は全く異なります。

確率密度は区分的に線形であり、配列xとpによって次のように定義されます。 i = 0、...、N(N = x.size()-1)に対して点(x [i]、p [i])を結ぶ区分線形関数が構築される。次に、この関数を(積分で除算することによって)正規化し、確率密度を得る。

#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; 
} 

この例では、多角形関数は(0、0)、(20,1)、(40,0)を接続しています。したがって、その形状は底40と高さ1の二等辺三角形であり、20の面積が得られます。したがって、確率密度fは(0、0)、(20,1/20)、(40,0)を結びます。これは、区間[20,21 [f(20)*(21 - 20)= 1/20 * 1 = 1/20程度の抽選結果を期待できることを意味する。合計で200,000の値を引き、それから、[20、21 [。

GCC、クランとインテルレポート9734ポイント21、20 [で[と二等辺三角形と非常によく似ているパターンを表示:

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 

残念ながら、Visual Studioの2012年11月CTPはこれを与える:

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 

注:

  1. 私はより良い表示するための切り捨てVisual Studioの出力をしました。
  2. [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

あなたのプログラムの視覚的な出力が、 "ビジョン"とは何かを持つと主張する唯一のツールチェーンの出力で壊れることは皮肉なことです! –

+2

ああ、ライブラリのバグです。それはMSに提出する必要があります。 –

+0

さて、これは私が悪い、悪い人ではないことを落ち着かせる。わーい。 gccのC++ 11のものを今からしかコーディングするつもりはありません。 Microsoftに提出されました。 – Wierzba

関連する問題