Как использовать биссекцию?
Вчера у меня были проблемы с другими функциями повышения, но, к счастью, вы, ребята, помогли мне их решить. Сегодня мне нужно знать, как правильно использовать функцию деления пополам.
Итак, вот как я думаю, что это должно работать, но, тем не менее, кажется, что я тоже это понимаю. Итак, я хотел бы использовать:
template <class F, class T, class Tol>
std::pair<T, T>
bisect(
F f,
T min,
T max,
Tol tol);
отсюда, но моя проблема с толерантностью, потому что я не знаю, как это исправить. я пробовал
double value = boost::math::tools::eps_tolerance<double>(0.00001);
и как мне вернуть значение, когда пополам найдено? Должен ли результат быть парой чисел как std::pair в функции, а после этого просто вычислить min+max/2?
Спасибо!
1 ответ
Это пример использования bisect
, Рассмотрите решение уравнения x^2 - 3x + 1 = 0
:
struct TerminationCondition {
bool operator() (double min, double max) {
return abs(min - max) <= 0.000001;
}
};
struct FunctionToApproximate {
double operator() (double x) {
return x*x - 3*x + 1; // Replace with your function
}
};
// ...
using boost::math::tools::bisect;
double from = 0; // The solution must lie in the interval [from, to], additionally f(from) <= 0 && f(to) >= 0
double to = 1;
std::pair<double, double> result = bisect(FunctionToApproximate(), from, to, TerminationCondition());
double root = (result.first + result.second) / 2; // = 0.381966...
РЕДАКТИРОВАТЬ: Альтернативно, вот как вы можете использовать его с пользовательскими функциями:
double myF(double x) {
return x*x*x;
}
double otherF(double x) {
return log(abs(x));
}
// ...
std::pair<double, double> result1 = bisect(&myF, from, to, TerminationCondition());
std::pair<double, double> result2 = bisect(&otherF, 0.1, 1.1, TerminationCondition());
Обратите внимание, что
bisect
также поддерживает лямбды:
using boost::math::tools::bisect;
auto root = bisect
(
[](double x){return x;},
-1.0, 1.0,
[](double l, double r){return abs(l-r) < 1e-8;}
);