Boost-Geometry-Utils

 view release on metacpan or  search on metacpan

src/boost/math/special_functions/expint.hpp  view on Meta::CPAN

         BOOST_MATH_BIG_CONSTANT(T, 113, -1077042281708.42654526404581272546244),
         BOOST_MATH_BIG_CONSTANT(T, 113, -68028222642.1941480871395695677675137)
      };
      static const T Q[20] = {    
         BOOST_MATH_BIG_CONSTANT(T, 113, 1),
         BOOST_MATH_BIG_CONSTANT(T, 113, 168.542326331163836642960118190147311),
         BOOST_MATH_BIG_CONSTANT(T, 113, 12535.7237814586576783518249115343619),
         BOOST_MATH_BIG_CONSTANT(T, 113, 544891.263372016404143120911148640627),
         BOOST_MATH_BIG_CONSTANT(T, 113, 15454474.7241010258634446523045237762),
         BOOST_MATH_BIG_CONSTANT(T, 113, 302495899.896629522673410325891717381),
         BOOST_MATH_BIG_CONSTANT(T, 113, 4215565948.38886507646911672693270307),
         BOOST_MATH_BIG_CONSTANT(T, 113, 42552409471.7951815668506556705733344),
         BOOST_MATH_BIG_CONSTANT(T, 113, 313592377066.753173979584098301610186),
         BOOST_MATH_BIG_CONSTANT(T, 113, 1688763640223.4541980740597514904542),
         BOOST_MATH_BIG_CONSTANT(T, 113, 6610992294901.59589748057620192145704),
         BOOST_MATH_BIG_CONSTANT(T, 113, 18601637235659.6059890851321772682606),
         BOOST_MATH_BIG_CONSTANT(T, 113, 36944278231087.2571020964163402941583),
         BOOST_MATH_BIG_CONSTANT(T, 113, 50425858518481.7497071917028793820058),
         BOOST_MATH_BIG_CONSTANT(T, 113, 45508060902865.0899967797848815980644),
         BOOST_MATH_BIG_CONSTANT(T, 113, 25649955002765.3817331501988304758142),
         BOOST_MATH_BIG_CONSTANT(T, 113, 8259575619094.6518520988612711292331),
         BOOST_MATH_BIG_CONSTANT(T, 113, 1299981487496.12607474362723586264515),
         BOOST_MATH_BIG_CONSTANT(T, 113, 70242279152.8241187845178443118302693),
         BOOST_MATH_BIG_CONSTANT(T, 113, -37633302.9409263839042721539363416685)
      };
      T recip = 1 / z;
      result = 1 + tools::evaluate_polynomial(P, recip)
         / tools::evaluate_polynomial(Q, recip);
      result *= exp(-z) * recip;
   }
   else
   {
      result = 0;
   }
   return result;
}

template <class T>
struct expint_fraction
{
   typedef std::pair<T,T> result_type;
   expint_fraction(unsigned n_, T z_) : b(n_ + z_), i(-1), n(n_){}
   std::pair<T,T> operator()()
   {
      std::pair<T,T> result = std::make_pair(-static_cast<T>((i+1) * (n+i)), b);
      b += 2;
      ++i;
      return result;
   }
private:
   T b;
   int i;
   unsigned n;
};

template <class T, class Policy>
inline T expint_as_fraction(unsigned n, T z, const Policy& pol)
{
   BOOST_MATH_STD_USING
   BOOST_MATH_INSTRUMENT_VARIABLE(z)
   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
   expint_fraction<T> f(n, z);
   T result = tools::continued_fraction_b(
      f, 
      boost::math::policies::get_epsilon<T, Policy>(),
      max_iter);
   policies::check_series_iterations<T>("boost::math::expint_continued_fraction<%1%>(unsigned,%1%)", max_iter, pol);
   BOOST_MATH_INSTRUMENT_VARIABLE(result)
   BOOST_MATH_INSTRUMENT_VARIABLE(max_iter)
   result = exp(-z) / result;
   BOOST_MATH_INSTRUMENT_VARIABLE(result)
   return result;
}

template <class T>
struct expint_series
{
   typedef T result_type;
   expint_series(unsigned k_, T z_, T x_k_, T denom_, T fact_) 
      : k(k_), z(z_), x_k(x_k_), denom(denom_), fact(fact_){}
   T operator()()
   {
      x_k *= -z;
      denom += 1;
      fact *= ++k;
      return x_k / (denom * fact);
   }
private:
   unsigned k;
   T z;
   T x_k;
   T denom;
   T fact;
};

template <class T, class Policy>
inline T expint_as_series(unsigned n, T z, const Policy& pol)
{
   BOOST_MATH_STD_USING
   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();

   BOOST_MATH_INSTRUMENT_VARIABLE(z)

   T result = 0;
   T x_k = -1;
   T denom = T(1) - n;
   T fact = 1;
   unsigned k = 0;
   for(; k < n - 1;)
   {
      result += x_k / (denom * fact);
      denom += 1;
      x_k *= -z;
      fact *= ++k;
   }
   BOOST_MATH_INSTRUMENT_VARIABLE(result)
   result += pow(-z, static_cast<T>(n - 1)) 
      * (boost::math::digamma(static_cast<T>(n)) - log(z)) / fact;
   BOOST_MATH_INSTRUMENT_VARIABLE(result)

   expint_series<T> s(k, z, x_k, denom, fact);
   result = tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, result);
   policies::check_series_iterations<T>("boost::math::expint_series<%1%>(unsigned,%1%)", max_iter, pol);
   BOOST_MATH_INSTRUMENT_VARIABLE(result)
   BOOST_MATH_INSTRUMENT_VARIABLE(max_iter)
   return result;
}

