Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Generalizing to Compute the nth root

Boost , Math Toolkit 2.5.0 , Examples of Root-Finding (with and without derivatives)

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

При желании мы можем теперь дополнительно обобщить для вычисления корняnпутем вычисления производных.при времени компиляциис использованием правил дифференциации и<boost::math::pow<N>>, где параметр шаблона<N>является целым числом и постоянной времени компиляции. Наш функтор и функция теперь имеют дополнительный параметр шаблона<N>для требуемого корня.

[Note] Note

Поскольку полномочия и производные фиксируются во время компиляции, полученный код так же эффективен, как если бы кодировался вручную, как куб и примеры пятого корня выше. Хороший компилятор также должен оптимизировать повторные умножения.

Нашnкорневой функтор

template <int N, class T = double>
struct nth_functor_2deriv
{ // Functor returning both 1st and 2nd derivatives.
  BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
  nth_functor_2deriv(T const& to_find_root_of) : a(to_find_root_of)
  { /* Constructor stores value a to find root of, for example: */ }
  // using boost::math::tuple; // to return three values.
  std::tuple<T, T, T> operator()(T const& x)
  {
    // Return f(x), f'(x) and f''(x).
    using boost::math::pow;
    T fx = pow<N>(x) - a;                  // Difference (estimate x^n - a).
    T dx = N * pow<N - 1>(x);              // 1st derivative f'(x).
    T d2x = N * (N - 1) * pow<N - 2 >(x);  // 2nd derivative f''(x).
    return std::make_tuple(fx, dx, d2x);   // 'return' fx, dx and d2x.
  }
private:
  T a;                                     // to be 'nth_rooted'.
};

и нашаnкорневая функция

template <int N, class T = double>
T nth_2deriv(T x)
{ // return nth root of x using 1st and 2nd derivatives and Halley.
  using namespace std;  // Help ADL of std functions.
  using namespace boost::math::tools; // For halley_iterate.
  BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
  BOOST_STATIC_ASSERT_MSG((N > 1000) == false, "root N is too big!");
  typedef double guess_type; // double may restrict (exponent) range for a multiprecision T?
  int exponent;
  frexp(static_cast<guess_type>(x), &exponent);                 // Get exponent of z (ignore mantissa).
  T guess = ldexp(static_cast<guess_type>(1.), exponent / N);   // Rough guess is to divide the exponent by n.
  T min = ldexp(static_cast<guess_type>(1.) / 2, exponent / N); // Minimum possible value is half our guess.
  T max = ldexp(static_cast<guess_type>(2.), exponent / N);     // Maximum possible value is twice our guess.
  int digits = std::numeric_limits<T>::digits * 0.4;            // Accuracy triples with each step, so stop when
                                                                // slightly more than one third of the digits are correct.
  const boost::uintmax_t maxit = 20;
  boost::uintmax_t it = maxit;
  T result = halley_iterate(nth_functor_2deriv<N, T>(x), guess, min, max, digits, it);
  return result;
}
    show_nth_root<5, double>(2.);
    show_nth_root<5, long double>(2.);
#ifndef _MSC_VER  // float128 is not supported by Microsoft compiler 2013.
    show_nth_root<5, float128>(2);
#endif
    show_nth_root<5, cpp_dec_float_50>(2); // dec
    show_nth_root<5, cpp_bin_float_50>(2); // bin

производит продукцию, аналогичную этой

 Using MSVC 2013
nth Root finding Example.
Type double value = 2, 5th root = 1.14869835499704
Type long double value = 2, 5th root = 1.14869835499704
Type class boost::multiprecision::number<class boost::multiprecision::backends::cpp_dec_float<50,int,void>,1> value = 2,
  5th root = 1.1486983549970350067986269467779275894438508890978
Type class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,0> value = 2,
  5th root = 1.1486983549970350067986269467779275894438508890978
[Tip] Tip

Позаботьтесь о типе, переданном функции. Лучше всего пройти<double>или более точный тип плавающей точки.

При переходе целочисленного значения, например,<nth_2deriv<5>(2)>будет отклонено, в то время как<nth_2deriv<5, double>(2)>преобразует целое число в<double>.

Избегайте передачи значения<float>, которое вызовет предупреждения (фактически ложные) от компилятора о потенциальной потере данных, как отмечалось выше.

[Warning] Warning

Например, просьба о неразумных корнях<show_nth_root<1000000>(2.);>может привести к. Утрата значения, как<Type doublevalue =2,1000000throot =1.00000069314783>. Использование функции<pow>более разумно для этой необычной потребности.

Полный код этого примера находится по адресуroot_finding_n_example.cpp.


PrevUpHomeNext

Статья Generalizing to Compute the nth root раздела Math Toolkit 2.5.0 Examples of Root-Finding (with and without derivatives) может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Examples of Root-Finding (with and without derivatives) ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 00:59:34/0.0042259693145752/0