Теперь предположим, что мы хотим найтипятый кореньиз числаа.
Уравнение, которое мы хотим решить:
f(x) =x5-a
Если ваша дифференциация немного ржавая (или вы столкнулись с функцией, сложность которой делает дифференциацию сложной), то вы можете получить помощь, например, с бесценного сайтаWolframAlpha.
Например, вход в комменд:<differentiate
x^
5
>
Язык Вольфрама:<D[x^
5,x]
>
Вывод:<d/dx(x
^5)=5
x^
4
>
Чтобы получить второй дифференциал, введите:<second
differentiatex
^5
>
Команды Wolfram Language<D[x^
5,{x,
2}]
>
Чтобы получить результат:<d^
2/dx^2(x
^5)=20
x^
3
>
Чтобы получить эталонное значение, мы можем ввести:<fifth root 3126
>
или:<N[3126^(1/5),50]
>
Чтобы получить результат с точностью 50 десятичных цифр:
50003199590478625588206333405631053401128722314376
(Мы также можем получить эталонное значение, используямноготочный корень).
1-я и 2-я производные x5являются:
f'(x) = 5x4
f''(x) = 20x3
Используя эти выражения для производных, функтор:
template <class T>
struct fifth_functor_2deriv
{
fifth_functor_2deriv(T const& to_find_root_of) : a(to_find_root_of)
{ }
std::tuple<T, T, T> operator()(T const& x)
{
T fx = boost::math::pow<5>(x) - a;
T dx = 5 * boost::math::pow<4>(x);
T d2x = 20 * boost::math::pow<3>(x);
return std::make_tuple(fx, dx, d2x);
}
private:
T a;
};
Теперь наша пятая функция:
template <class T>
T fifth_2deriv(T x)
{
using namespace std;
using namespace boost::math::tools;
int exponent;
frexp(x, &exponent);
T guess = ldexp(1., exponent / 5);
T min = ldexp(0.5, exponent / 5);
T max = ldexp(2., exponent / 5);
const int digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
const boost::uintmax_t maxit = 50;
boost::uintmax_t it = maxit;
T result = halley_iterate(fifth_functor_2deriv<T>(x), guess, min, max, digits, it);
return result;
}
Полный код этого примера находится по адресуroot_finding_example.cppиroot_finding_n_example.cpp.