template <class T, class Policy, class Tag>
T expint_imp(unsigned n, T z, const Policy& pol, const Tag& tag)
{
   BOOST_MATH_STD_USING
   static const char* function = "boost::math::expint<%1%>(unsigned, %1%)";
   if(z < 0)
      return policies::raise_domain_error<T>(function, "Function requires z >= 0 but got %1%.", z, pol);
   if(z == 0)
      return n == 1 ? policies::raise_overflow_error<T>(function, 0, pol) : T(1 / (static_cast<T>(n - 1)));

   T result;

   bool f;
   if(n < 3)
   {
      f = z < 0.5;
   }
   else
   {
      f = z < (static_cast<T>(n - 2) / static_cast<T>(n - 1));
   }
#ifdef BOOST_MSVC
#  pragma warning(push)
#  pragma warning(disable:4127) // conditional expression is constant
#endif
   if(n == 0)
      result = exp(-z) / z;
   else if((n == 1) && (Tag::value))
   {
      result = expint_1_rational(z, tag);
   }
   else if(f)
      result = expint_as_series(n, z, pol);
   else
      result = expint_as_fraction(n, z, pol);
#ifdef BOOST_MSVC
#  pragma warning(pop)
#endif

   return result;
}

template <class T>
struct expint_i_series
{
   typedef T result_type;
   expint_i_series(T z_) : k(0), z_k(1), z(z_){}
   T operator()()
   {
      z_k *= z / ++k;
      return z_k / k;
   }
private:
   unsigned k;
   T z_k;
   T z;
};

template <class T, class Policy>
T expint_i_as_series(T z, const Policy& pol)
{
   BOOST_MATH_STD_USING
   T result = log(z); // (log(z) - log(1 / z)) / 2;
   result += constants::euler<T>();
   expint_i_series<T> s(z);
   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
   result = tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, result);
   policies::check_series_iterations<T>("boost::math::expint_i_series<%1%>(%1%)", max_iter, pol);
   return result;
}

template <class T, class Policy, class Tag>
T expint_i_imp(T z, const Policy& pol, const Tag& tag)
{
   static const char* function = "boost::math::expint<%1%>(%1%)";
   if(z < 0)
      return -expint_imp(1, T(-z), pol, tag);
   if(z == 0)
      return -policies::raise_overflow_error<T>(function, 0, pol);
   return expint_i_as_series(z, pol);
}

template <class T, class Policy>
T expint_i_imp(T z, const Policy& pol, const mpl::int_<53>& tag)
{
   BOOST_MATH_STD_USING
   static const char* function = "boost::math::expint<%1%>(%1%)";
   if(z < 0)
      return -expint_imp(1, T(-z), pol, tag);
   if(z == 0)
      return -policies::raise_overflow_error<T>(function, 0, pol);

   T result;

   if(z <= 6)
   {
      // Maximum Deviation Found:                     2.852e-18
      // Expected Error Term:                         2.852e-18
      // Max Error found at double precision =        Poly: 2.636335e-16   Cheb: 4.187027e-16
      static const T P[10] = {    
         BOOST_MATH_BIG_CONSTANT(T, 53, 2.98677224343598593013),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.356343618769377415068),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.780836076283730801839),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.114670926327032002811),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.0499434773576515260534),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.00726224593341228159561),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.00115478237227804306827),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.000116419523609765200999),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.798296365679269702435e-5),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.2777056254402008721e-6)
      };
      static const T Q[8] = {    
         BOOST_MATH_BIG_CONSTANT(T, 53, 1),
         BOOST_MATH_BIG_CONSTANT(T, 53, -1.17090412365413911947),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.62215109846016746276),
         BOOST_MATH_BIG_CONSTANT(T, 53, -0.195114782069495403315),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.0391523431392967238166),
         BOOST_MATH_BIG_CONSTANT(T, 53, -0.00504800158663705747345),
         BOOST_MATH_BIG_CONSTANT(T, 53, 0.000389034007436065401822),
         BOOST_MATH_BIG_CONSTANT(T, 53, -0.138972589601781706598e-4)
      };

      static const T c1 = BOOST_MATH_BIG_CONSTANT(T, 53, 1677624236387711.0);
      static const T c2 = BOOST_MATH_BIG_CONSTANT(T, 53, 4503599627370496.0);
      static const T r1 = static_cast<T>(c1 / c2);
      static const T r2 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.131401834143860282009280387409357165515556574352422001206362e-16);
      static const T r = static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 53, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392));
      T t = (z / 3) - 1;



( run in 0.678 second using v1.01-cache-2.11-cpan-71847e10f99 )