2

I am sampling random numbers from normal distribution using the following code snippet under both Visual Studio 2012 (TC: 11.0) and Visual Studio 2017 (TC: 14.1):

#include "stdafx.h"

#include <iostream>
#include <random>
#include <cmath>

int main()
{
    std::mt19937 e1;
    std::mt19937 e2;
    std::normal_distribution<> normal_dist(0, 1);

    for (int n = 0; n<10; ++n) {
        std::cout << "seq=" << e1();
        std::cout << "; PRN=" << normal_dist(e2);
        std::cout << std::endl;
    }

    return 0;
}

Under VS12 (TC: 11.0) I receive the following results:

seq=3499211612; PRN=0.253161
seq=581869302; PRN=-0.293219
seq=3890346734; PRN=0.0845901
seq=3586334585; PRN=-0.0570855
seq=545404204; PRN=0.992328
seq=4161255391; PRN=-1.43822
seq=3922919429; PRN=-0.910655
seq=949333985; PRN=0.106847
seq=2715962298; PRN=-0.600247
seq=1323567403; PRN=-0.844453

Likewise, under VS17 (TC: 14.1) I get

seq=3499211612; PRN=-0.146382
seq=581869302; PRN=0.13453
seq=3890346734; PRN=-1.87138
seq=3586334585; PRN=0.46065
seq=545404204; PRN=-0.214253
seq=4161255391; PRN=0.163712
seq=3922919429; PRN=-0.827944
seq=949333985; PRN=0.298595
seq=2715962298; PRN=1.05547
seq=1323567403; PRN=0.0102154

As I understand the sequence generation is tool chain independent, whereas the normal distribution sampling is not. What is the reason for this tool chain-dependency?

Many thanks in advance!

ff112358
  • 51
  • 5

1 Answers1

3

Apparently Microsoft changed some implementations in the random include. When drawing random numbers from a distribution at some point a uniform distribution sample is required. Under toolchain 14.1 the code for this task is:

_NRAND(_Eng, _Ty)

As I discovered, toolchains 11.0 of Visual Studio 2012 and 14.1 of Visual Studio 2017 exhibit different implementations for the macro _NRAND. The purpose of this macro is to map the sequence of integer values drawn from the PRN engine _Eng onto the interval [0, 1). The implementational difference is as follows:

  • Under Visual Studio 2012 each value of the sequence is rescaled in a straight forward fashion by substracting the sequence's minimum value and dividing by the difference of its maximum and minimum value.
  • Under Visual Studio 2017 _NRAND calls the function generate_canonical. For details on the implementation see line 282 ff in random. What it actually does is to calculate some kind of polynomial average on multiple rescaled elements of the sequence.
ff112358
  • 51
  • 5