normanius
normanius

Reputation: 9842

How to find out the implementation details for a certain standard C++ function?

Let's look for example at std::normal_distribution.

I know that there is a handful of algorithms to sample from a normal distribution (reference: Wikipedia). And I know that the standard specification usually leaves it to the implementation to choose the algorithm (reference: SO).

However, it is sometimes required to specify which algorithm is in use under the hood. How to find out the details about the implementation?

(I admit that I don't know much about the different implementations of the C++ standard library that exist in this world. Mostly, I'm using the ones shipped with XCode/clang, gcc and MSVC.)

Upvotes: 2

Views: 714

Answers (3)

Sam P
Sam P

Reputation: 721

Normal Distribution is found here

Core logic is

        uniform_real_distribution<result_type> _Uni(-1, 1);
        result_type __u;
        result_type __v;
        result_type __s;
        do
        {
            __u = _Uni(__g);
            __v = _Uni(__g);
            __s = __u * __u + __v * __v;
        } while (__s > 1 || __s == 0);
        result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
        __v_ = __v * _Fp;
        __v_hot_ = true;
        _Up = __u * _Fp;

Upvotes: 0

jimifiki
jimifiki

Reputation: 5544

I had to write a Wrapper class like this:

struct Generator{
  Generator() : val(0), count(0) {}
  Generator(std::mt19937&& aGen) : val(0), count(0), theGen(aGen) {}
  long long int operator()(void){
    val = theGen();
    std::cout << val << " " << count << std::endl;
    ++count;
    return val;
  }
  long long int max(){return theGen.max();};
  long long int min(){return theGen.min();};
  long long int val;
  size_t count;
  std::mt19937 theGen;
}; 

to get some introspection on how my compiler implements normal_distribution.

In order to see it in action you have to write something along these lines:

std::normal_distribution<> dis(1.0, 2.0);
Generator gen(std::mt19937 (42));
dis(gen);

calling iteratively dis(gen); could be instructive

Upvotes: 0

cadaniluk
cadaniluk

Reputation: 15229

Sometimes a utility's behavior is explicitly defined by the standard, sometimes it's not.

  1. Look in the standard; if found, it's strictly-conforming and portable. Yoohay!
  2. If not specified or explicitly implementation-defined, look into the standard library implementation of your choice. The source code will explain it.
    Unfortunately it's implementation-defined and unportable then. If specified by POSIX or something similar, yoohay again, but only for POSIX-conforming or "something similar"-conforming platforms.

Here's an example:

The C++14 standard draft N4296 says in §26.5.8.5.1:

A normal_distribution random number distribution produces random numbers x distributed according to the probability density function

formula

The distribution parameters µ and σ are also known as this distribution's mean and standard deviation.

I have no idea about PRNG, so I cannot explain this formula to you but I think this is the thing you were looking for.

There you have a function (more specifically: a "probability density function") for calculating random numbers using normal distribution. The whole algorithm builds around this and can be found in the corresponding standard library implementation.

Upvotes: 1

Related Questions