在 gcc 实现中,这很简单;这些参数仅用作实际算法输出的简单乘法和移位。但我可以想象其他算法在这种特殊情况下会遇到问题。我应该更好地建立一个外部安全防护,还是只给std::normal_distribution
' 的构造函数一个 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 定义。
我想补充一点,这在数学上很有意义:对于标准差(宽度)=0,高斯正态分布变为狄拉克三角函数。
狄拉克 delta 函数在除 x==0 之外的任何地方都定义为 ==0,其中未定义。但是,在积分范围内包含 x==0 的 delta 函数上的每个积分都定义为 1,而不包含 x==0 的积分则为 0。
这种行为不能在浮点数/双精度数的定义中正确表示,因此 stddev=0 的正态分布必须保持未定义。