Проблемы с функцией Log в библиотеках Boost C ++ - PullRequest
1 голос
/ 02 декабря 2010

У меня есть этот код, чтобы получить логарифм числа с заданной общей базой:

#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>
// ...
// Boost Log returns boost::math::log1p(x) = log(e, x + 1)
double res = (double)(boost::math::log1p(arg - 1));
// Base conversion: log(new, y) = log(old, y) / log(old, new)
// Then ==> log(base, arg) = log(e, arg) / log(e, base)
res = (double)(res / ((double)boost::math::log1p(base - 1)));
return res;

Как видите, загрузочные библиотеки определяют только неперианский журнал, и есть также хитрый способ получить этот журнал, потому что то, что эта библиотека возвращает вам, это не log (x), а log (x + 1). Как видите, эта проблема решается путем указания аргумента arg - 1, и все должно работать.

ХОРОШО Это работает, но только неперианский журнал в порядке, я имею в виду, если я запускаю этот код:

#include <boost/math/special_functions/powm1.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/sqrt1pm1.hpp>
// ...
// Boost Log returns boost::math::log1p(x) = log(e, x + 1)
double res = (double)(boost::math::log1p(arg - 1));
// Base conversion: log(new, y) = log(old, y) / log(old, new)
// Then ==> log(base, arg) = log(e, arg) / log(e, base)
//res = (double)(res / ((double)boost::math::log1p(base - 1)));
return res;

Все в порядке, но правильно, когда я выполняю базовое изменение, все не хорошо, я получаю неправильные результаты ... Я не знаю, может быть, это математическая проблема ... Я знаю этот журнал (basea, x ) = log (baseb, x) / log (baseb, basea) ...

Где я не так делаю ??

Ну, может быть, это математическая проблема, касающаяся числовой стабильности и т. Д. ... чтобы получить журнал на другой базе, какова лучшая практика ???????

Ответы [ 2 ]

1 голос
/ 02 декабря 2010

Я не уверен, что именно происходит, но у вас может быть проблема с округлением. Проблема с дельтой 1 +, где дельта мала, состоит в том, что двойные числа не созданы, чтобы держать дельту с высокой точностью, поскольку 1 доминирует чрезвычайно, а дельта считается незначительной.

Цель библиотеки повышения состоит в том, чтобы позволить вам передавать 1 и дельту по отдельности, чтобы не потерять точность дельты, когда вы берете журнал, что даст вам число, близкое к 0.

Примером является дельта = 0,00000000123456789

Если вы добавите это к 1, затем снова вычтите 1, вы не увидите все эти числа, поскольку двойное число содержит только около 15 точек точности, но число выше +1 дает 17, тогда как число, которое я напечатал, использует только 9 мест, потому ведущие нули не в счет.

0 голосов
/ 13 октября 2015

Непонятно, что это за тип arg. Вы можете попробовать несколько вещей

  1. Verify boost :: math :: log1p () печатает ожидаемый результат.

  2. Убедитесь, что arg - 1 действительно двойное число, и распечатайте его. Вместо этого вы попробовали: arg - 1.0

...