【问题标题】:Possible construction bug in std::poisson_distributionstd::poisson_distribution 中可能的构造错误
【发布时间】:2022-01-20 15:03:45
【问题描述】:

我不确定这是该评论/问题的正确平台,但请考虑以下代码 sn-p:

#include <random>
#include <iostream>
#include <limits>
int main()
{
    int m=std::numeric_limits<int>::max();
    std::cout<<m<<"\n";
    std::poisson_distribution<int> p(m+1.);//implicit conversion to double
    std::mt19937 rng(std::random_device{}());
    auto x=p(rng);
    std::cout<<x<<std::endl;
    return 0;
}

代码编译并运行。尽管显然它没有正确采样分布,因为 50% 的时间 x 应该大于 m+1,这是不允许的。在我的机器上,程序只输出小于 m 的数字,但这可能是一种未定义的行为。事实上,如果我打印 std::cout&lt;&lt;p.max()&lt;&lt;"\n"; 我会得到 m。 现在,我知道从数学上讲,我基本上是从正态分布中抽样的,我可以轻松解决这个问题。但是我想知道是否 构建分发时或如果应在以下页面中添加注释时应引发运行时异常:https://en.cppreference.com/w/cpp/numeric/random/poisson_distribution。 如果您同意我的观点,我应该联系谁?

【问题讨论】:

  • 是的。但这只是为了清楚起见而做的一个例子。如果提取大于 MAXINT 的数字的概率不可忽略,您仍然会错误地对分布进行采样。
  • 在我的机器上,程序只输出小于 m 的数字——在每台机器上都是如此。 p 返回int,根据定义,这些值为正数。它不能返回任何大于m 的值。
  • 但这不是有符号整数溢出的情况。数学全部隐藏在类内部,类被指定返回“非负整数值”。
  • 我不确定你在期待什么。 cppreference.com 只是记录标准。他们不解释标准。您在这里要求病理行为。我不确定这是否符合标准。
  • 我看到了这个想法 - 代码,与规范不匹配,分布不匹配。也许它应该被指定,也许它是显而易见的。我找不到任何可以在eel.is/c++draft/rand 中指定的内容。 Gcc 只取下一个数字,直到它在 gcc random.tcc 范围内。 Llvm 似乎只是“钳制积分”返回值llcm poisson_distribution.h

标签: c++ language-lawyer std


【解决方案1】:

所有泊松分布支持所有非负整数。因此,总是值因为太大而无法生成。有人可能会争辩说,这些值应该被限制在该范围内,或者它们应该被重新绘制。对于合理的λ值,两者都没有任何实际效果,但是选择一个不寻常的参数会迫使不可避免的选择成为主导效果。

【讨论】:

  • 标准已经涵盖了这一点:“本子条款中指定的每个概率密度函数 p 和每个离散概率函数 P 的值在其规定域之外的任何地方都为 0。”永远不会生成不可表示的值。
  • @RaymondChen:不过,这并没有说明函数的其余部分会发生什么,以保持其积分 1。
猜你喜欢
  • 2018-05-15
  • 2013-08-24
  • 1970-01-01
  • 2014-12-29
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
相关资源
最近更新 更多