Boost-Geometry-Utils
view release on metacpan or search on metacpan
src/boost/math/special_functions/bessel.hpp view on Meta::CPAN
#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/detail/iconv.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>
#include <boost/math/tools/series.hpp>
namespace boost{ namespace math{
namespace detail{
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 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::get_epsilon<T, Policy>(), max_iter, zero);
#else
T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
#endif
policies::check_series_iterations<T>("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, T(-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) || (x < 5)))
{
//
// This series will actually converge rapidly for all small
// x - say up to x < 20 - but the first few terms are large
// and divergent which leads to large errors :-(
//
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.
int ival = detail::iconv(v, pol);
if((abs(ival) < 200) && (0 == v - ival))
{
return bessel_jn(ival/*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)
{
( run in 0.866 second using v1.01-cache-2.11-cpan-96521ef73a4 )