我正在编写一个蒙特卡洛算法,其中有一次我需要除以一个随机变量。更准确地说:随机变量用作差商的步长,所以我实际上首先将某个变量乘以该变量,然后再将其从该表达式的某个局部线性函数中除以。像
double f(double);
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<> >
r( std::tr1::mt19937(time(NULL)),
std::tr1::normal_distribution<>(0) );
double h = r();
double a = ( f(x+h) - f(x) ) / h;
这在大多数情况下都可以正常工作,但在h=0
. 从数学上讲,这不是一个问题,因为在正态分布随机变量的任何有限(或实际上是可数)选择中,它们都将以概率 1 非零。但在数字实现中,我会遇到h==0
每 ≈2³² 函数调用(不管 mersenne twister 的周期比宇宙长,它仍然输出普通long
的 s!)。
避免这个麻烦很简单,目前我正在做
double h = r();
while (h==0) h=r();
但我不认为这特别优雅。有没有更好的办法?
我正在评估的函数实际上不仅仅是一个简单的 ℝ->ℝ
f
,而是一个 ℝᵐxℝⁿ -> ℝ,我在其中计算 ℝᵐ 变量的梯度,同时对 ℝⁿ 变量进行数值积分。整个函数叠加了不可预测的(但“连贯的”)噪声,有时还有特定的(但未知的)突出频率,当我尝试使用h
.