bessel.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 492 行 · 第 1/2 页

HPP
492
字号
//  Copyright (c) 2007 John Maddock//  Use, modification and distribution are subject to the//  Boost Software License, Version 1.0. (See accompanying file//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// This header just defines the function entry points, and adds dispatch// to the right implementation method.  Most of the implementation details// are in separate headers and copyright Xiaogang Zhang.//#ifndef BOOST_MATH_BESSEL_HPP#define BOOST_MATH_BESSEL_HPP#ifdef _MSC_VER#pragma once#endif#include <boost/math/special_functions/detail/bessel_jy.hpp>#include <boost/math/special_functions/detail/bessel_jn.hpp>#include <boost/math/special_functions/detail/bessel_yn.hpp>#include <boost/math/special_functions/detail/bessel_ik.hpp>#include <boost/math/special_functions/detail/bessel_i0.hpp>#include <boost/math/special_functions/detail/bessel_i1.hpp>#include <boost/math/special_functions/detail/bessel_kn.hpp>#include <boost/math/special_functions/sin_pi.hpp>#include <boost/math/special_functions/cos_pi.hpp>#include <boost/math/special_functions/sinc.hpp>#include <boost/math/special_functions/trunc.hpp>#include <boost/math/special_functions/round.hpp>#include <boost/math/tools/rational.hpp>#include <boost/math/tools/promotion.hpp>namespace boost{ namespace math{namespace detail{template <class T, class Policy>struct bessel_j_small_z_series_term{   typedef T result_type;   bessel_j_small_z_series_term(T v_, T x)      : N(0), v(v_)   {      BOOST_MATH_STD_USING      mult = x / 2;      term = pow(mult, v) / boost::math::tgamma(v+1, Policy());      mult *= -mult;   }   T operator()()   {      T r = term;      ++N;      term *= mult / (N * (N + v));      return r;   }private:   unsigned N;   T v;   T mult;   T term;};template <class T, class Policy>struct sph_bessel_j_small_z_series_term{   typedef T result_type;   sph_bessel_j_small_z_series_term(unsigned v_, T x)      : N(0), v(v_)   {      BOOST_MATH_STD_USING      mult = x / 2;      term = pow(mult, T(v)) / boost::math::tgamma(v+1+T(0.5f), Policy());      mult *= -mult;   }   T operator()()   {      T r = term;      ++N;      term *= mult / (N * T(N + v + 0.5f));      return r;   }private:   unsigned N;   unsigned v;   T mult;   T term;};template <class T, class Policy>inline T bessel_j_small_z_series(T v, T x, const Policy& pol){   bessel_j_small_z_series_term<T, Policy> s(v, x);   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))   T zero = 0;   T result = boost::math::tools::sum_series(s, boost::math::policies::digits<T, Policy>(), max_iter, zero);#else   T result = boost::math::tools::sum_series(s, boost::math::policies::digits<T, Policy>(), max_iter);#endif   policies::check_series_iterations("boost::math::bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol);   return result;}template <class T, class Policy>inline T sph_bessel_j_small_z_series(unsigned v, T x, const Policy& pol){   BOOST_MATH_STD_USING // ADL of std names   sph_bessel_j_small_z_series_term<T, Policy> s(v, x);   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))   T zero = 0;   T result = boost::math::tools::sum_series(s, boost::math::policies::digits<T, Policy>(), max_iter, zero);#else   T result = boost::math::tools::sum_series(s, boost::math::policies::digits<T, Policy>(), max_iter);#endif   policies::check_series_iterations("boost::math::sph_bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol);   return result * sqrt(constants::pi<T>() / 4);}template <class T, class Policy>T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol){   BOOST_MATH_STD_USING   static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)";   if(x < 0)   {      // better have integer v:      if(floor(v) == v)      {         T r = cyl_bessel_j_imp(v, -x, t, pol);         if(iround(v, pol) & 1)            r = -r;         return r;      }      else         return policies::raise_domain_error<T>(            function,            "Got x = %1%, but we need x >= 0", x, pol);   }   if(x == 0)      return (v == 0) ? 1 : (v > 0) ? 0 :          policies::raise_domain_error<T>(            function,             "Got v = %1%, but require v >= 0 or a negative integer: the result would be complex.", v, pol);         if((v >= 0) && ((x < 1) || (v > x * x / 4)))   {      return bessel_j_small_z_series(v, x, pol);   }      T j, y;   bessel_jy(v, x, &j, &y, need_j, pol);   return j;}template <class T, class Policy>inline T cyl_bessel_j_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol){   BOOST_MATH_STD_USING  // ADL of std names.   typedef typename bessel_asymptotic_tag<T, Policy>::type tag_type;   if((fabs(v) < 200) && (floor(v) == v))   {      if(fabs(x) > asymptotic_bessel_j_limit<T>(v, tag_type()))         return asymptotic_bessel_j_large_x_2(v, x);      else         return bessel_jn(iround(v, pol), x, pol);   }   return cyl_bessel_j_imp(v, x, bessel_no_int_tag(), pol);}template <class T, class Policy>inline T cyl_bessel_j_imp(int v, T x, const bessel_int_tag&, const Policy& pol){   BOOST_MATH_STD_USING   typedef typename bessel_asymptotic_tag<T, Policy>::type tag_type;   if(fabs(x) > asymptotic_bessel_j_limit<T>(abs(v), tag_type()))   {      T r = asymptotic_bessel_j_large_x_2(static_cast<T>(abs(v)), x);      if((v < 0) && (v & 1))         r = -r;      return r;   }   else      return bessel_jn(v, x, pol);}template <class T, class Policy>inline T sph_bessel_j_imp(unsigned n, T x, const Policy& pol){   BOOST_MATH_STD_USING // ADL of std names   if(x < 0)      return policies::raise_domain_error<T>(         "boost::math::sph_bessel_j<%1%>(%1%,%1%)",         "Got x = %1%, but function requires x > 0.", x, pol);   //   // Special case, n == 0 resolves down to the sinus cardinal of x:   //   if(n == 0)      return boost::math::sinc_pi(x, pol);   //   // When x is small we may end up with 0/0, use series evaluation   // instead, especially as it converges rapidly:   //   if(x < 1)      return sph_bessel_j_small_z_series(n, x, pol);   //   // Default case is just a naive evaluation of the definition:   //   return sqrt(constants::pi<T>() / (2 * x))       * cyl_bessel_j_imp(T(n)+T(0.5f), x, bessel_no_int_tag(), pol);}template <class T, class Policy>T cyl_bessel_i_imp(T v, T x, const Policy& pol){   //   // This handles all the bessel I functions, note that we don't optimise   // for integer v, other than the v = 0 or 1 special cases, as Millers   // algorithm is at least as inefficient as the general case (the general   // case has better error handling too).   //   BOOST_MATH_STD_USING   if(x < 0)   {      // better have integer v:      if(floor(v) == v)      {         T r = cyl_bessel_i_imp(v, -x, pol);         if(iround(v, pol) & 1)            r = -r;         return r;      }      else         return policies::raise_domain_error<T>(         "boost::math::cyl_bessel_i<%1%>(%1%,%1%)",            "Got x = %1%, but we need x >= 0", x, pol);   }   if(x == 0)   {      return (v == 0) ? 1 : 0;   }   if(v == 0.5f)   {      // common special case, note try and avoid overflow in exp(x):

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?