【发布时间】:2013-10-20 13:08:33
【问题描述】:
所以我最近一直在研究订单统计的一些概率分布。在那个领域,很常见的是从实数区间 [0, 1] 中看到许多具有高数幂的公式。
考虑数字 a ~ b ~ 0,都是正数。我想计算类似 a^n / b^m 其中 n, m 是巨大的数字。
我的问题如下: 如果我使用像
这样的 C 代码double f(double a, double b, long m, long n)
{
return( pow(a, n) / pow(b, m) );
}
这会稳定吗?规则应该是首先评估 a^n,然后是 b^m,然后除,但是如果 a^n 或 b^m 足够小,它将为零或 NaN。相反,我可以做类似的事情
double g(double a, double b, long m, long n)
{
double res;
long i;
res = 1;
for (i = 0; i < min(m, n); ++i)
{
res = res * a / b;
}
if ( n > m )
{
res = res * pow(a, n - m);
} else {
res = res / pow(b, m - n);
}
return( res );
}
您知道 1) 在这种情况下是否需要优化?如果没有,如何处理此类情况以进行快速稳定的评估?
【问题讨论】:
-
为了避免这种情况,在日志域中计算是否可行?即
result = exp(n*log(a) - m*log(b))。 (免责声明:我绝对不是数字专家。) -
您需要第二种形式。但不要使用
for循环。使用pow(a/b, min(m, n))减少操作次数。 (假设m和n必须是非负数。) -
好的,谢谢!我想使用 sum() 和 log(a)-log(b) 结合这两种方法没有问题:)
-
在您的
a ~ b ~ 0中,~应该表示近似相等吗?
标签: c optimization numerical stability