Мне нужно вычислить среднее геометрическое большого набора чисел, значения которых не ограничены априори. Наивный способ был быЭффективный способ вычисления среднего геометрического числа чисел
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
отдельно?
Есть ли максимальный диапазон, в пределах которого находится значение чисел? –
@Walter: вы пытались использовать long double – ahmedsafan86
@Ahmedsafan не помогает, если слишком много чисел: рассмотрите числа в диапазоне от 0,01 до 1 и 10^6 из них ... – Walter