如何了解某个标准C++函数的实现细节?

ztmd8pv5  于 2023-01-18  发布在  其他
关注(0)|答案(3)|浏览(166)

让我们看一下std::normal_distribution的例子。
我知道有一些算法可以从正态分布中进行采样(参考:Wikipedia)。而且我知道标准规范通常留给实现来选择算法(参考:SO)。
但有时需要在引擎盖下指定使用的是哪种算法,如何找出实现的细节?
(我承认,我不太了解目前存在的C++标准库的不同实现,大多数情况下,我使用的是XCode/clang、gcc和MSVC附带的实现。)

bpsygsoo

bpsygsoo1#

有时候,一个实用程序的行为是由标准明确定义的,有时候则不是。
1.看标准;如果找到,它是严格符合和便携式。
1.如果没有指定或明确定义实现,请查看您选择的标准库实现。源代码将对此进行解释。
不幸的是,它是由实现定义的,并且不可移植。如果由POSIX或类似的东西指定,你可以再次使用,但只适用于符合POSIX或"类似的东西"的平台。
下面是一个例子:
C++14标准草案N4296在§ 26.5.8.5.1中指出:
normal_distribution随机数分布产生根据概率密度函数分布的随机数x

分布参数µσ也称为该分布的平均值和标准差。
我不知道PRNG,所以我不能解释这个公式给你,但我认为这是你一直在寻找的东西。
这里有一个函数(更具体地说:一个"概率密度函数"),用于使用正态分布计算随机数。整个算法围绕此构建,可以在相应的标准库实现中找到。

vdgimpew

vdgimpew2#

我不得不写一个Wrapper类,如下所示:

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

来反省一下编译器是如何实现normal_distribution的。
为了看到它的实际效果,你必须沿着下面的思路写一些东西:

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

迭代地调用dis(gen);可能是有益的

ux6nzvsh

ux6nzvsh3#

正态分布见此处
核心逻辑是

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;

相关问题