【问题标题】:Bug in the C++ standard library in std::poisson_distribution?std::poisson_distribution 中的 C++ 标准库中的错误?
【发布时间】:2018-05-15 03:38:52
【问题描述】:

我认为我在 C++ 标准库中遇到了 std::poisson_distribution 的错误行为。

问题:

  1. 您能否确认这确实是一个错误而不是我的错误?
  2. poisson_distribution 函数的标准库代码到底有什么问题,假设它确实是一个错误?

详情:

以下 C++ 代码(文件 poisson_test.cc)用于生成泊松分布数:

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

int main() {
  // The problem turned out to be independent on the engine
  std::mt19937_64 engine;

  // Set fixed seed for easy reproducibility
  // The problem turned out to be independent on seed
  engine.seed(1);
  std::poisson_distribution<int> distribution(157.17);

  for (int i = 0; i < 1E8; i++) {
    const int number = distribution(engine);
    std::cout << number << std::endl;
  }
}

我将这段代码编译如下:

clang++ -o poisson_test -std=c++11 poisson_test.cc
./poisson_test > mypoisson.txt

以下python脚本用于分析mypoisson.txt文件中的随机数序列:

import numpy as np
import matplotlib.pyplot as plt

def expectation(x, m):
    " Poisson pdf " 
    # Use Ramanujan formula to get ln n!
    lnx = x * np.log(x) - x + 1./6. * np.log(x * (1 + 4*x*(1+2*x))) + 1./2. * np.log(np.pi)
    return np.exp(x*np.log(m) - m - lnx)

data = np.loadtxt('mypoisson.txt', dtype = 'int')

unique, counts = np.unique(data, return_counts = True)
hist = counts.astype(float) / counts.sum()
stat_err = np.sqrt(counts) / counts.sum()
plt.errorbar(unique, hist, yerr = stat_err, fmt = '.', \
             label = 'Poisson generated \n by std::poisson_distribution')
plt.plot(unique, expectation(unique, expected_mean), \
         label = 'expected probability \n density function')
plt.legend()
plt.show()

# Determine bins with statistical significance of deviation larger than 3 sigma
deviation_in_sigma = (hist - expectation(unique, expected_mean)) / stat_err
d = dict((k, v) for k, v in zip(unique, deviation_in_sigma) if np.abs(v) > 3.0)
print d

脚本产生以下情节:

您可以用肉眼看到问题。 n = 158 处的偏差具有统计显着性,实际上是 22σ 偏差!

上一个情节的特写。

【问题讨论】:

  • 它是哪个标准库? AFAIK,Clang 倾向于在 Linux 上使用 libstdc++,在 Mac 上使用 libc++。
  • @chris 我在 Ubuntu 上,我检查过它是 libstdc++。打印出 ____GLIBCXX____ 给出 20160609。关于 clang 版本,“clang -v”给出“clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)” 你能在 Mac 上重现这个错误吗?
  • 我已使用 Visual C++ 2017(32 位构建)编译并运行,但没有发现异常值。 (158 的值在 0.03166 左右,略低于 157 的 0.03182)
  • 只是对数学的评论,泊松分布不是连续的而是离散的,因此没有probability density function。不过,您可以计算 probability mass function。我意识到你的线图有助于引导眼睛,但泊松分布确实有非整数变量,所以绘制连续线有点误导。
  • 查看来源:// NB: This case not in the book, nor in the Errata, but should be ok... - 我对手头的问题一无所知(除了一些关于接受/拒绝算法的非常基本的 uni 知识),但它是那种声明让我紧张... :o)

标签: c++ c++11 libstdc++ c++-standard-library


【解决方案1】:

我的系统设置如下(Debian测试):

libstdc++-7-dev:
  Installed: 7.2.0-16

libc++-dev:
  Installed: 3.5-2

clang:
  Installed: 1:3.8-37

g++:
  Installed: 4:7.2.0-1d1

我可以确认使用libstdc++时的错误:

g++ -o pois_gcc -std=c++11 pois.cpp
clang++ -o pois_clang -std=c++11 -stdlib=libstdc++ pois.cpp
clang++ -o pois_clang_libc -std=c++11 -stdlib=libc++ pois.cpp

结果:

【讨论】:

  • report那个错误吗?你可能应该!然后在你的问题中给出它的 URL!
  • 信用不归我所有。如果他愿意,我会等待@DmytroOliinychenko 报告这一点。虽然如果他决定不这样做,我也可以这样做。
  • 报告给 GCC bugtracker。
  • @ChristophTerasa 请链接到错误报告
猜你喜欢
  • 2022-01-20
  • 2015-12-03
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 2014-06-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多