我需要计算一组数字的几何平均值,这些数字的值未事先限制。朴素的方法是
double geometric_mean(std::vector<double> const&data) // failure
{
auto product = 1.0;
for(auto x:data) product *= x;
return std::pow(product,1.0/data.size());
}
但是,这种方法可能会因为在累积的 product
中出现下溢或上溢而失败(注意:即使使用 long double
也无法完全避免此问题)。因此,下一个选择是对对数进行求和:
double geometric_mean(std::vector<double> const&data)
{
auto sumlog = 0.0;
for(auto x:data) sum_log += std::log(x);
return std::exp(sum_log/data.size());
}
这个方法可以工作,但是对于每一个元素都调用了std::log()
,可能会导致速度变慢。有没有办法避免这种情况?例如通过分别跟踪积累的product
的指数和尾数(相当于)?
log()
相对于其他替代方案的速度有多慢?我很想看到一个实际的性能比较... - comingstormdouble
类型,可以非常高效地实现对数运算。你可能真的想在这里进行一次比较,结果会非常有趣 :) - filmor