是否保证“std::normal_distribution”正常,标准偏差为0
Is `std::normal_distribution` guaranteed to be ok with standard deviation 0?
在gcc实现中,这很简单;参数仅作为实际算法输出的简单乘法和移位来应用。但我可以想象其他算法在这种特殊情况下会出现问题。我应该更好地构建一个外部安全保护,还是只给std::normal_distribution
的构造函数一个0作为标准差参数来获得"非随机分布",即总是产生平均值的分布?
(性能除外)
标准规定如下(§26.5.8.4.4):
explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0);
Requires: 0 < stddev.
因此,0
的标准推导被标准明确禁止,因此不能保证工作。因此,建立一个外部保障似乎是一个好主意
即使典型的实现将在0的标准派生上工作(不确定情况是否如此),我也可以想象一个测试这种情况的实现,当标准派生为零时抛出异常,如果不是则抛出异常(以确保代码是可移植的)。作为替代方案,代码可能会在某个地方除以标准推导,这对于0
的推导也会有问题。
不能使用0的标准偏差。根据标准,第26.5.8.5.1节:
explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0);
Requires: 0 < stddev.
使用值0会导致未定义的行为,因此需要对该值进行特殊处理。
正如前面的作者所指出的,normal_distribution函数的行为只为stddev>0定义。
我只想补充一点,这在数学上很有意义:对于stddev(宽度)=0,高斯正态分布变成了Dirac-delta函数。
Dirac delta函数被定义为除了x=0之外的所有地方都是==0,在那里它是未定义的。然而,在其积分极限内包括x==0的delta函数上的每一个积分都被定义为1,而不包含x==0的积分是0。
这种行为不能在浮点/双精度数字的定义中正确表示,因此stddev=0的正态分布必须保持未定义状态。
相关文章:
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 为什么constexpr的性能比正常表达式差
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 在我的项目中包括eigen将标准INT定义为eigen :: denseIndex-如何使用正常INT
- OPENCV标准视差图无法正常工作
- 是否保证“std::normal_distribution”正常,标准偏差为0
- 标准 IO C++无法正常输出 NULL 的原因是什么?
- 模仿从标准模板库中删除的函数无法正常工作