summaryrefslogtreecommitdiff
path: root/src/third_party/boost-1.56.0/boost/math/special_functions
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/boost-1.56.0/boost/math/special_functions')
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/bernoulli.hpp143
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/beta.hpp1490
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/cbrt.hpp180
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/bernoulli_details.hpp652
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/erf_inv.hpp536
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/fp_traits.hpp579
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/gamma_inva.hpp233
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inv_ab.hpp328
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inverse.hpp993
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_inverse.hpp551
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_large.hpp768
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/lanczos_sse2.hpp204
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/lgamma_small.hpp522
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/round_fwd.hpp93
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/t_distribution_inv.hpp549
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_bernoulli.hpp700
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_factorial.hpp625
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/erf.hpp1155
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/expm1.hpp343
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/factorials.hpp268
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/fpclassify.hpp606
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/gamma.hpp1931
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/lanczos.hpp1296
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/log1p.hpp503
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/math_fwd.hpp1499
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/pow.hpp141
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/powm1.hpp61
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/round.hpp109
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/sign.hpp194
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/sqrt1pm1.hpp48
-rw-r--r--src/third_party/boost-1.56.0/boost/math/special_functions/trunc.hpp111
31 files changed, 17411 insertions, 0 deletions
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/bernoulli.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/bernoulli.hpp
new file mode 100644
index 00000000000..2c2ccd52363
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/bernoulli.hpp
@@ -0,0 +1,143 @@
+
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2013 Nikhar Agrawal
+// Copyright 2013 Christopher Kormanyos
+// Copyright 2013 John Maddock
+// Copyright 2013 Paul Bristow
+// Distributed under 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)
+
+#ifndef _BOOST_BERNOULLI_B2N_2013_05_30_HPP_
+#define _BOOST_BERNOULLI_B2N_2013_05_30_HPP_
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/detail/unchecked_bernoulli.hpp>
+#include <boost/math/special_functions/detail/bernoulli_details.hpp>
+
+namespace boost { namespace math {
+
+namespace detail {
+
+template <class T, class OutputIterator, class Policy, int N>
+OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const mpl::int_<N>& tag)
+{
+ for(std::size_t i = start; (i <= max_bernoulli_b2n<T>::value) && (i < start + n); ++i)
+ {
+ *out = unchecked_bernoulli_imp<T>(i, tag);
+ ++out;
+ }
+
+ for(std::size_t i = (std::max)(static_cast<std::size_t>(max_bernoulli_b2n<T>::value + 1), start); i < start + n; ++i)
+ {
+ // We must overflow:
+ *out = (i & 1 ? 1 : -1) * policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(n)", 0, T(i), pol);
+ ++out;
+ }
+ return out;
+}
+
+template <class T, class OutputIterator, class Policy>
+OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const mpl::int_<0>& tag)
+{
+ for(std::size_t i = start; (i <= max_bernoulli_b2n<T>::value) && (i < start + n); ++i)
+ {
+ *out = unchecked_bernoulli_imp<T>(i, tag);
+ ++out;
+ }
+ //
+ // Short circuit return so we don't grab the mutex below unless we have to:
+ //
+ if(start + n <= max_bernoulli_b2n<T>::value)
+ return out;
+
+ return get_bernoulli_numbers_cache<T, Policy>().copy_bernoulli_numbers(out, start, n, pol);
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline T bernoulli_b2n(const int i, const Policy &pol)
+{
+ typedef mpl::int_<detail::bernoulli_imp_variant<T>::value> tag_type;
+ if(i < 0)
+ return policies::raise_domain_error<T>("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol);
+
+ T result;
+ boost::math::detail::bernoulli_number_imp<T>(&result, static_cast<std::size_t>(i), 1u, pol, tag_type());
+ return result;
+}
+
+template <class T>
+inline T bernoulli_b2n(const int i)
+{
+ return boost::math::bernoulli_b2n<T>(i, policies::policy<>());
+}
+
+template <class T, class OutputIterator, class Policy>
+inline OutputIterator bernoulli_b2n(const int start_index,
+ const unsigned number_of_bernoullis_b2n,
+ OutputIterator out_it,
+ const Policy& pol)
+{
+ typedef mpl::int_<detail::bernoulli_imp_variant<T>::value> tag_type;
+ if(start_index < 0)
+ {
+ *out_it = policies::raise_domain_error<T>("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol);
+ return ++out_it;
+ }
+
+ return boost::math::detail::bernoulli_number_imp<T>(out_it, start_index, number_of_bernoullis_b2n, pol, tag_type());
+}
+
+template <class T, class OutputIterator>
+inline OutputIterator bernoulli_b2n(const int start_index,
+ const unsigned number_of_bernoullis_b2n,
+ OutputIterator out_it)
+{
+ return boost::math::bernoulli_b2n<T, OutputIterator>(start_index, number_of_bernoullis_b2n, out_it, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline T tangent_t2n(const int i, const Policy &pol)
+{
+ if(i < 0)
+ return policies::raise_domain_error<T>("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol);
+
+ T result;
+ boost::math::detail::get_bernoulli_numbers_cache<T, Policy>().copy_tangent_numbers(&result, i, 1, pol);
+ return result;
+}
+
+template <class T>
+inline T tangent_t2n(const int i)
+{
+ return boost::math::tangent_t2n<T>(i, policies::policy<>());
+}
+
+template <class T, class OutputIterator, class Policy>
+inline OutputIterator tangent_t2n(const int start_index,
+ const unsigned number_of_tangent_t2n,
+ OutputIterator out_it,
+ const Policy& pol)
+{
+ if(start_index < 0)
+ {
+ *out_it = policies::raise_domain_error<T>("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol);
+ return ++out_it;
+ }
+
+ return boost::math::detail::get_bernoulli_numbers_cache<T, Policy>().copy_tangent_numbers(out_it, start_index, number_of_tangent_t2n, pol);
+}
+
+template <class T, class OutputIterator>
+inline OutputIterator tangent_t2n(const int start_index,
+ const unsigned number_of_tangent_t2n,
+ OutputIterator out_it)
+{
+ return boost::math::tangent_t2n<T, OutputIterator>(start_index, number_of_tangent_t2n, out_it, policies::policy<>());
+}
+
+} } // namespace boost::math
+
+#endif // _BOOST_BERNOULLI_B2N_2013_05_30_HPP_
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/beta.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/beta.hpp
new file mode 100644
index 00000000000..e48d713e3b1
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/beta.hpp
@@ -0,0 +1,1490 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_BETA_HPP
+#define BOOST_MATH_SPECIAL_BETA_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/special_functions/factorials.hpp>
+#include <boost/math/special_functions/erf.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/expm1.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail{
+
+//
+// Implementation of Beta(a,b) using the Lanczos approximation:
+//
+template <class T, class Lanczos, class Policy>
+T beta_imp(T a, T b, const Lanczos&, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // for ADL of std names
+
+ if(a <= 0)
+ return policies::raise_domain_error<T>("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got a=%1%).", a, pol);
+ if(b <= 0)
+ return policies::raise_domain_error<T>("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got b=%1%).", b, pol);
+
+ T result;
+
+ T prefix = 1;
+ T c = a + b;
+
+ // Special cases:
+ if((c == a) && (b < tools::epsilon<T>()))
+ return boost::math::tgamma(b, pol);
+ else if((c == b) && (a < tools::epsilon<T>()))
+ return boost::math::tgamma(a, pol);
+ if(b == 1)
+ return 1/a;
+ else if(a == 1)
+ return 1/b;
+
+ /*
+ //
+ // This code appears to be no longer necessary: it was
+ // used to offset errors introduced from the Lanczos
+ // approximation, but the current Lanczos approximations
+ // are sufficiently accurate for all z that we can ditch
+ // this. It remains in the file for future reference...
+ //
+ // If a or b are less than 1, shift to greater than 1:
+ if(a < 1)
+ {
+ prefix *= c / a;
+ c += 1;
+ a += 1;
+ }
+ if(b < 1)
+ {
+ prefix *= c / b;
+ c += 1;
+ b += 1;
+ }
+ */
+
+ if(a < b)
+ std::swap(a, b);
+
+ // Lanczos calculation:
+ T agh = a + Lanczos::g() - T(0.5);
+ T bgh = b + Lanczos::g() - T(0.5);
+ T cgh = c + Lanczos::g() - T(0.5);
+ result = Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b) / Lanczos::lanczos_sum_expG_scaled(c);
+ T ambh = a - T(0.5) - b;
+ if((fabs(b * ambh) < (cgh * 100)) && (a > 100))
+ {
+ // Special case where the base of the power term is close to 1
+ // compute (1+x)^y instead:
+ result *= exp(ambh * boost::math::log1p(-b / cgh, pol));
+ }
+ else
+ {
+ result *= pow(agh / cgh, a - T(0.5) - b);
+ }
+ if(cgh > 1e10f)
+ // this avoids possible overflow, but appears to be marginally less accurate:
+ result *= pow((agh / cgh) * (bgh / cgh), b);
+ else
+ result *= pow((agh * bgh) / (cgh * cgh), b);
+ result *= sqrt(boost::math::constants::e<T>() / bgh);
+
+ // If a and b were originally less than 1 we need to scale the result:
+ result *= prefix;
+
+ return result;
+} // template <class T, class Lanczos> beta_imp(T a, T b, const Lanczos&)
+
+//
+// Generic implementation of Beta(a,b) without Lanczos approximation support
+// (Caution this is slow!!!):
+//
+template <class T, class Policy>
+T beta_imp(T a, T b, const lanczos::undefined_lanczos& /* l */, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ if(a <= 0)
+ return policies::raise_domain_error<T>("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got a=%1%).", a, pol);
+ if(b <= 0)
+ return policies::raise_domain_error<T>("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got b=%1%).", b, pol);
+
+ T result;
+
+ T prefix = 1;
+ T c = a + b;
+
+ // special cases:
+ if((c == a) && (b < tools::epsilon<T>()))
+ return boost::math::tgamma(b, pol);
+ else if((c == b) && (a < tools::epsilon<T>()))
+ return boost::math::tgamma(a, pol);
+ if(b == 1)
+ return 1/a;
+ else if(a == 1)
+ return 1/b;
+
+ // shift to a and b > 1 if required:
+ if(a < 1)
+ {
+ prefix *= c / a;
+ c += 1;
+ a += 1;
+ }
+ if(b < 1)
+ {
+ prefix *= c / b;
+ c += 1;
+ b += 1;
+ }
+ if(a < b)
+ std::swap(a, b);
+
+ // set integration limits:
+ T la = (std::max)(T(10), a);
+ T lb = (std::max)(T(10), b);
+ T lc = (std::max)(T(10), T(a+b));
+
+ // calculate the fraction parts:
+ T sa = detail::lower_gamma_series(a, la, pol) / a;
+ sa += detail::upper_gamma_fraction(a, la, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sb = detail::lower_gamma_series(b, lb, pol) / b;
+ sb += detail::upper_gamma_fraction(b, lb, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sc = detail::lower_gamma_series(c, lc, pol) / c;
+ sc += detail::upper_gamma_fraction(c, lc, ::boost::math::policies::get_epsilon<T, Policy>());
+
+ // and the exponent part:
+ result = exp(lc - la - lb) * pow(la/lc, a) * pow(lb/lc, b);
+
+ // and combine:
+ result *= sa * sb / sc;
+
+ // if a and b were originally less than 1 we need to scale the result:
+ result *= prefix;
+
+ return result;
+} // template <class T>T beta_imp(T a, T b, const lanczos::undefined_lanczos& l)
+
+
+//
+// Compute the leading power terms in the incomplete Beta:
+//
+// (x^a)(y^b)/Beta(a,b) when normalised, and
+// (x^a)(y^b) otherwise.
+//
+// Almost all of the error in the incomplete beta comes from this
+// function: particularly when a and b are large. Computing large
+// powers are *hard* though, and using logarithms just leads to
+// horrendous cancellation errors.
+//
+template <class T, class Lanczos, class Policy>
+T ibeta_power_terms(T a,
+ T b,
+ T x,
+ T y,
+ const Lanczos&,
+ bool normalised,
+ const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ if(!normalised)
+ {
+ // can we do better here?
+ return pow(x, a) * pow(y, b);
+ }
+
+ T result;
+
+ T prefix = 1;
+ T c = a + b;
+
+ // combine power terms with Lanczos approximation:
+ T agh = a + Lanczos::g() - T(0.5);
+ T bgh = b + Lanczos::g() - T(0.5);
+ T cgh = c + Lanczos::g() - T(0.5);
+ result = Lanczos::lanczos_sum_expG_scaled(c) / (Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b));
+
+ // l1 and l2 are the base of the exponents minus one:
+ T l1 = (x * b - y * agh) / agh;
+ T l2 = (y * a - x * bgh) / bgh;
+ if(((std::min)(fabs(l1), fabs(l2)) < 0.2))
+ {
+ // when the base of the exponent is very near 1 we get really
+ // gross errors unless extra care is taken:
+ if((l1 * l2 > 0) || ((std::min)(a, b) < 1))
+ {
+ //
+ // This first branch handles the simple cases where either:
+ //
+ // * The two power terms both go in the same direction
+ // (towards zero or towards infinity). In this case if either
+ // term overflows or underflows, then the product of the two must
+ // do so also.
+ // *Alternatively if one exponent is less than one, then we
+ // can't productively use it to eliminate overflow or underflow
+ // from the other term. Problems with spurious overflow/underflow
+ // can't be ruled out in this case, but it is *very* unlikely
+ // since one of the power terms will evaluate to a number close to 1.
+ //
+ if(fabs(l1) < 0.1)
+ {
+ result *= exp(a * boost::math::log1p(l1, pol));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ result *= pow((x * cgh) / agh, a);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ if(fabs(l2) < 0.1)
+ {
+ result *= exp(b * boost::math::log1p(l2, pol));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ result *= pow((y * cgh) / bgh, b);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ else if((std::max)(fabs(l1), fabs(l2)) < 0.5)
+ {
+ //
+ // Both exponents are near one and both the exponents are
+ // greater than one and further these two
+ // power terms tend in opposite directions (one towards zero,
+ // the other towards infinity), so we have to combine the terms
+ // to avoid any risk of overflow or underflow.
+ //
+ // We do this by moving one power term inside the other, we have:
+ //
+ // (1 + l1)^a * (1 + l2)^b
+ // = ((1 + l1)*(1 + l2)^(b/a))^a
+ // = (1 + l1 + l3 + l1*l3)^a ; l3 = (1 + l2)^(b/a) - 1
+ // = exp((b/a) * log(1 + l2)) - 1
+ //
+ // The tricky bit is deciding which term to move inside :-)
+ // By preference we move the larger term inside, so that the
+ // size of the largest exponent is reduced. However, that can
+ // only be done as long as l3 (see above) is also small.
+ //
+ bool small_a = a < b;
+ T ratio = b / a;
+ if((small_a && (ratio * l2 < 0.1)) || (!small_a && (l1 / ratio > 0.1)))
+ {
+ T l3 = boost::math::expm1(ratio * boost::math::log1p(l2, pol), pol);
+ l3 = l1 + l3 + l3 * l1;
+ l3 = a * boost::math::log1p(l3, pol);
+ result *= exp(l3);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ T l3 = boost::math::expm1(boost::math::log1p(l1, pol) / ratio, pol);
+ l3 = l2 + l3 + l3 * l2;
+ l3 = b * boost::math::log1p(l3, pol);
+ result *= exp(l3);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ else if(fabs(l1) < fabs(l2))
+ {
+ // First base near 1 only:
+ T l = a * boost::math::log1p(l1, pol)
+ + b * log((y * cgh) / bgh);
+ result *= exp(l);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ // Second base near 1 only:
+ T l = b * boost::math::log1p(l2, pol)
+ + a * log((x * cgh) / agh);
+ result *= exp(l);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ else
+ {
+ // general case:
+ T b1 = (x * cgh) / agh;
+ T b2 = (y * cgh) / bgh;
+ l1 = a * log(b1);
+ l2 = b * log(b2);
+ BOOST_MATH_INSTRUMENT_VARIABLE(b1);
+ BOOST_MATH_INSTRUMENT_VARIABLE(b2);
+ BOOST_MATH_INSTRUMENT_VARIABLE(l1);
+ BOOST_MATH_INSTRUMENT_VARIABLE(l2);
+ if((l1 >= tools::log_max_value<T>())
+ || (l1 <= tools::log_min_value<T>())
+ || (l2 >= tools::log_max_value<T>())
+ || (l2 <= tools::log_min_value<T>())
+ )
+ {
+ // Oops, overflow, sidestep:
+ if(a < b)
+ result *= pow(pow(b2, b/a) * b1, a);
+ else
+ result *= pow(pow(b1, a/b) * b2, b);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ // finally the normal case:
+ result *= pow(b1, a) * pow(b2, b);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ // combine with the leftover terms from the Lanczos approximation:
+ result *= sqrt(bgh / boost::math::constants::e<T>());
+ result *= sqrt(agh / cgh);
+ result *= prefix;
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+
+ return result;
+}
+//
+// Compute the leading power terms in the incomplete Beta:
+//
+// (x^a)(y^b)/Beta(a,b) when normalised, and
+// (x^a)(y^b) otherwise.
+//
+// Almost all of the error in the incomplete beta comes from this
+// function: particularly when a and b are large. Computing large
+// powers are *hard* though, and using logarithms just leads to
+// horrendous cancellation errors.
+//
+// This version is generic, slow, and does not use the Lanczos approximation.
+//
+template <class T, class Policy>
+T ibeta_power_terms(T a,
+ T b,
+ T x,
+ T y,
+ const boost::math::lanczos::undefined_lanczos&,
+ bool normalised,
+ const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ if(!normalised)
+ {
+ return pow(x, a) * pow(y, b);
+ }
+
+ T result= 0; // assignment here silences warnings later
+
+ T c = a + b;
+
+ // integration limits for the gamma functions:
+ //T la = (std::max)(T(10), a);
+ //T lb = (std::max)(T(10), b);
+ //T lc = (std::max)(T(10), a+b);
+ T la = a + 5;
+ T lb = b + 5;
+ T lc = a + b + 5;
+ // gamma function partials:
+ T sa = detail::lower_gamma_series(a, la, pol) / a;
+ sa += detail::upper_gamma_fraction(a, la, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sb = detail::lower_gamma_series(b, lb, pol) / b;
+ sb += detail::upper_gamma_fraction(b, lb, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sc = detail::lower_gamma_series(c, lc, pol) / c;
+ sc += detail::upper_gamma_fraction(c, lc, ::boost::math::policies::get_epsilon<T, Policy>());
+ // gamma function powers combined with incomplete beta powers:
+
+ T b1 = (x * lc) / la;
+ T b2 = (y * lc) / lb;
+ T e1 = lc - la - lb;
+ T lb1 = a * log(b1);
+ T lb2 = b * log(b2);
+
+ if((lb1 >= tools::log_max_value<T>())
+ || (lb1 <= tools::log_min_value<T>())
+ || (lb2 >= tools::log_max_value<T>())
+ || (lb2 <= tools::log_min_value<T>())
+ || (e1 >= tools::log_max_value<T>())
+ || (e1 <= tools::log_min_value<T>())
+ )
+ {
+ result = exp(lb1 + lb2 - e1);
+ }
+ else
+ {
+ T p1, p2;
+ if((fabs(b1 - 1) * a < 10) && (a > 1))
+ p1 = exp(a * boost::math::log1p((x * b - y * la) / la, pol));
+ else
+ p1 = pow(b1, a);
+ if((fabs(b2 - 1) * b < 10) && (b > 1))
+ p2 = exp(b * boost::math::log1p((y * a - x * lb) / lb, pol));
+ else
+ p2 = pow(b2, b);
+ T p3 = exp(e1);
+ result = p1 * p2 / p3;
+ }
+ // and combine with the remaining gamma function components:
+ result /= sa * sb / sc;
+
+ return result;
+}
+//
+// Series approximation to the incomplete beta:
+//
+template <class T>
+struct ibeta_series_t
+{
+ typedef T result_type;
+ ibeta_series_t(T a_, T b_, T x_, T mult) : result(mult), x(x_), apn(a_), poch(1-b_), n(1) {}
+ T operator()()
+ {
+ T r = result / apn;
+ apn += 1;
+ result *= poch * x / n;
+ ++n;
+ poch += 1;
+ return r;
+ }
+private:
+ T result, x, apn, poch;
+ int n;
+};
+
+template <class T, class Lanczos, class Policy>
+T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool normalised, T* p_derivative, T y, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T result;
+
+ BOOST_ASSERT((p_derivative == 0) || normalised);
+
+ if(normalised)
+ {
+ T c = a + b;
+
+ // incomplete beta power term, combined with the Lanczos approximation:
+ T agh = a + Lanczos::g() - T(0.5);
+ T bgh = b + Lanczos::g() - T(0.5);
+ T cgh = c + Lanczos::g() - T(0.5);
+ result = Lanczos::lanczos_sum_expG_scaled(c) / (Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b));
+ if(a * b < bgh * 10)
+ result *= exp((b - 0.5f) * boost::math::log1p(a / bgh, pol));
+ else
+ result *= pow(cgh / bgh, b - 0.5f);
+ result *= pow(x * cgh / agh, a);
+ result *= sqrt(agh / boost::math::constants::e<T>());
+
+ if(p_derivative)
+ {
+ *p_derivative = result * pow(y, b);
+ BOOST_ASSERT(*p_derivative >= 0);
+ }
+ }
+ else
+ {
+ // Non-normalised, just compute the power:
+ result = pow(x, a);
+ }
+ if(result < tools::min_value<T>())
+ return s0; // Safeguard: series can't cope with denorms.
+ ibeta_series_t<T> s(a, b, x, result);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+ result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, s0);
+ policies::check_series_iterations<T>("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (with lanczos)", max_iter, pol);
+ return result;
+}
+//
+// Incomplete Beta series again, this time without Lanczos support:
+//
+template <class T, class Policy>
+T ibeta_series(T a, T b, T x, T s0, const boost::math::lanczos::undefined_lanczos&, bool normalised, T* p_derivative, T y, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T result;
+ BOOST_ASSERT((p_derivative == 0) || normalised);
+
+ if(normalised)
+ {
+ T c = a + b;
+
+ // figure out integration limits for the gamma function:
+ //T la = (std::max)(T(10), a);
+ //T lb = (std::max)(T(10), b);
+ //T lc = (std::max)(T(10), a+b);
+ T la = a + 5;
+ T lb = b + 5;
+ T lc = a + b + 5;
+
+ // calculate the gamma parts:
+ T sa = detail::lower_gamma_series(a, la, pol) / a;
+ sa += detail::upper_gamma_fraction(a, la, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sb = detail::lower_gamma_series(b, lb, pol) / b;
+ sb += detail::upper_gamma_fraction(b, lb, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sc = detail::lower_gamma_series(c, lc, pol) / c;
+ sc += detail::upper_gamma_fraction(c, lc, ::boost::math::policies::get_epsilon<T, Policy>());
+
+ // and their combined power-terms:
+ T b1 = (x * lc) / la;
+ T b2 = lc/lb;
+ T e1 = lc - la - lb;
+ T lb1 = a * log(b1);
+ T lb2 = b * log(b2);
+
+ if((lb1 >= tools::log_max_value<T>())
+ || (lb1 <= tools::log_min_value<T>())
+ || (lb2 >= tools::log_max_value<T>())
+ || (lb2 <= tools::log_min_value<T>())
+ || (e1 >= tools::log_max_value<T>())
+ || (e1 <= tools::log_min_value<T>()) )
+ {
+ T p = lb1 + lb2 - e1;
+ result = exp(p);
+ }
+ else
+ {
+ result = pow(b1, a);
+ if(a * b < lb * 10)
+ result *= exp(b * boost::math::log1p(a / lb, pol));
+ else
+ result *= pow(b2, b);
+ result /= exp(e1);
+ }
+ // and combine the results:
+ result /= sa * sb / sc;
+
+ if(p_derivative)
+ {
+ *p_derivative = result * pow(y, b);
+ BOOST_ASSERT(*p_derivative >= 0);
+ }
+ }
+ else
+ {
+ // Non-normalised, just compute the power:
+ result = pow(x, a);
+ }
+ if(result < tools::min_value<T>())
+ return s0; // Safeguard: series can't cope with denorms.
+ ibeta_series_t<T> s(a, b, x, result);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+ result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, s0);
+ policies::check_series_iterations<T>("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (without lanczos)", max_iter, pol);
+ return result;
+}
+
+//
+// Continued fraction for the incomplete beta:
+//
+template <class T>
+struct ibeta_fraction2_t
+{
+ typedef std::pair<T, T> result_type;
+
+ ibeta_fraction2_t(T a_, T b_, T x_, T y_) : a(a_), b(b_), x(x_), y(y_), m(0) {}
+
+ result_type operator()()
+ {
+ T aN = (a + m - 1) * (a + b + m - 1) * m * (b - m) * x * x;
+ T denom = (a + 2 * m - 1);
+ aN /= denom * denom;
+
+ T bN = m;
+ bN += (m * (b - m) * x) / (a + 2*m - 1);
+ bN += ((a + m) * (a * y - b * x + 1 + m *(2 - x))) / (a + 2*m + 1);
+
+ ++m;
+
+ return std::make_pair(aN, bN);
+ }
+
+private:
+ T a, b, x, y;
+ int m;
+};
+//
+// Evaluate the incomplete beta via the continued fraction representation:
+//
+template <class T, class Policy>
+inline T ibeta_fraction2(T a, T b, T x, T y, const Policy& pol, bool normalised, T* p_derivative)
+{
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+ BOOST_MATH_STD_USING
+ T result = ibeta_power_terms(a, b, x, y, lanczos_type(), normalised, pol);
+ if(p_derivative)
+ {
+ *p_derivative = result;
+ BOOST_ASSERT(*p_derivative >= 0);
+ }
+ if(result == 0)
+ return result;
+
+ ibeta_fraction2_t<T> f(a, b, x, y);
+ T fract = boost::math::tools::continued_fraction_b(f, boost::math::policies::get_epsilon<T, Policy>());
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ return result / fract;
+}
+//
+// Computes the difference between ibeta(a,b,x) and ibeta(a+k,b,x):
+//
+template <class T, class Policy>
+T ibeta_a_step(T a, T b, T x, T y, int k, const Policy& pol, bool normalised, T* p_derivative)
+{
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(k);
+
+ T prefix = ibeta_power_terms(a, b, x, y, lanczos_type(), normalised, pol);
+ if(p_derivative)
+ {
+ *p_derivative = prefix;
+ BOOST_ASSERT(*p_derivative >= 0);
+ }
+ prefix /= a;
+ if(prefix == 0)
+ return prefix;
+ T sum = 1;
+ T term = 1;
+ // series summation from 0 to k-1:
+ for(int i = 0; i < k-1; ++i)
+ {
+ term *= (a+b+i) * x / (a+i+1);
+ sum += term;
+ }
+ prefix *= sum;
+
+ return prefix;
+}
+//
+// This function is only needed for the non-regular incomplete beta,
+// it computes the delta in:
+// beta(a,b,x) = prefix + delta * beta(a+k,b,x)
+// it is currently only called for small k.
+//
+template <class T>
+inline T rising_factorial_ratio(T a, T b, int k)
+{
+ // calculate:
+ // (a)(a+1)(a+2)...(a+k-1)
+ // _______________________
+ // (b)(b+1)(b+2)...(b+k-1)
+
+ // This is only called with small k, for large k
+ // it is grossly inefficient, do not use outside it's
+ // intended purpose!!!
+ BOOST_MATH_INSTRUMENT_VARIABLE(k);
+ if(k == 0)
+ return 1;
+ T result = 1;
+ for(int i = 0; i < k; ++i)
+ result *= (a+i) / (b+i);
+ return result;
+}
+//
+// Routine for a > 15, b < 1
+//
+// Begin by figuring out how large our table of Pn's should be,
+// quoted accuracies are "guestimates" based on empiracal observation.
+// Note that the table size should never exceed the size of our
+// tables of factorials.
+//
+template <class T>
+struct Pn_size
+{
+ // This is likely to be enough for ~35-50 digit accuracy
+ // but it's hard to quantify exactly:
+ BOOST_STATIC_CONSTANT(unsigned, value = 50);
+ BOOST_STATIC_ASSERT(::boost::math::max_factorial<T>::value >= 100);
+};
+template <>
+struct Pn_size<float>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 15); // ~8-15 digit accuracy
+ BOOST_STATIC_ASSERT(::boost::math::max_factorial<float>::value >= 30);
+};
+template <>
+struct Pn_size<double>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 30); // 16-20 digit accuracy
+ BOOST_STATIC_ASSERT(::boost::math::max_factorial<double>::value >= 60);
+};
+template <>
+struct Pn_size<long double>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 50); // ~35-50 digit accuracy
+ BOOST_STATIC_ASSERT(::boost::math::max_factorial<long double>::value >= 100);
+};
+
+template <class T, class Policy>
+T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Policy& pol, bool normalised)
+{
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+ BOOST_MATH_STD_USING
+ //
+ // This is DiDonato and Morris's BGRAT routine, see Eq's 9 through 9.6.
+ //
+ // Some values we'll need later, these are Eq 9.1:
+ //
+ T bm1 = b - 1;
+ T t = a + bm1 / 2;
+ T lx, u;
+ if(y < 0.35)
+ lx = boost::math::log1p(-y, pol);
+ else
+ lx = log(x);
+ u = -t * lx;
+ // and from from 9.2:
+ T prefix;
+ T h = regularised_gamma_prefix(b, u, pol, lanczos_type());
+ if(h <= tools::min_value<T>())
+ return s0;
+ if(normalised)
+ {
+ prefix = h / boost::math::tgamma_delta_ratio(a, b, pol);
+ prefix /= pow(t, b);
+ }
+ else
+ {
+ prefix = full_igamma_prefix(b, u, pol) / pow(t, b);
+ }
+ prefix *= mult;
+ //
+ // now we need the quantity Pn, unfortunatately this is computed
+ // recursively, and requires a full history of all the previous values
+ // so no choice but to declare a big table and hope it's big enough...
+ //
+ T p[ ::boost::math::detail::Pn_size<T>::value ] = { 1 }; // see 9.3.
+ //
+ // Now an initial value for J, see 9.6:
+ //
+ T j = boost::math::gamma_q(b, u, pol) / h;
+ //
+ // Now we can start to pull things together and evaluate the sum in Eq 9:
+ //
+ T sum = s0 + prefix * j; // Value at N = 0
+ // some variables we'll need:
+ unsigned tnp1 = 1; // 2*N+1
+ T lx2 = lx / 2;
+ lx2 *= lx2;
+ T lxp = 1;
+ T t4 = 4 * t * t;
+ T b2n = b;
+
+ for(unsigned n = 1; n < sizeof(p)/sizeof(p[0]); ++n)
+ {
+ /*
+ // debugging code, enable this if you want to determine whether
+ // the table of Pn's is large enough...
+ //
+ static int max_count = 2;
+ if(n > max_count)
+ {
+ max_count = n;
+ std::cerr << "Max iterations in BGRAT was " << n << std::endl;
+ }
+ */
+ //
+ // begin by evaluating the next Pn from Eq 9.4:
+ //
+ tnp1 += 2;
+ p[n] = 0;
+ T mbn = b - n;
+ unsigned tmp1 = 3;
+ for(unsigned m = 1; m < n; ++m)
+ {
+ mbn = m * b - n;
+ p[n] += mbn * p[n-m] / boost::math::unchecked_factorial<T>(tmp1);
+ tmp1 += 2;
+ }
+ p[n] /= n;
+ p[n] += bm1 / boost::math::unchecked_factorial<T>(tnp1);
+ //
+ // Now we want Jn from Jn-1 using Eq 9.6:
+ //
+ j = (b2n * (b2n + 1) * j + (u + b2n + 1) * lxp) / t4;
+ lxp *= lx2;
+ b2n += 2;
+ //
+ // pull it together with Eq 9:
+ //
+ T r = prefix * p[n] * j;
+ sum += r;
+ if(r > 1)
+ {
+ if(fabs(r) < fabs(tools::epsilon<T>() * sum))
+ break;
+ }
+ else
+ {
+ if(fabs(r / tools::epsilon<T>()) < fabs(sum))
+ break;
+ }
+ }
+ return sum;
+} // template <class T, class Lanczos>T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Lanczos& l, bool normalised)
+
+//
+// For integer arguments we can relate the incomplete beta to the
+// complement of the binomial distribution cdf and use this finite sum.
+//
+template <class T>
+inline T binomial_ccdf(T n, T k, T x, T y)
+{
+ BOOST_MATH_STD_USING // ADL of std names
+ T result = pow(x, n);
+ T term = result;
+ for(unsigned i = itrunc(T(n - 1)); i > k; --i)
+ {
+ term *= ((i + 1) * y) / ((n - i) * x) ;
+ result += term;
+ }
+
+ return result;
+}
+
+
+//
+// The incomplete beta function implementation:
+// This is just a big bunch of spagetti code to divide up the
+// input range and select the right implementation method for
+// each domain:
+//
+template <class T, class Policy>
+T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, bool normalised, T* p_derivative)
+{
+ static const char* function = "boost::math::ibeta<%1%>(%1%, %1%, %1%)";
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+ BOOST_MATH_STD_USING // for ADL of std math functions.
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(a);
+ BOOST_MATH_INSTRUMENT_VARIABLE(b);
+ BOOST_MATH_INSTRUMENT_VARIABLE(x);
+ BOOST_MATH_INSTRUMENT_VARIABLE(inv);
+ BOOST_MATH_INSTRUMENT_VARIABLE(normalised);
+
+ bool invert = inv;
+ T fract;
+ T y = 1 - x;
+
+ BOOST_ASSERT((p_derivative == 0) || normalised);
+
+ if(p_derivative)
+ *p_derivative = -1; // value not set.
+
+ if((x < 0) || (x > 1))
+ return policies::raise_domain_error<T>(function, "Parameter x outside the range [0,1] in the incomplete beta function (got x=%1%).", x, pol);
+
+ if(normalised)
+ {
+ if(a < 0)
+ return policies::raise_domain_error<T>(function, "The argument a to the incomplete beta function must be >= zero (got a=%1%).", a, pol);
+ if(b < 0)
+ return policies::raise_domain_error<T>(function, "The argument b to the incomplete beta function must be >= zero (got b=%1%).", b, pol);
+ // extend to a few very special cases:
+ if(a == 0)
+ {
+ if(b == 0)
+ return policies::raise_domain_error<T>(function, "The arguments a and b to the incomplete beta function cannot both be zero, with x=%1%.", x, pol);
+ if(b > 0)
+ return inv ? 0 : 1;
+ }
+ else if(b == 0)
+ {
+ if(a > 0)
+ return inv ? 1 : 0;
+ }
+ }
+ else
+ {
+ if(a <= 0)
+ return policies::raise_domain_error<T>(function, "The argument a to the incomplete beta function must be greater than zero (got a=%1%).", a, pol);
+ if(b <= 0)
+ return policies::raise_domain_error<T>(function, "The argument b to the incomplete beta function must be greater than zero (got b=%1%).", b, pol);
+ }
+
+ if(x == 0)
+ {
+ if(p_derivative)
+ {
+ *p_derivative = (a == 1) ? (T)1 : (a < 1) ? T(tools::max_value<T>() / 2) : T(tools::min_value<T>() * 2);
+ }
+ return (invert ? (normalised ? T(1) : boost::math::beta(a, b, pol)) : T(0));
+ }
+ if(x == 1)
+ {
+ if(p_derivative)
+ {
+ *p_derivative = (b == 1) ? T(1) : (b < 1) ? T(tools::max_value<T>() / 2) : T(tools::min_value<T>() * 2);
+ }
+ return (invert == 0 ? (normalised ? 1 : boost::math::beta(a, b, pol)) : 0);
+ }
+ if((a == 0.5f) && (b == 0.5f))
+ {
+ // We have an arcsine distribution:
+ if(p_derivative)
+ {
+ *p_derivative = (invert ? -1 : 1) / constants::pi<T>() * sqrt(y * x);
+ }
+ T p = invert ? asin(sqrt(y)) / constants::half_pi<T>() : asin(sqrt(x)) / constants::half_pi<T>();
+ if(!normalised)
+ p *= constants::pi<T>();
+ return p;
+ }
+ if(a == 1)
+ {
+ std::swap(a, b);
+ std::swap(x, y);
+ invert = !invert;
+ }
+ if(b == 1)
+ {
+ //
+ // Special case see: http://functions.wolfram.com/GammaBetaErf/BetaRegularized/03/01/01/
+ //
+ if(a == 1)
+ {
+ if(p_derivative)
+ *p_derivative = invert ? -1 : 1;
+ return invert ? y : x;
+ }
+
+ if(p_derivative)
+ {
+ *p_derivative = (invert ? -1 : 1) * a * pow(x, a - 1);
+ }
+ T p;
+ if(y < 0.5)
+ p = invert ? T(-boost::math::expm1(a * boost::math::log1p(-y, pol), pol)) : T(exp(a * boost::math::log1p(-y, pol)));
+ else
+ p = invert ? T(-boost::math::powm1(x, a, pol)) : T(pow(x, a));
+ if(!normalised)
+ p /= a;
+ return p;
+ }
+
+ if((std::min)(a, b) <= 1)
+ {
+ if(x > 0.5)
+ {
+ std::swap(a, b);
+ std::swap(x, y);
+ invert = !invert;
+ BOOST_MATH_INSTRUMENT_VARIABLE(invert);
+ }
+ if((std::max)(a, b) <= 1)
+ {
+ // Both a,b < 1:
+ if((a >= (std::min)(T(0.2), b)) || (pow(x, a) <= 0.9))
+ {
+ if(!invert)
+ {
+ fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = -(normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else
+ {
+ std::swap(a, b);
+ std::swap(x, y);
+ invert = !invert;
+ if(y >= 0.3)
+ {
+ if(!invert)
+ {
+ fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = -(normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else
+ {
+ // Sidestep on a, and then use the series representation:
+ T prefix;
+ if(!normalised)
+ {
+ prefix = rising_factorial_ratio(T(a+b), a, 20);
+ }
+ else
+ {
+ prefix = 1;
+ }
+ fract = ibeta_a_step(a, b, x, y, 20, pol, normalised, p_derivative);
+ if(!invert)
+ {
+ fract = beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract -= (normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ }
+ }
+ else
+ {
+ // One of a, b < 1 only:
+ if((b <= 1) || ((x < 0.1) && (pow(b * x, a) <= 0.7)))
+ {
+ if(!invert)
+ {
+ fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = -(normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else
+ {
+ std::swap(a, b);
+ std::swap(x, y);
+ invert = !invert;
+
+ if(y >= 0.3)
+ {
+ if(!invert)
+ {
+ fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = -(normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else if(a >= 15)
+ {
+ if(!invert)
+ {
+ fract = beta_small_b_large_a_series(a, b, x, y, T(0), T(1), pol, normalised);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = -(normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -beta_small_b_large_a_series(a, b, x, y, fract, T(1), pol, normalised);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else
+ {
+ // Sidestep to improve errors:
+ T prefix;
+ if(!normalised)
+ {
+ prefix = rising_factorial_ratio(T(a+b), a, 20);
+ }
+ else
+ {
+ prefix = 1;
+ }
+ fract = ibeta_a_step(a, b, x, y, 20, pol, normalised, p_derivative);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ if(!invert)
+ {
+ fract = beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract -= (normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Both a,b >= 1:
+ T lambda;
+ if(a < b)
+ {
+ lambda = a - (a + b) * x;
+ }
+ else
+ {
+ lambda = (a + b) * y - b;
+ }
+ if(lambda < 0)
+ {
+ std::swap(a, b);
+ std::swap(x, y);
+ invert = !invert;
+ BOOST_MATH_INSTRUMENT_VARIABLE(invert);
+ }
+
+ if(b < 40)
+ {
+ if((floor(a) == a) && (floor(b) == b) && (a < (std::numeric_limits<int>::max)() - 100))
+ {
+ // relate to the binomial distribution and use a finite sum:
+ T k = a - 1;
+ T n = b + k;
+ fract = binomial_ccdf(n, k, x, y);
+ if(!normalised)
+ fract *= boost::math::beta(a, b, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else if(b * x <= 0.7)
+ {
+ if(!invert)
+ {
+ fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = -(normalised ? 1 : boost::math::beta(a, b, pol));
+ invert = false;
+ fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else if(a > 15)
+ {
+ // sidestep so we can use the series representation:
+ int n = itrunc(T(floor(b)), pol);
+ if(n == b)
+ --n;
+ T bbar = b - n;
+ T prefix;
+ if(!normalised)
+ {
+ prefix = rising_factorial_ratio(T(a+bbar), bbar, n);
+ }
+ else
+ {
+ prefix = 1;
+ }
+ fract = ibeta_a_step(bbar, a, y, x, n, pol, normalised, static_cast<T*>(0));
+ fract = beta_small_b_large_a_series(a, bbar, x, y, fract, T(1), pol, normalised);
+ fract /= prefix;
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else if(normalised)
+ {
+ // the formula here for the non-normalised case is tricky to figure
+ // out (for me!!), and requires two pochhammer calculations rather
+ // than one, so leave it for now....
+ int n = itrunc(T(floor(b)), pol);
+ T bbar = b - n;
+ if(bbar <= 0)
+ {
+ --n;
+ bbar += 1;
+ }
+ fract = ibeta_a_step(bbar, a, y, x, n, pol, normalised, static_cast<T*>(0));
+ fract += ibeta_a_step(a, bbar, x, y, 20, pol, normalised, static_cast<T*>(0));
+ if(invert)
+ fract -= (normalised ? 1 : boost::math::beta(a, b, pol));
+ //fract = ibeta_series(a+20, bbar, x, fract, l, normalised, p_derivative, y);
+ fract = beta_small_b_large_a_series(T(a+20), bbar, x, y, fract, T(1), pol, normalised);
+ if(invert)
+ {
+ fract = -fract;
+ invert = false;
+ }
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ else
+ {
+ fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ else
+ {
+ fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative);
+ BOOST_MATH_INSTRUMENT_VARIABLE(fract);
+ }
+ }
+ if(p_derivative)
+ {
+ if(*p_derivative < 0)
+ {
+ *p_derivative = ibeta_power_terms(a, b, x, y, lanczos_type(), true, pol);
+ }
+ T div = y * x;
+
+ if(*p_derivative != 0)
+ {
+ if((tools::max_value<T>() * div < *p_derivative))
+ {
+ // overflow, return an arbitarily large value:
+ *p_derivative = tools::max_value<T>() / 2;
+ }
+ else
+ {
+ *p_derivative /= div;
+ }
+ }
+ }
+ return invert ? (normalised ? 1 : boost::math::beta(a, b, pol)) - fract : fract;
+} // template <class T, class Lanczos>T ibeta_imp(T a, T b, T x, const Lanczos& l, bool inv, bool normalised)
+
+template <class T, class Policy>
+inline T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, bool normalised)
+{
+ return ibeta_imp(a, b, x, pol, inv, normalised, static_cast<T*>(0));
+}
+
+template <class T, class Policy>
+T ibeta_derivative_imp(T a, T b, T x, const Policy& pol)
+{
+ static const char* function = "ibeta_derivative<%1%>(%1%,%1%,%1%)";
+ //
+ // start with the usual error checks:
+ //
+ if(a <= 0)
+ return policies::raise_domain_error<T>(function, "The argument a to the incomplete beta function must be greater than zero (got a=%1%).", a, pol);
+ if(b <= 0)
+ return policies::raise_domain_error<T>(function, "The argument b to the incomplete beta function must be greater than zero (got b=%1%).", b, pol);
+ if((x < 0) || (x > 1))
+ return policies::raise_domain_error<T>(function, "Parameter x outside the range [0,1] in the incomplete beta function (got x=%1%).", x, pol);
+ //
+ // Now the corner cases:
+ //
+ if(x == 0)
+ {
+ return (a > 1) ? 0 :
+ (a == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error<T>(function, 0, pol);
+ }
+ else if(x == 1)
+ {
+ return (b > 1) ? 0 :
+ (b == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error<T>(function, 0, pol);
+ }
+ //
+ // Now the regular cases:
+ //
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+ T f1 = ibeta_power_terms<T>(a, b, x, 1 - x, lanczos_type(), true, pol);
+ T y = (1 - x) * x;
+
+ if(f1 == 0)
+ return 0;
+
+ if((tools::max_value<T>() * y < f1))
+ {
+ // overflow:
+ return policies::raise_overflow_error<T>(function, 0, pol);
+ }
+
+ f1 /= y;
+
+ return f1;
+}
+//
+// Some forwarding functions that dis-ambiguate the third argument type:
+//
+template <class RT1, class RT2, class Policy>
+inline typename tools::promote_args<RT1, RT2>::type
+ beta(RT1 a, RT2 b, const Policy&, const mpl::true_*)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<RT1, RT2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::beta_imp(static_cast<value_type>(a), static_cast<value_type>(b), evaluation_type(), forwarding_policy()), "boost::math::beta<%1%>(%1%,%1%)");
+}
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ beta(RT1 a, RT2 b, RT3 x, const mpl::false_*)
+{
+ return boost::math::beta(a, b, x, policies::policy<>());
+}
+} // namespace detail
+
+//
+// The actual function entry-points now follow, these just figure out
+// which Lanczos approximation to use
+// and forward to the implementation functions:
+//
+template <class RT1, class RT2, class A>
+inline typename tools::promote_args<RT1, RT2, A>::type
+ beta(RT1 a, RT2 b, A arg)
+{
+ typedef typename policies::is_policy<A>::type tag;
+ return boost::math::detail::beta(a, b, arg, static_cast<tag*>(0));
+}
+
+template <class RT1, class RT2>
+inline typename tools::promote_args<RT1, RT2>::type
+ beta(RT1 a, RT2 b)
+{
+ return boost::math::beta(a, b, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ beta(RT1 a, RT2 b, RT3 x, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::ibeta_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(x), forwarding_policy(), false, false), "boost::math::beta<%1%>(%1%,%1%,%1%)");
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ betac(RT1 a, RT2 b, RT3 x, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::ibeta_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(x), forwarding_policy(), true, false), "boost::math::betac<%1%>(%1%,%1%,%1%)");
+}
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ betac(RT1 a, RT2 b, RT3 x)
+{
+ return boost::math::betac(a, b, x, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta(RT1 a, RT2 b, RT3 x, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::ibeta_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(x), forwarding_policy(), false, true), "boost::math::ibeta<%1%>(%1%,%1%,%1%)");
+}
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta(RT1 a, RT2 b, RT3 x)
+{
+ return boost::math::ibeta(a, b, x, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac(RT1 a, RT2 b, RT3 x, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::ibeta_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(x), forwarding_policy(), true, true), "boost::math::ibetac<%1%>(%1%,%1%,%1%)");
+}
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac(RT1 a, RT2 b, RT3 x)
+{
+ return boost::math::ibetac(a, b, x, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::ibeta_derivative_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(x), forwarding_policy()), "boost::math::ibeta_derivative<%1%>(%1%,%1%,%1%)");
+}
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_derivative(RT1 a, RT2 b, RT3 x)
+{
+ return boost::math::ibeta_derivative(a, b, x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#include <boost/math/special_functions/detail/ibeta_inverse.hpp>
+#include <boost/math/special_functions/detail/ibeta_inv_ab.hpp>
+
+#endif // BOOST_MATH_SPECIAL_BETA_HPP
+
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/cbrt.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/cbrt.hpp
new file mode 100644
index 00000000000..0fc6e0742af
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/cbrt.hpp
@@ -0,0 +1,180 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SF_CBRT_HPP
+#define BOOST_MATH_SF_CBRT_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/mpl/divides.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+
+struct big_int_type
+{
+ operator boost::uintmax_t()const;
+};
+
+template <class T>
+struct largest_cbrt_int_type
+{
+ typedef typename mpl::if_<
+ boost::is_convertible<big_int_type, T>,
+ boost::uintmax_t,
+ unsigned int
+ >::type type;
+};
+
+template <class T, class Policy>
+T cbrt_imp(T z, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ //
+ // cbrt approximation for z in the range [0.5,1]
+ // It's hard to say what number of terms gives the optimum
+ // trade off between precision and performance, this seems
+ // to be about the best for double precision.
+ //
+ // Maximum Deviation Found: 1.231e-006
+ // Expected Error Term: -1.231e-006
+ // Maximum Relative Change in Control Points: 5.982e-004
+ //
+ static const T P[] = {
+ static_cast<T>(0.37568269008611818),
+ static_cast<T>(1.3304968705558024),
+ static_cast<T>(-1.4897101632445036),
+ static_cast<T>(1.2875573098219835),
+ static_cast<T>(-0.6398703759826468),
+ static_cast<T>(0.13584489959258635),
+ };
+ static const T correction[] = {
+ static_cast<T>(0.62996052494743658238360530363911), // 2^-2/3
+ static_cast<T>(0.79370052598409973737585281963615), // 2^-1/3
+ static_cast<T>(1),
+ static_cast<T>(1.2599210498948731647672106072782), // 2^1/3
+ static_cast<T>(1.5874010519681994747517056392723), // 2^2/3
+ };
+
+ if(!(boost::math::isfinite)(z))
+ {
+ return policies::raise_domain_error("boost::math::cbrt<%1%>(%1%)", "Argument to function must be finite but got %1%.", z, pol);
+ }
+
+ int i_exp, sign(1);
+ if(z < 0)
+ {
+ z = -z;
+ sign = -sign;
+ }
+ if(z == 0)
+ return 0;
+
+ T guess = frexp(z, &i_exp);
+ int original_i_exp = i_exp; // save for later
+ guess = tools::evaluate_polynomial(P, guess);
+ int i_exp3 = i_exp / 3;
+
+ typedef typename largest_cbrt_int_type<T>::type shift_type;
+
+ BOOST_STATIC_ASSERT( ::std::numeric_limits<shift_type>::radix == 2);
+
+ if(abs(i_exp3) < std::numeric_limits<shift_type>::digits)
+ {
+ if(i_exp3 > 0)
+ guess *= shift_type(1u) << i_exp3;
+ else
+ guess /= shift_type(1u) << -i_exp3;
+ }
+ else
+ {
+ guess = ldexp(guess, i_exp3);
+ }
+ i_exp %= 3;
+ guess *= correction[i_exp + 2];
+ //
+ // Now inline Halley iteration.
+ // We do this here rather than calling tools::halley_iterate since we can
+ // simplify the expressions algebraically, and don't need most of the error
+ // checking of the boilerplate version as we know in advance that the function
+ // is well behaved...
+ //
+ typedef typename policies::precision<T, Policy>::type prec;
+ typedef typename mpl::divides<prec, mpl::int_<3> >::type prec3;
+ typedef typename mpl::plus<prec3, mpl::int_<3> >::type new_prec;
+ typedef typename policies::normalise<Policy, policies::digits2<new_prec::value> >::type new_policy;
+ //
+ // Epsilon calculation uses compile time arithmetic when it's available for type T,
+ // otherwise uses ldexp to calculate at runtime:
+ //
+ T eps = (new_prec::value > 3) ? policies::get_epsilon<T, new_policy>() : ldexp(T(1), -2 - tools::digits<T>() / 3);
+ T diff;
+
+ if(original_i_exp < std::numeric_limits<T>::max_exponent - 3)
+ {
+ //
+ // Safe from overflow, use the fast method:
+ //
+ do
+ {
+ T g3 = guess * guess * guess;
+ diff = (g3 + z + z) / (g3 + g3 + z);
+ guess *= diff;
+ }
+ while(fabs(1 - diff) > eps);
+ }
+ else
+ {
+ //
+ // Either we're ready to overflow, or we can't tell because numeric_limits isn't
+ // available for type T:
+ //
+ do
+ {
+ T g2 = guess * guess;
+ diff = (g2 - z / guess) / (2 * guess + z / g2);
+ guess -= diff;
+ }
+ while((guess * eps) < fabs(diff));
+ }
+
+ return sign * guess;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type cbrt(T z, const Policy& pol)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ return static_cast<result_type>(detail::cbrt_imp(value_type(z), pol));
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type cbrt(T z)
+{
+ return cbrt(z, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SF_CBRT_HPP
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/bernoulli_details.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/bernoulli_details.hpp
new file mode 100644
index 00000000000..4114a0bd749
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/bernoulli_details.hpp
@@ -0,0 +1,652 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2013 John Maddock
+// Distributed under 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)
+
+#ifndef BOOST_MATH_BERNOULLI_DETAIL_HPP
+#define BOOST_MATH_BERNOULLI_DETAIL_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_mutex.hpp>
+#include <boost/math/tools/toms748_solve.hpp>
+
+#ifdef BOOST_HAS_THREADS
+
+#ifndef BOOST_NO_CXX11_HDR_ATOMIC
+# include <atomic>
+# define BOOST_MATH_ATOMIC_NS std
+#if ATOMIC_INT_LOCK_FREE == 2
+typedef std::atomic<int> atomic_counter_type;
+typedef int atomic_integer_type;
+#elif ATOMIC_SHORT_LOCK_FREE == 2
+typedef std::atomic<short> atomic_counter_type;
+typedef short atomic_integer_type;
+#elif ATOMIC_LONG_LOCK_FREE == 2
+typedef std::atomic<long> atomic_counter_type;
+typedef long atomic_integer_type;
+#elif ATOMIC_LLONG_LOCK_FREE == 2
+typedef std::atomic<long long> atomic_counter_type;
+typedef long long atomic_integer_type;
+#else
+# define BOOST_MATH_NO_ATOMIC_INT
+#endif
+
+#else // BOOST_NO_CXX11_HDR_ATOMIC
+//
+// We need Boost.Atomic, but on any platform that supports auto-linking we do
+// not need to link against a separate library:
+//
+#define BOOST_ATOMIC_NO_LIB
+#include <boost/atomic.hpp>
+# define BOOST_MATH_ATOMIC_NS boost
+
+namespace boost{ namespace math{ namespace detail{
+
+//
+// We need a type to use as an atomic counter:
+//
+#if BOOST_ATOMIC_INT_LOCK_FREE == 2
+typedef boost::atomic<int> atomic_counter_type;
+typedef int atomic_integer_type;
+#elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
+typedef boost::atomic<short> atomic_counter_type;
+typedef short atomic_integer_type;
+#elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
+typedef boost::atomic<long> atomic_counter_type;
+typedef long atomic_integer_type;
+#elif BOOST_ATOMIC_LLONG_LOCK_FREE == 2
+typedef boost::atomic<long long> atomic_counter_type;
+typedef long long atomic_integer_type;
+#else
+# define BOOST_MATH_NO_ATOMIC_INT
+#endif
+
+}}} // namespaces
+
+#endif // BOOST_NO_CXX11_HDR_ATOMIC
+
+#endif // BOOST_HAS_THREADS
+
+namespace boost{ namespace math{ namespace detail{
+//
+// Asymptotic expansion for B2n due to
+// Luschny LogB3 formula (http://www.luschny.de/math/primes/bernincl.html)
+//
+template <class T, class Policy>
+T b2n_asymptotic(int n)
+{
+ BOOST_MATH_STD_USING
+ const T nx = static_cast<T>(n);
+ const T nx2(nx * nx);
+
+ const T approximate_log_of_bernoulli_bn =
+ ((boost::math::constants::half<T>() + nx) * log(nx))
+ + ((boost::math::constants::half<T>() - nx) * log(boost::math::constants::pi<T>()))
+ + (((T(3) / 2) - nx) * boost::math::constants::ln_two<T>())
+ + ((nx * (T(2) - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520));
+ return ((n / 2) & 1 ? 1 : -1) * (approximate_log_of_bernoulli_bn > tools::log_max_value<T>()
+ ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, nx, Policy())
+ : static_cast<T>(exp(approximate_log_of_bernoulli_bn)));
+}
+
+template <class T, class Policy>
+T t2n_asymptotic(int n)
+{
+ BOOST_MATH_STD_USING
+ // Just get B2n and convert to a Tangent number:
+ T t2n = fabs(b2n_asymptotic<T, Policy>(2 * n)) / (2 * n);
+ T p2 = ldexp(T(1), n);
+ if(tools::max_value<T>() / p2 < t2n)
+ return policies::raise_overflow_error<T>("boost::math::tangent_t2n<%1%>(std::size_t)", 0, T(n), Policy());
+ t2n *= p2;
+ p2 -= 1;
+ if(tools::max_value<T>() / p2 < t2n)
+ return policies::raise_overflow_error<T>("boost::math::tangent_t2n<%1%>(std::size_t)", 0, Policy());
+ t2n *= p2;
+ return t2n;
+}
+//
+// We need to know the approximate value of /n/ which will
+// cause bernoulli_b2n<T>(n) to return infinity - this allows
+// us to elude a great deal of runtime checking for values below
+// n, and only perform the full overflow checks when we know that we're
+// getting close to the point where our calculations will overflow.
+// We use Luschny's LogB3 formula (http://www.luschny.de/math/primes/bernincl.html)
+// to find the limit, and since we're dealing with the log of the Bernoulli numbers
+// we need only perform the calculation at double precision and not with T
+// (which may be a multiprecision type). The limit returned is within 1 of the true
+// limit for all the types tested. Note that although the code below is basically
+// the same as b2n_asymptotic above, it has been recast as a continuous real-valued
+// function as this makes the root finding go smoother/faster. It also omits the
+// sign of the Bernoulli number.
+//
+struct max_bernoulli_root_functor
+{
+ max_bernoulli_root_functor(long long t) : target(static_cast<double>(t)) {}
+ double operator()(double n)
+ {
+ BOOST_MATH_STD_USING
+
+ // Luschny LogB3(n) formula.
+
+ const double nx2(n * n);
+
+ const double approximate_log_of_bernoulli_bn
+ = ((boost::math::constants::half<double>() + n) * log(n))
+ + ((boost::math::constants::half<double>() - n) * log(boost::math::constants::pi<double>()))
+ + (((double(3) / 2) - n) * boost::math::constants::ln_two<double>())
+ + ((n * (2 - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520));
+
+ return approximate_log_of_bernoulli_bn - target;
+ }
+private:
+ double target;
+};
+
+template <class T, class Policy>
+inline std::size_t find_bernoulli_overflow_limit(const mpl::false_&)
+{
+ long long t = lltrunc(boost::math::tools::log_max_value<T>());
+ max_bernoulli_root_functor fun(t);
+ boost::math::tools::equal_floor tol;
+ boost::uintmax_t max_iter = boost::math::policies::get_max_root_iterations<Policy>();
+ return static_cast<std::size_t>(boost::math::tools::toms748_solve(fun, sqrt(double(t)), double(t), tol, max_iter).first) / 2;
+}
+
+template <class T, class Policy>
+inline std::size_t find_bernoulli_overflow_limit(const mpl::true_&)
+{
+ return max_bernoulli_index<bernoulli_imp_variant<T>::value>::value;
+}
+
+template <class T, class Policy>
+std::size_t b2n_overflow_limit()
+{
+ // This routine is called at program startup if it's called at all:
+ // that guarantees safe initialization of the static variable.
+ typedef mpl::bool_<(bernoulli_imp_variant<T>::value >= 1) && (bernoulli_imp_variant<T>::value <= 3)> tag_type;
+ static const std::size_t lim = find_bernoulli_overflow_limit<T, Policy>(tag_type());
+ return lim;
+}
+
+//
+// The tangent numbers grow larger much more rapidly than the Bernoulli numbers do....
+// so to compute the Bernoulli numbers from the tangent numbers, we need to avoid spurious
+// overflow in the calculation, we can do this by scaling all the tangent number by some scale factor:
+//
+template <class T>
+inline typename enable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2), T>::type tangent_scale_factor()
+{
+ BOOST_MATH_STD_USING
+ return ldexp(T(1), std::numeric_limits<T>::min_exponent + 5);
+}
+template <class T>
+inline typename disable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2), T>::type tangent_scale_factor()
+{
+ return tools::min_value<T>() * 16;
+}
+//
+// Initializer: ensure all our constants are initialized prior to the first call of main:
+//
+template <class T, class Policy>
+struct bernoulli_initializer
+{
+ struct init
+ {
+ init()
+ {
+ //
+ // We call twice, once to initialize our static table, and once to
+ // initialize our dymanic table:
+ //
+ boost::math::bernoulli_b2n<T>(2, Policy());
+ try{
+ boost::math::bernoulli_b2n<T>(max_bernoulli_b2n<T>::value + 1, Policy());
+ } catch(const std::overflow_error&){}
+ boost::math::tangent_t2n<T>(2, Policy());
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy>
+const typename bernoulli_initializer<T, Policy>::init bernoulli_initializer<T, Policy>::initializer;
+
+//
+// We need something to act as a cache for our calculated Bernoulli numbers. In order to
+// ensure both fast access and thread safety, we need a stable table which may be extended
+// in size, but which never reallocates: that way values already calculated may be accessed
+// concurrently with another thread extending the table with new values.
+//
+// Very very simple vector class that will never allocate more than once, we could use
+// boost::container::static_vector here, but that allocates on the stack, which may well
+// cause issues for the amount of memory we want in the extreme case...
+//
+template <class T>
+struct fixed_vector : private std::allocator<T>
+{
+ typedef unsigned size_type;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+ fixed_vector() : m_used(0)
+ {
+ std::size_t overflow_limit = 5 + b2n_overflow_limit<T, policies::policy<> >();
+ m_capacity = static_cast<unsigned>((std::min)(overflow_limit, static_cast<std::size_t>(100000u)));
+ m_data = this->allocate(m_capacity);
+ }
+ ~fixed_vector()
+ {
+ for(unsigned i = 0; i < m_used; ++i)
+ this->destroy(&m_data[i]);
+ this->deallocate(m_data, m_capacity);
+ }
+ T& operator[](unsigned n) { BOOST_ASSERT(n < m_used); return m_data[n]; }
+ const T& operator[](unsigned n)const { BOOST_ASSERT(n < m_used); return m_data[n]; }
+ unsigned size()const { return m_used; }
+ unsigned size() { return m_used; }
+ void resize(unsigned n, const T& val)
+ {
+ if(n > m_capacity)
+ throw std::runtime_error("Exhausted storage for Bernoulli numbers.");
+ for(unsigned i = m_used; i < n; ++i)
+ new (m_data + i) T(val);
+ m_used = n;
+ }
+ void resize(unsigned n) { resize(n, T()); }
+ T* begin() { return m_data; }
+ T* end() { return m_data + m_used; }
+ T* begin()const { return m_data; }
+ T* end()const { return m_data + m_used; }
+ unsigned capacity()const { return m_capacity; }
+private:
+ T* m_data;
+ unsigned m_used, m_capacity;
+};
+
+template <class T, class Policy>
+class bernoulli_numbers_cache
+{
+public:
+ bernoulli_numbers_cache() : m_overflow_limit((std::numeric_limits<std::size_t>::max)())
+#if defined(BOOST_HAS_THREADS) && !defined(BOOST_MATH_NO_ATOMIC_INT)
+ , m_counter(0)
+#endif
+ {}
+
+ typedef fixed_vector<T> container_type;
+
+ void tangent(std::size_t m)
+ {
+ static const std::size_t min_overflow_index = b2n_overflow_limit<T, Policy>() - 1;
+ tn.resize(static_cast<typename container_type::size_type>(m), T(0U));
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(min_overflow_index);
+
+ std::size_t prev_size = m_intermediates.size();
+ m_intermediates.resize(m, T(0U));
+
+ if(prev_size == 0)
+ {
+ m_intermediates[1] = tangent_scale_factor<T>() /*T(1U)*/;
+ tn[0U] = T(0U);
+ tn[1U] = tangent_scale_factor<T>()/* T(1U)*/;
+ BOOST_MATH_INSTRUMENT_VARIABLE(tn[0]);
+ BOOST_MATH_INSTRUMENT_VARIABLE(tn[1]);
+ }
+
+ for(std::size_t i = std::max<size_t>(2, prev_size); i < m; i++)
+ {
+ bool overflow_check = false;
+ if(i >= min_overflow_index && (boost::math::tools::max_value<T>() / (i-1) < m_intermediates[1]) )
+ {
+ std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value<T>());
+ break;
+ }
+ m_intermediates[1] = m_intermediates[1] * (i-1);
+ for(std::size_t j = 2; j <= i; j++)
+ {
+ overflow_check =
+ (i >= min_overflow_index) && (
+ (boost::math::tools::max_value<T>() / (i - j) < m_intermediates[j])
+ || (boost::math::tools::max_value<T>() / (i - j + 2) < m_intermediates[j-1])
+ || (boost::math::tools::max_value<T>() - m_intermediates[j] * (i - j) < m_intermediates[j-1] * (i - j + 2))
+ || ((boost::math::isinf)(m_intermediates[j]))
+ );
+
+ if(overflow_check)
+ {
+ std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value<T>());
+ break;
+ }
+ m_intermediates[j] = m_intermediates[j] * (i - j) + m_intermediates[j-1] * (i - j + 2);
+ }
+ if(overflow_check)
+ break; // already filled the tn...
+ tn[static_cast<typename container_type::size_type>(i)] = m_intermediates[i];
+ BOOST_MATH_INSTRUMENT_VARIABLE(i);
+ BOOST_MATH_INSTRUMENT_VARIABLE(tn[static_cast<typename container_type::size_type>(i)]);
+ }
+ }
+
+ void tangent_numbers_series(const std::size_t m)
+ {
+ BOOST_MATH_STD_USING
+ static const std::size_t min_overflow_index = b2n_overflow_limit<T, Policy>() - 1;
+
+ typename container_type::size_type old_size = bn.size();
+
+ tangent(m);
+ bn.resize(static_cast<typename container_type::size_type>(m));
+
+ if(!old_size)
+ {
+ bn[0] = 1;
+ old_size = 1;
+ }
+
+ T power_two(ldexp(T(1), static_cast<int>(2 * old_size)));
+
+ for(std::size_t i = old_size; i < m; i++)
+ {
+ T b(static_cast<T>(i * 2));
+ //
+ // Not only do we need to take care to avoid spurious over/under flow in
+ // the calculation, but we also need to avoid overflow altogether in case
+ // we're calculating with a type where "bad things" happen in that case:
+ //
+ b = b / (power_two * tangent_scale_factor<T>());
+ b /= (power_two - 1);
+ bool overflow_check = (i >= min_overflow_index) && (tools::max_value<T>() / tn[static_cast<typename container_type::size_type>(i)] < b);
+ if(overflow_check)
+ {
+ m_overflow_limit = i;
+ while(i < m)
+ {
+ b = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : tools::max_value<T>();
+ bn[static_cast<typename container_type::size_type>(i)] = ((i % 2U) ? b : T(-b));
+ ++i;
+ }
+ break;
+ }
+ else
+ {
+ b *= tn[static_cast<typename container_type::size_type>(i)];
+ }
+
+ power_two = ldexp(power_two, 2);
+
+ const bool b_neg = i % 2 == 0;
+
+ bn[static_cast<typename container_type::size_type>(i)] = ((!b_neg) ? b : T(-b));
+ }
+ }
+
+ template <class OutputIterator>
+ OutputIterator copy_bernoulli_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol)
+ {
+ //
+ // There are basically 3 thread safety options:
+ //
+ // 1) There are no threads (BOOST_HAS_THREADS is not defined).
+ // 2) There are threads, but we do not have a true atomic integer type,
+ // in this case we just use a mutex to guard against race conditions.
+ // 3) There are threads, and we have an atomic integer: in this case we can
+ // use the double-checked locking pattern to avoid thread synchronisation
+ // when accessing values already in the cache.
+ //
+ // First off handle the common case for overflow and/or asymptotic expansion:
+ //
+ if(start + n > bn.capacity())
+ {
+ if(start < bn.capacity())
+ {
+ out = copy_bernoulli_numbers(out, start, bn.capacity() - start, pol);
+ n -= bn.capacity() - start;
+ start = static_cast<std::size_t>(bn.capacity());
+ }
+ if(start < b2n_overflow_limit<T, Policy>() + 2u)
+ {
+ for(; n; ++start, --n)
+ {
+ *out = b2n_asymptotic<T, Policy>(static_cast<typename container_type::size_type>(start * 2U));
+ ++out;
+ }
+ }
+ for(; n; ++start, --n)
+ {
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(start), pol);
+ ++out;
+ }
+ return out;
+ }
+ #if !defined(BOOST_HAS_THREADS)
+ //
+ // Single threaded code, very simple:
+ //
+ if(start + n >= bn.size())
+ {
+ std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+ tangent_numbers_series(new_size);
+ }
+
+ for(std::size_t i = (std::max)(max_bernoulli_b2n<T>::value + 1, start); i < start + n; ++i)
+ {
+ *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[i];
+ ++out;
+ }
+ #elif defined(BOOST_MATH_NO_ATOMIC_INT)
+ //
+ // We need to grab a mutex every time we get here, for both readers and writers:
+ //
+ boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+ if(start + n >= bn.size())
+ {
+ std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+ tangent_numbers_series(new_size);
+ }
+
+ for(std::size_t i = (std::max)(max_bernoulli_b2n<T>::value + 1, start); i < start + n; ++i)
+ {
+ *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[i];
+ ++out;
+ }
+
+ #else
+ //
+ // Double-checked locking pattern, lets us access cached already cached values
+ // without locking:
+ //
+ // Get the counter and see if we need to calculate more constants:
+ //
+ if(static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+ {
+ boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+
+ if(static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+ {
+ if(start + n >= bn.size())
+ {
+ std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+ tangent_numbers_series(new_size);
+ }
+ m_counter.store(static_cast<atomic_integer_type>(bn.size()), BOOST_MATH_ATOMIC_NS::memory_order_release);
+ }
+ }
+
+ for(std::size_t i = (std::max)(static_cast<std::size_t>(max_bernoulli_b2n<T>::value + 1), start); i < start + n; ++i)
+ {
+ *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[static_cast<typename container_type::size_type>(i)];
+ ++out;
+ }
+
+ #endif
+ return out;
+ }
+
+ template <class OutputIterator>
+ OutputIterator copy_tangent_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol)
+ {
+ //
+ // There are basically 3 thread safety options:
+ //
+ // 1) There are no threads (BOOST_HAS_THREADS is not defined).
+ // 2) There are threads, but we do not have a true atomic integer type,
+ // in this case we just use a mutex to guard against race conditions.
+ // 3) There are threads, and we have an atomic integer: in this case we can
+ // use the double-checked locking pattern to avoid thread synchronisation
+ // when accessing values already in the cache.
+ //
+ //
+ // First off handle the common case for overflow and/or asymptotic expansion:
+ //
+ if(start + n > bn.capacity())
+ {
+ if(start < bn.capacity())
+ {
+ out = copy_tangent_numbers(out, start, bn.capacity() - start, pol);
+ n -= bn.capacity() - start;
+ start = static_cast<std::size_t>(bn.capacity());
+ }
+ if(start < b2n_overflow_limit<T, Policy>() + 2u)
+ {
+ for(; n; ++start, --n)
+ {
+ *out = t2n_asymptotic<T, Policy>(static_cast<typename container_type::size_type>(start));
+ ++out;
+ }
+ }
+ for(; n; ++start, --n)
+ {
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(start), pol);
+ ++out;
+ }
+ return out;
+ }
+ #if !defined(BOOST_HAS_THREADS)
+ //
+ // Single threaded code, very simple:
+ //
+ if(start + n >= bn.size())
+ {
+ std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+ tangent_numbers_series(new_size);
+ }
+
+ for(std::size_t i = start; i < start + n; ++i)
+ {
+ if(i >= m_overflow_limit)
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+ else
+ {
+ if(tools::max_value<T>() * tangent_scale_factor<T>() < tn[static_cast<typename container_type::size_type>(i)])
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+ else
+ *out = tn[static_cast<typename container_type::size_type>(i)] / tangent_scale_factor<T>();
+ }
+ ++out;
+ }
+ #elif defined(BOOST_MATH_NO_ATOMIC_INT)
+ //
+ // We need to grab a mutex every time we get here, for both readers and writers:
+ //
+ boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+ if(start + n >= bn.size())
+ {
+ std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+ tangent_numbers_series(new_size);
+ }
+
+ for(std::size_t i = start; i < start + n; ++i)
+ {
+ if(i >= m_overflow_limit)
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+ else
+ {
+ if(tools::max_value<T>() * tangent_scale_factor<T>() < tn[static_cast<typename container_type::size_type>(i)])
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+ else
+ *out = tn[static_cast<typename container_type::size_type>(i)] / tangent_scale_factor<T>();
+ }
+ ++out;
+ }
+
+ #else
+ //
+ // Double-checked locking pattern, lets us access cached already cached values
+ // without locking:
+ //
+ // Get the counter and see if we need to calculate more constants:
+ //
+ if(static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+ {
+ boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+
+ if(static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+ {
+ if(start + n >= bn.size())
+ {
+ std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+ tangent_numbers_series(new_size);
+ }
+ m_counter.store(static_cast<atomic_integer_type>(bn.size()), BOOST_MATH_ATOMIC_NS::memory_order_release);
+ }
+ }
+
+ for(std::size_t i = start; i < start + n; ++i)
+ {
+ if(i >= m_overflow_limit)
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+ else
+ {
+ if(tools::max_value<T>() * tangent_scale_factor<T>() < tn[static_cast<typename container_type::size_type>(i)])
+ *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+ else
+ *out = tn[static_cast<typename container_type::size_type>(i)] / tangent_scale_factor<T>();
+ }
+ ++out;
+ }
+
+ #endif
+ return out;
+ }
+
+private:
+ //
+ // The caches for Bernoulli and tangent numbers, once allocated,
+ // these must NEVER EVER reallocate as it breaks our thread
+ // safety guarentees:
+ //
+ fixed_vector<T> bn, tn;
+ std::vector<T> m_intermediates;
+ // The value at which we know overflow has already occured for the Bn:
+ std::size_t m_overflow_limit;
+#if !defined(BOOST_HAS_THREADS)
+#elif defined(BOOST_MATH_NO_ATOMIC_INT)
+ boost::detail::lightweight_mutex m_mutex;
+#else
+ boost::detail::lightweight_mutex m_mutex;
+ atomic_counter_type m_counter;
+#endif
+};
+
+template <class T, class Policy>
+inline bernoulli_numbers_cache<T, Policy>& get_bernoulli_numbers_cache()
+{
+ //
+ // Force this function to be called at program startup so all the static variables
+ // get initailzed then (thread safety).
+ //
+ bernoulli_initializer<T, Policy>::force_instantiate();
+ static bernoulli_numbers_cache<T, Policy> data;
+ return data;
+}
+
+}}}
+
+#endif // BOOST_MATH_BERNOULLI_DETAIL_HPP
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/erf_inv.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/erf_inv.hpp
new file mode 100644
index 00000000000..77aa72fc266
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/erf_inv.hpp
@@ -0,0 +1,536 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SF_ERF_INV_HPP
+#define BOOST_MATH_SF_ERF_INV_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail{
+//
+// The inverse erf and erfc functions share a common implementation,
+// this version is for 80-bit long double's and smaller:
+//
+template <class T, class Policy>
+T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>*)
+{
+ BOOST_MATH_STD_USING // for ADL of std names.
+
+ T result = 0;
+
+ if(p <= 0.5)
+ {
+ //
+ // Evaluate inverse erf using the rational approximation:
+ //
+ // x = p(p+10)(Y+R(p))
+ //
+ // Where Y is a constant, and R(p) is optimised for a low
+ // absolute error compared to |Y|.
+ //
+ // double: Max error found: 2.001849e-18
+ // long double: Max error found: 1.017064e-20
+ // Maximum Deviation Found (actual error term at infinite precision) 8.030e-21
+ //
+ static const float Y = 0.0891314744949340820313f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000508781949658280665617),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00836874819741736770379),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0334806625409744615033),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0126926147662974029034),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0365637971411762664006),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0219878681111168899165),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00822687874676915743155),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00538772965071242932965)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.970005043303290640362),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -1.56574558234175846809),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.56221558398423026363),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.662328840472002992063),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.71228902341542847553),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0527396382340099713954),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0795283687341571680018),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00233393759374190016776),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000886216390456424707504)
+ };
+ T g = p * (p + 10);
+ T r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p);
+ result = g * Y + g * r;
+ }
+ else if(q >= 0.25)
+ {
+ //
+ // Rational approximation for 0.5 > q >= 0.25
+ //
+ // x = sqrt(-2*log(q)) / (Y + R(q))
+ //
+ // Where Y is a constant, and R(q) is optimised for a low
+ // absolute error compared to Y.
+ //
+ // double : Max error found: 7.403372e-17
+ // long double : Max error found: 6.084616e-20
+ // Maximum Deviation Found (error term) 4.811e-20
+ //
+ static const float Y = 2.249481201171875f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.202433508355938759655),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.105264680699391713268),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 8.37050328343119927838),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 17.6447298408374015486),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -18.8510648058714251895),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -44.6382324441786960818),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 17.445385985570866523),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 21.1294655448340526258),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -3.67192254707729348546)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 6.24264124854247537712),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 3.9713437953343869095),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -28.6608180499800029974),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -20.1432634680485188801),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 48.5609213108739935468),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 10.8268667355460159008),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -22.6436933413139721736),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.72114765761200282724)
+ };
+ T g = sqrt(-2 * log(q));
+ T xs = q - 0.25;
+ T r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+ result = g / (Y + r);
+ }
+ else
+ {
+ //
+ // For q < 0.25 we have a series of rational approximations all
+ // of the general form:
+ //
+ // let: x = sqrt(-log(q))
+ //
+ // Then the result is given by:
+ //
+ // x(Y+R(x-B))
+ //
+ // where Y is a constant, B is the lowest value of x for which
+ // the approximation is valid, and R(x-B) is optimised for a low
+ // absolute error compared to Y.
+ //
+ // Note that almost all code will really go through the first
+ // or maybe second approximation. After than we're dealing with very
+ // small input values indeed: 80 and 128 bit long double's go all the
+ // way down to ~ 1e-5000 so the "tail" is rather long...
+ //
+ T x = sqrt(-log(q));
+ if(x < 3)
+ {
+ // Max error found: 1.089051e-20
+ static const float Y = 0.807220458984375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.131102781679951906451),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.163794047193317060787),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.117030156341995252019),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.387079738972604337464),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.337785538912035898924),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.142869534408157156766),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0290157910005329060432),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00214558995388805277169),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.679465575181126350155e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.285225331782217055858e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.681149956853776992068e-9)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 3.46625407242567245975),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 5.38168345707006855425),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 4.77846592945843778382),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 2.59301921623620271374),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.848854343457902036425),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.152264338295331783612),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.01105924229346489121)
+ };
+ T xs = x - 1.125;
+ T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+ result = Y * x + R * x;
+ }
+ else if(x < 6)
+ {
+ // Max error found: 8.389174e-21
+ static const float Y = 0.93995571136474609375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0350353787183177984712),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00222426529213447927281),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0185573306514231072324),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00950804701325919603619),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00187123492819559223345),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000157544617424960554631),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.460469890584317994083e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.230404776911882601748e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.266339227425782031962e-11)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.3653349817554063097),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.762059164553623404043),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.220091105764131249824),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0341589143670947727934),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00263861676657015992959),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.764675292302794483503e-4)
+ };
+ T xs = x - 3;
+ T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+ result = Y * x + R * x;
+ }
+ else if(x < 18)
+ {
+ // Max error found: 1.481312e-19
+ static const float Y = 0.98362827301025390625f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0167431005076633737133),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00112951438745580278863),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00105628862152492910091),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000209386317487588078668),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.149624783758342370182e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.449696789927706453732e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.462596163522878599135e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.281128735628831791805e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.99055709973310326855e-16)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.591429344886417493481),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.138151865749083321638),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0160746087093676504695),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000964011807005165528527),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.275335474764726041141e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.282243172016108031869e-6)
+ };
+ T xs = x - 6;
+ T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+ result = Y * x + R * x;
+ }
+ else if(x < 44)
+ {
+ // Max error found: 5.697761e-20
+ static const float Y = 0.99714565277099609375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0024978212791898131227),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.779190719229053954292e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.254723037413027451751e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.162397777342510920873e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.396341011304801168516e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.411632831190944208473e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.145596286718675035587e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.116765012397184275695e-17)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.207123112214422517181),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0169410838120975906478),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000690538265622684595676),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.145007359818232637924e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.144437756628144157666e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.509761276599778486139e-9)
+ };
+ T xs = x - 18;
+ T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+ result = Y * x + R * x;
+ }
+ else
+ {
+ // Max error found: 1.279746e-20
+ static const float Y = 0.99941349029541015625f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000539042911019078575891),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.28398759004727721098e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.899465114892291446442e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.229345859265920864296e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.225561444863500149219e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.947846627503022684216e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.135880130108924861008e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.348890393399948882918e-21)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0845746234001899436914),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00282092984726264681981),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.468292921940894236786e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.399968812193862100054e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.161809290887904476097e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.231558608310259605225e-11)
+ };
+ T xs = x - 44;
+ T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+ result = Y * x + R * x;
+ }
+ }
+ return result;
+}
+
+template <class T, class Policy>
+struct erf_roots
+{
+ boost::math::tuple<T,T,T> operator()(const T& guess)
+ {
+ BOOST_MATH_STD_USING
+ T derivative = sign * (2 / sqrt(constants::pi<T>())) * exp(-(guess * guess));
+ T derivative2 = -2 * guess * derivative;
+ return boost::math::make_tuple(((sign > 0) ? static_cast<T>(boost::math::erf(guess, Policy()) - target) : static_cast<T>(boost::math::erfc(guess, Policy())) - target), derivative, derivative2);
+ }
+ erf_roots(T z, int s) : target(z), sign(s) {}
+private:
+ T target;
+ int sign;
+};
+
+template <class T, class Policy>
+T erf_inv_imp(const T& p, const T& q, const Policy& pol, const boost::mpl::int_<0>*)
+{
+ //
+ // Generic version, get a guess that's accurate to 64-bits (10^-19)
+ //
+ T guess = erf_inv_imp(p, q, pol, static_cast<mpl::int_<64> const*>(0));
+ T result;
+ //
+ // If T has more bit's than 64 in it's mantissa then we need to iterate,
+ // otherwise we can just return the result:
+ //
+ if(policies::digits<T, Policy>() > 64)
+ {
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+ if(p <= 0.5)
+ {
+ result = tools::halley_iterate(detail::erf_roots<typename remove_cv<T>::type, Policy>(p, 1), guess, static_cast<T>(0), tools::max_value<T>(), (policies::digits<T, Policy>() * 2) / 3, max_iter);
+ }
+ else
+ {
+ result = tools::halley_iterate(detail::erf_roots<typename remove_cv<T>::type, Policy>(q, -1), guess, static_cast<T>(0), tools::max_value<T>(), (policies::digits<T, Policy>() * 2) / 3, max_iter);
+ }
+ policies::check_root_iterations<T>("boost::math::erf_inv<%1%>", max_iter, pol);
+ }
+ else
+ {
+ result = guess;
+ }
+ return result;
+}
+
+template <class T, class Policy>
+struct erf_inv_initializer
+{
+ struct init
+ {
+ init()
+ {
+ do_init();
+ }
+ static bool is_value_non_zero(T);
+ static void do_init()
+ {
+ boost::math::erf_inv(static_cast<T>(0.25), Policy());
+ boost::math::erf_inv(static_cast<T>(0.55), Policy());
+ boost::math::erf_inv(static_cast<T>(0.95), Policy());
+ boost::math::erfc_inv(static_cast<T>(1e-15), Policy());
+ // These following initializations must not be called if
+ // type T can not hold the relevant values without
+ // underflow to zero. We check this at runtime because
+ // some tools such as valgrind silently change the precision
+ // of T at runtime, and numeric_limits basically lies!
+ if(is_value_non_zero(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130))))
+ boost::math::erfc_inv(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130)), Policy());
+
+ // Some compilers choke on constants that would underflow, even in code that isn't instantiated
+ // so try and filter these cases out in the preprocessor:
+#if LDBL_MAX_10_EXP >= 800
+ if(is_value_non_zero(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800))))
+ boost::math::erfc_inv(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800)), Policy());
+ if(is_value_non_zero(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900))))
+ boost::math::erfc_inv(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900)), Policy());
+#else
+ if(is_value_non_zero(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800))))
+ boost::math::erfc_inv(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800)), Policy());
+ if(is_value_non_zero(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900))))
+ boost::math::erfc_inv(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900)), Policy());
+#endif
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy>
+const typename erf_inv_initializer<T, Policy>::init erf_inv_initializer<T, Policy>::initializer;
+
+template <class T, class Policy>
+bool erf_inv_initializer<T, Policy>::init::is_value_non_zero(T v)
+{
+ // This needs to be non-inline to detect whether v is non zero at runtime
+ // rather than at compile time, only relevant when running under valgrind
+ // which changes long double's to double's on the fly.
+ return v != 0;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+typename tools::promote_args<T>::type erfc_inv(T z, const Policy& pol)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+
+ //
+ // Begin by testing for domain errors, and other special cases:
+ //
+ static const char* function = "boost::math::erfc_inv<%1%>(%1%, %1%)";
+ if((z < 0) || (z > 2))
+ return policies::raise_domain_error<result_type>(function, "Argument outside range [0,2] in inverse erfc function (got p=%1%).", z, pol);
+ if(z == 0)
+ return policies::raise_overflow_error<result_type>(function, 0, pol);
+ if(z == 2)
+ return -policies::raise_overflow_error<result_type>(function, 0, pol);
+ //
+ // Normalise the input, so it's in the range [0,1], we will
+ // negate the result if z is outside that range. This is a simple
+ // application of the erfc reflection formula: erfc(-z) = 2 - erfc(z)
+ //
+ result_type p, q, s;
+ if(z > 1)
+ {
+ q = 2 - z;
+ p = 1 - q;
+ s = -1;
+ }
+ else
+ {
+ p = 1 - z;
+ q = z;
+ s = 1;
+ }
+ //
+ // A bit of meta-programming to figure out which implementation
+ // to use, based on the number of bits in the mantissa of T:
+ //
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+ typedef typename mpl::if_<
+ mpl::or_<mpl::less_equal<precision_type, mpl::int_<0> >, mpl::greater<precision_type, mpl::int_<64> > >,
+ mpl::int_<0>,
+ mpl::int_<64>
+ >::type tag_type;
+ //
+ // Likewise use internal promotion, so we evaluate at a higher
+ // precision internally if it's appropriate:
+ //
+ typedef typename policies::evaluation<result_type, Policy>::type eval_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ detail::erf_inv_initializer<eval_type, forwarding_policy>::force_instantiate();
+
+ //
+ // And get the result, negating where required:
+ //
+ return s * policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::erf_inv_imp(static_cast<eval_type>(p), static_cast<eval_type>(q), forwarding_policy(), static_cast<tag_type const*>(0)), function);
+}
+
+template <class T, class Policy>
+typename tools::promote_args<T>::type erf_inv(T z, const Policy& pol)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+
+ //
+ // Begin by testing for domain errors, and other special cases:
+ //
+ static const char* function = "boost::math::erf_inv<%1%>(%1%, %1%)";
+ if((z < -1) || (z > 1))
+ return policies::raise_domain_error<result_type>(function, "Argument outside range [-1, 1] in inverse erf function (got p=%1%).", z, pol);
+ if(z == 1)
+ return policies::raise_overflow_error<result_type>(function, 0, pol);
+ if(z == -1)
+ return -policies::raise_overflow_error<result_type>(function, 0, pol);
+ if(z == 0)
+ return 0;
+ //
+ // Normalise the input, so it's in the range [0,1], we will
+ // negate the result if z is outside that range. This is a simple
+ // application of the erf reflection formula: erf(-z) = -erf(z)
+ //
+ result_type p, q, s;
+ if(z < 0)
+ {
+ p = -z;
+ q = 1 - p;
+ s = -1;
+ }
+ else
+ {
+ p = z;
+ q = 1 - z;
+ s = 1;
+ }
+ //
+ // A bit of meta-programming to figure out which implementation
+ // to use, based on the number of bits in the mantissa of T:
+ //
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+ typedef typename mpl::if_<
+ mpl::or_<mpl::less_equal<precision_type, mpl::int_<0> >, mpl::greater<precision_type, mpl::int_<64> > >,
+ mpl::int_<0>,
+ mpl::int_<64>
+ >::type tag_type;
+ //
+ // Likewise use internal promotion, so we evaluate at a higher
+ // precision internally if it's appropriate:
+ //
+ typedef typename policies::evaluation<result_type, Policy>::type eval_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+ //
+ // Likewise use internal promotion, so we evaluate at a higher
+ // precision internally if it's appropriate:
+ //
+ typedef typename policies::evaluation<result_type, Policy>::type eval_type;
+
+ detail::erf_inv_initializer<eval_type, forwarding_policy>::force_instantiate();
+ //
+ // And get the result, negating where required:
+ //
+ return s * policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::erf_inv_imp(static_cast<eval_type>(p), static_cast<eval_type>(q), forwarding_policy(), static_cast<tag_type const*>(0)), function);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erfc_inv(T z)
+{
+ return erfc_inv(z, policies::policy<>());
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erf_inv(T z)
+{
+ return erf_inv(z, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SF_ERF_INV_HPP
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/fp_traits.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/fp_traits.hpp
new file mode 100644
index 00000000000..63ebf11ae08
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/fp_traits.hpp
@@ -0,0 +1,579 @@
+// fp_traits.hpp
+
+#ifndef BOOST_MATH_FP_TRAITS_HPP
+#define BOOST_MATH_FP_TRAITS_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under 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)
+
+/*
+To support old compilers, care has been taken to avoid partial template
+specialization and meta function forwarding.
+With these techniques, the code could be simplified.
+*/
+
+#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
+// The VAX floating point formats are used (for float and double)
+# define BOOST_FPCLASSIFY_VAX_FORMAT
+#endif
+
+#include <cstring>
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std{ using ::memcpy; }
+#endif
+
+#ifndef FP_NORMAL
+
+#define FP_ZERO 0
+#define FP_NORMAL 1
+#define FP_INFINITE 2
+#define FP_NAN 3
+#define FP_SUBNORMAL 4
+
+#else
+
+#define BOOST_HAS_FPCLASSIFY
+
+#ifndef fpclassify
+# if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \
+ && defined(_GLIBCXX_USE_C99_MATH) \
+ && !(defined(_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) \
+ && (_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC != 0))
+# ifdef _STLP_VENDOR_CSTD
+# if _STLPORT_VERSION >= 0x520
+# define BOOST_FPCLASSIFY_PREFIX ::__std_alias::
+# else
+# define BOOST_FPCLASSIFY_PREFIX ::_STLP_VENDOR_CSTD::
+# endif
+# else
+# define BOOST_FPCLASSIFY_PREFIX ::std::
+# endif
+# else
+# undef BOOST_HAS_FPCLASSIFY
+# define BOOST_FPCLASSIFY_PREFIX
+# endif
+#elif (defined(__HP_aCC) && !defined(__hppa))
+// aCC 6 appears to do "#define fpclassify fpclassify" which messes us up a bit!
+# define BOOST_FPCLASSIFY_PREFIX ::
+#else
+# define BOOST_FPCLASSIFY_PREFIX
+#endif
+
+#ifdef __MINGW32__
+# undef BOOST_HAS_FPCLASSIFY
+#endif
+
+#endif
+
+
+//------------------------------------------------------------------------------
+
+namespace boost {
+namespace math {
+namespace detail {
+
+//------------------------------------------------------------------------------
+
+/*
+The following classes are used to tag the different methods that are used
+for floating point classification
+*/
+
+struct native_tag {};
+template <bool has_limits>
+struct generic_tag {};
+struct ieee_tag {};
+struct ieee_copy_all_bits_tag : public ieee_tag {};
+struct ieee_copy_leading_bits_tag : public ieee_tag {};
+
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+//
+// These helper functions are used only when numeric_limits<>
+// members are not compile time constants:
+//
+inline bool is_generic_tag_false(const generic_tag<false>*)
+{
+ return true;
+}
+inline bool is_generic_tag_false(const void*)
+{
+ return false;
+}
+#endif
+
+//------------------------------------------------------------------------------
+
+/*
+Most processors support three different floating point precisions:
+single precision (32 bits), double precision (64 bits)
+and extended double precision (80 - 128 bits, depending on the processor)
+
+Note that the C++ type long double can be implemented
+both as double precision and extended double precision.
+*/
+
+struct unknown_precision{};
+struct single_precision {};
+struct double_precision {};
+struct extended_double_precision {};
+
+// native_tag version --------------------------------------------------------------
+
+template<class T> struct fp_traits_native
+{
+ typedef native_tag method;
+};
+
+// generic_tag version -------------------------------------------------------------
+
+template<class T, class U> struct fp_traits_non_native
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ typedef generic_tag<std::numeric_limits<T>::is_specialized> method;
+#else
+ typedef generic_tag<false> method;
+#endif
+};
+
+// ieee_tag versions ---------------------------------------------------------------
+
+/*
+These specializations of fp_traits_non_native contain information needed
+to "parse" the binary representation of a floating point number.
+
+Typedef members:
+
+ bits -- the target type when copying the leading bytes of a floating
+ point number. It is a typedef for uint32_t or uint64_t.
+
+ method -- tells us whether all bytes are copied or not.
+ It is a typedef for ieee_copy_all_bits_tag or ieee_copy_leading_bits_tag.
+
+Static data members:
+
+ sign, exponent, flag, significand -- bit masks that give the meaning of the
+ bits in the leading bytes.
+
+Static function members:
+
+ get_bits(), set_bits() -- provide access to the leading bytes.
+
+*/
+
+// ieee_tag version, float (32 bits) -----------------------------------------------
+
+#ifndef BOOST_FPCLASSIFY_VAX_FORMAT
+
+template<> struct fp_traits_non_native<float, single_precision>
+{
+ typedef ieee_copy_all_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x007fffff);
+
+ typedef uint32_t bits;
+ static void get_bits(float x, uint32_t& a) { std::memcpy(&a, &x, 4); }
+ static void set_bits(float& x, uint32_t a) { std::memcpy(&x, &a, 4); }
+};
+
+// ieee_tag version, double (64 bits) ----------------------------------------------
+
+#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) \
+ || defined(__BORLANDC__) || defined(__CODEGEAR__)
+
+template<> struct fp_traits_non_native<double, double_precision>
+{
+ typedef ieee_copy_leading_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);
+
+ typedef uint32_t bits;
+
+ static void get_bits(double x, uint32_t& a)
+ {
+ std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(double& x, uint32_t a)
+ {
+ std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 4);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+//..............................................................................
+
+#else
+
+template<> struct fp_traits_non_native<double, double_precision>
+{
+ typedef ieee_copy_all_bits_tag method;
+
+ static const uint64_t sign = ((uint64_t)0x80000000u) << 32;
+ static const uint64_t exponent = ((uint64_t)0x7ff00000) << 32;
+ static const uint64_t flag = 0;
+ static const uint64_t significand
+ = (((uint64_t)0x000fffff) << 32) + ((uint64_t)0xffffffffu);
+
+ typedef uint64_t bits;
+ static void get_bits(double x, uint64_t& a) { std::memcpy(&a, &x, 8); }
+ static void set_bits(double& x, uint64_t a) { std::memcpy(&x, &a, 8); }
+};
+
+#endif
+
+#endif // #ifndef BOOST_FPCLASSIFY_VAX_FORMAT
+
+// long double (64 bits) -------------------------------------------------------
+
+#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\
+ || defined(__BORLANDC__) || defined(__CODEGEAR__)
+
+template<> struct fp_traits_non_native<long double, double_precision>
+{
+ typedef ieee_copy_leading_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);
+
+ typedef uint32_t bits;
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 4);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+//..............................................................................
+
+#else
+
+template<> struct fp_traits_non_native<long double, double_precision>
+{
+ typedef ieee_copy_all_bits_tag method;
+
+ static const uint64_t sign = (uint64_t)0x80000000u << 32;
+ static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
+ static const uint64_t flag = 0;
+ static const uint64_t significand
+ = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffffu;
+
+ typedef uint64_t bits;
+ static void get_bits(long double x, uint64_t& a) { std::memcpy(&a, &x, 8); }
+ static void set_bits(long double& x, uint64_t a) { std::memcpy(&x, &a, 8); }
+};
+
+#endif
+
+
+// long double (>64 bits), x86 and x64 -----------------------------------------
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
+ || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
+ || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
+
+// Intel extended double precision format (80 bits)
+
+template<>
+struct fp_traits_non_native<long double, extended_double_precision>
+{
+ typedef ieee_copy_leading_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x00007fff);
+
+ typedef uint32_t bits;
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ std::memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
+ }
+};
+
+
+// long double (>64 bits), Itanium ---------------------------------------------
+
+#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+
+// The floating point format is unknown at compile time
+// No template specialization is provided.
+// The generic_tag definition is used.
+
+// The Itanium supports both
+// the Intel extended double precision format (80 bits) and
+// the IEEE extended double precision format with 15 exponent bits (128 bits).
+
+#elif defined(__GNUC__) && (LDBL_MANT_DIG == 106)
+
+//
+// Define nothing here and fall though to generic_tag:
+// We have GCC's "double double" in effect, and any attempt
+// to handle it via bit-fiddling is pretty much doomed to fail...
+//
+
+// long double (>64 bits), PowerPC ---------------------------------------------
+
+#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
+ || defined(__ppc) || defined(__ppc__) || defined(__PPC__)
+
+// PowerPC extended double precision format (128 bits)
+
+template<>
+struct fp_traits_non_native<long double, extended_double_precision>
+{
+ typedef ieee_copy_leading_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x000fffff);
+
+ typedef uint32_t bits;
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 12);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+
+// long double (>64 bits), Motorola 68K ----------------------------------------
+
+#elif defined(__m68k) || defined(__m68k__) \
+ || defined(__mc68000) || defined(__mc68000__) \
+
+// Motorola extended double precision format (96 bits)
+
+// It is the same format as the Intel extended double precision format,
+// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
+// 3) the flag bit is not set for infinity
+
+template<>
+struct fp_traits_non_native<long double, extended_double_precision>
+{
+ typedef ieee_copy_leading_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x00007fff);
+
+ // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
+
+ typedef uint32_t bits;
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ std::memcpy(&a, &x, 2);
+ std::memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
+ reinterpret_cast<const unsigned char*>(&x) + 4, 2);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ std::memcpy(&x, &a, 2);
+ std::memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
+ reinterpret_cast<const unsigned char*>(&a) + 2, 2);
+ }
+};
+
+
+// long double (>64 bits), All other processors --------------------------------
+
+#else
+
+// IEEE extended double precision format with 15 exponent bits (128 bits)
+
+template<>
+struct fp_traits_non_native<long double, extended_double_precision>
+{
+ typedef ieee_copy_leading_bits_tag method;
+
+ BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000u);
+ BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+ BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
+ BOOST_STATIC_CONSTANT(uint32_t, significand = 0x0000ffff);
+
+ typedef uint32_t bits;
+
+ static void get_bits(long double x, uint32_t& a)
+ {
+ std::memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+ }
+
+ static void set_bits(long double& x, uint32_t a)
+ {
+ std::memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+ }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+ BOOST_STATIC_CONSTANT(int, offset_ = 12);
+#else
+ BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+#endif
+
+//------------------------------------------------------------------------------
+
+// size_to_precision is a type switch for converting a C++ floating point type
+// to the corresponding precision type.
+
+template<int n, bool fp> struct size_to_precision
+{
+ typedef unknown_precision type;
+};
+
+template<> struct size_to_precision<4, true>
+{
+ typedef single_precision type;
+};
+
+template<> struct size_to_precision<8, true>
+{
+ typedef double_precision type;
+};
+
+template<> struct size_to_precision<10, true>
+{
+ typedef extended_double_precision type;
+};
+
+template<> struct size_to_precision<12, true>
+{
+ typedef extended_double_precision type;
+};
+
+template<> struct size_to_precision<16, true>
+{
+ typedef extended_double_precision type;
+};
+
+//------------------------------------------------------------------------------
+//
+// Figure out whether to use native classification functions based on
+// whether T is a built in floating point type or not:
+//
+template <class T>
+struct select_native
+{
+ typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
+ typedef fp_traits_non_native<T, precision> type;
+};
+template<>
+struct select_native<float>
+{
+ typedef fp_traits_native<float> type;
+};
+template<>
+struct select_native<double>
+{
+ typedef fp_traits_native<double> type;
+};
+template<>
+struct select_native<long double>
+{
+ typedef fp_traits_native<long double> type;
+};
+
+//------------------------------------------------------------------------------
+
+// fp_traits is a type switch that selects the right fp_traits_non_native
+
+#if (defined(BOOST_MATH_USE_C99) && !(defined(__GNUC__) && (__GNUC__ < 4))) \
+ && !defined(__hpux) \
+ && !defined(__DECCXX)\
+ && !defined(__osf__) \
+ && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)\
+ && !defined(__FAST_MATH__)\
+ && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)\
+ && !defined(BOOST_INTEL)
+# define BOOST_MATH_USE_STD_FPCLASSIFY
+#endif
+
+template<class T> struct fp_traits
+{
+ typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T), ::boost::is_floating_point<T>::value>::type precision;
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
+ typedef typename select_native<T>::type type;
+#else
+ typedef fp_traits_non_native<T, precision> type;
+#endif
+ typedef fp_traits_non_native<T, precision> sign_change_type;
+};
+
+//------------------------------------------------------------------------------
+
+} // namespace detail
+} // namespace math
+} // namespace boost
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/gamma_inva.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/gamma_inva.hpp
new file mode 100644
index 00000000000..7c32d2946c0
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/gamma_inva.hpp
@@ -0,0 +1,233 @@
+// (C) Copyright John Maddock 2006.
+// 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 is not a complete header file, it is included by gamma.hpp
+// after it has defined it's definitions. This inverts the incomplete
+// gamma functions P and Q on the first parameter "a" using a generic
+// root finding algorithm (TOMS Algorithm 748).
+//
+
+#ifndef BOOST_MATH_SP_DETAIL_GAMMA_INVA
+#define BOOST_MATH_SP_DETAIL_GAMMA_INVA
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/toms748_solve.hpp>
+#include <boost/cstdint.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+struct gamma_inva_t
+{
+ gamma_inva_t(T z_, T p_, bool invert_) : z(z_), p(p_), invert(invert_) {}
+ T operator()(T a)
+ {
+ return invert ? p - boost::math::gamma_q(a, z, Policy()) : boost::math::gamma_p(a, z, Policy()) - p;
+ }
+private:
+ T z, p;
+ bool invert;
+};
+
+template <class T, class Policy>
+T inverse_poisson_cornish_fisher(T lambda, T p, T q, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ // mean:
+ T m = lambda;
+ // standard deviation:
+ T sigma = sqrt(lambda);
+ // skewness
+ T sk = 1 / sigma;
+ // kurtosis:
+ // T k = 1/lambda;
+ // Get the inverse of a std normal distribution:
+ T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two<T>();
+ // Set the sign:
+ if(p < 0.5)
+ x = -x;
+ T x2 = x * x;
+ // w is correction term due to skewness
+ T w = x + sk * (x2 - 1) / 6;
+ /*
+ // Add on correction due to kurtosis.
+ // Disabled for now, seems to make things worse?
+ //
+ if(lambda >= 10)
+ w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36;
+ */
+ w = m + sigma * w;
+ return w > tools::min_value<T>() ? w : tools::min_value<T>();
+}
+
+template <class T, class Policy>
+T gamma_inva_imp(const T& z, const T& p, const T& q, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // for ADL of std lib math functions
+ //
+ // Special cases first:
+ //
+ if(p == 0)
+ {
+ return policies::raise_overflow_error<T>("boost::math::gamma_p_inva<%1%>(%1%, %1%)", 0, Policy());
+ }
+ if(q == 0)
+ {
+ return tools::min_value<T>();
+ }
+ //
+ // Function object, this is the functor whose root
+ // we have to solve:
+ //
+ gamma_inva_t<T, Policy> f(z, (p < q) ? p : q, (p < q) ? false : true);
+ //
+ // Tolerance: full precision.
+ //
+ tools::eps_tolerance<T> tol(policies::digits<T, Policy>());
+ //
+ // Now figure out a starting guess for what a may be,
+ // we'll start out with a value that'll put p or q
+ // right bang in the middle of their range, the functions
+ // are quite sensitive so we should need too many steps
+ // to bracket the root from there:
+ //
+ T guess;
+ T factor = 8;
+ if(z >= 1)
+ {
+ //
+ // We can use the relationship between the incomplete
+ // gamma function and the poisson distribution to
+ // calculate an approximate inverse, for large z
+ // this is actually pretty accurate, but it fails badly
+ // when z is very small. Also set our step-factor according
+ // to how accurate we think the result is likely to be:
+ //
+ guess = 1 + inverse_poisson_cornish_fisher(z, q, p, pol);
+ if(z > 5)
+ {
+ if(z > 1000)
+ factor = 1.01f;
+ else if(z > 50)
+ factor = 1.1f;
+ else if(guess > 10)
+ factor = 1.25f;
+ else
+ factor = 2;
+ if(guess < 1.1)
+ factor = 8;
+ }
+ }
+ else if(z > 0.5)
+ {
+ guess = z * 1.2f;
+ }
+ else
+ {
+ guess = -0.4f / log(z);
+ }
+ //
+ // Max iterations permitted:
+ //
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+ //
+ // Use our generic derivative-free root finding procedure.
+ // We could use Newton steps here, taking the PDF of the
+ // Poisson distribution as our derivative, but that's
+ // even worse performance-wise than the generic method :-(
+ //
+ std::pair<T, T> r = bracket_and_solve_root(f, guess, factor, false, tol, max_iter, pol);
+ if(max_iter >= policies::get_max_root_iterations<Policy>())
+ return policies::raise_evaluation_error<T>("boost::math::gamma_p_inva<%1%>(%1%, %1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol);
+ return (r.first + r.second) / 2;
+}
+
+} // namespace detail
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p_inva(T1 x, T2 p, const Policy& pol)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ if(p == 0)
+ {
+ policies::raise_overflow_error<result_type>("boost::math::gamma_p_inva<%1%>(%1%, %1%)", 0, Policy());
+ }
+ if(p == 1)
+ {
+ return tools::min_value<result_type>();
+ }
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::gamma_inva_imp(
+ static_cast<value_type>(x),
+ static_cast<value_type>(p),
+ static_cast<value_type>(1 - static_cast<value_type>(p)),
+ pol), "boost::math::gamma_p_inva<%1%>(%1%, %1%)");
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_q_inva(T1 x, T2 q, const Policy& pol)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ if(q == 1)
+ {
+ policies::raise_overflow_error<result_type>("boost::math::gamma_q_inva<%1%>(%1%, %1%)", 0, Policy());
+ }
+ if(q == 0)
+ {
+ return tools::min_value<result_type>();
+ }
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::gamma_inva_imp(
+ static_cast<value_type>(x),
+ static_cast<value_type>(1 - static_cast<value_type>(q)),
+ static_cast<value_type>(q),
+ pol), "boost::math::gamma_q_inva<%1%>(%1%, %1%)");
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p_inva(T1 x, T2 p)
+{
+ return boost::math::gamma_p_inva(x, p, policies::policy<>());
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_q_inva(T1 x, T2 q)
+{
+ return boost::math::gamma_q_inva(x, q, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_DETAIL_GAMMA_INVA
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inv_ab.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inv_ab.hpp
new file mode 100644
index 00000000000..f5735a84956
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inv_ab.hpp
@@ -0,0 +1,328 @@
+// (C) Copyright John Maddock 2006.
+// 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 is not a complete header file, it is included by beta.hpp
+// after it has defined it's definitions. This inverts the incomplete
+// beta functions ibeta and ibetac on the first parameters "a"
+// and "b" using a generic root finding algorithm (TOMS Algorithm 748).
+//
+
+#ifndef BOOST_MATH_SP_DETAIL_BETA_INV_AB
+#define BOOST_MATH_SP_DETAIL_BETA_INV_AB
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/toms748_solve.hpp>
+#include <boost/cstdint.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+struct beta_inv_ab_t
+{
+ beta_inv_ab_t(T b_, T z_, T p_, bool invert_, bool swap_ab_) : b(b_), z(z_), p(p_), invert(invert_), swap_ab(swap_ab_) {}
+ T operator()(T a)
+ {
+ return invert ?
+ p - boost::math::ibetac(swap_ab ? b : a, swap_ab ? a : b, z, Policy())
+ : boost::math::ibeta(swap_ab ? b : a, swap_ab ? a : b, z, Policy()) - p;
+ }
+private:
+ T b, z, p;
+ bool invert, swap_ab;
+};
+
+template <class T, class Policy>
+T inverse_negative_binomial_cornish_fisher(T n, T sf, T sfc, T p, T q, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ // mean:
+ T m = n * (sfc) / sf;
+ T t = sqrt(n * (sfc));
+ // standard deviation:
+ T sigma = t / sf;
+ // skewness
+ T sk = (1 + sfc) / t;
+ // kurtosis:
+ T k = (6 - sf * (5+sfc)) / (n * (sfc));
+ // Get the inverse of a std normal distribution:
+ T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two<T>();
+ // Set the sign:
+ if(p < 0.5)
+ x = -x;
+ T x2 = x * x;
+ // w is correction term due to skewness
+ T w = x + sk * (x2 - 1) / 6;
+ //
+ // Add on correction due to kurtosis.
+ //
+ if(n >= 10)
+ w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36;
+
+ w = m + sigma * w;
+ if(w < tools::min_value<T>())
+ return tools::min_value<T>();
+ return w;
+}
+
+template <class T, class Policy>
+T ibeta_inv_ab_imp(const T& b, const T& z, const T& p, const T& q, bool swap_ab, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // for ADL of std lib math functions
+ //
+ // Special cases first:
+ //
+ BOOST_MATH_INSTRUMENT_CODE("b = " << b << " z = " << z << " p = " << p << " q = " << " swap = " << swap_ab);
+ if(p == 0)
+ {
+ return swap_ab ? tools::min_value<T>() : tools::max_value<T>();
+ }
+ if(q == 0)
+ {
+ return swap_ab ? tools::max_value<T>() : tools::min_value<T>();
+ }
+ //
+ // Function object, this is the functor whose root
+ // we have to solve:
+ //
+ beta_inv_ab_t<T, Policy> f(b, z, (p < q) ? p : q, (p < q) ? false : true, swap_ab);
+ //
+ // Tolerance: full precision.
+ //
+ tools::eps_tolerance<T> tol(policies::digits<T, Policy>());
+ //
+ // Now figure out a starting guess for what a may be,
+ // we'll start out with a value that'll put p or q
+ // right bang in the middle of their range, the functions
+ // are quite sensitive so we should need too many steps
+ // to bracket the root from there:
+ //
+ T guess = 0;
+ T factor = 5;
+ //
+ // Convert variables to parameters of a negative binomial distribution:
+ //
+ T n = b;
+ T sf = swap_ab ? z : 1-z;
+ T sfc = swap_ab ? 1-z : z;
+ T u = swap_ab ? p : q;
+ T v = swap_ab ? q : p;
+ if(u <= pow(sf, n))
+ {
+ //
+ // Result is less than 1, negative binomial approximation
+ // is useless....
+ //
+ if((p < q) != swap_ab)
+ {
+ guess = (std::min)(T(b * 2), T(1));
+ }
+ else
+ {
+ guess = (std::min)(T(b / 2), T(1));
+ }
+ }
+ if(n * n * n * u * sf > 0.005)
+ guess = 1 + inverse_negative_binomial_cornish_fisher(n, sf, sfc, u, v, pol);
+
+ if(guess < 10)
+ {
+ //
+ // Negative binomial approximation not accurate in this area:
+ //
+ if((p < q) != swap_ab)
+ {
+ guess = (std::min)(T(b * 2), T(10));
+ }
+ else
+ {
+ guess = (std::min)(T(b / 2), T(10));
+ }
+ }
+ else
+ factor = (v < sqrt(tools::epsilon<T>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
+ BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
+ //
+ // Max iterations permitted:
+ //
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+ std::pair<T, T> r = bracket_and_solve_root(f, guess, factor, swap_ab ? true : false, tol, max_iter, pol);
+ if(max_iter >= policies::get_max_root_iterations<Policy>())
+ return policies::raise_evaluation_error<T>("boost::math::ibeta_invab_imp<%1%>(%1%,%1%,%1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol);
+ return (r.first + r.second) / 2;
+}
+
+} // namespace detail
+
+template <class RT1, class RT2, class RT3, class Policy>
+typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_inva(RT1 b, RT2 x, RT3 p, const Policy& pol)
+{
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ static const char* function = "boost::math::ibeta_inva<%1%>(%1%,%1%,%1%)";
+ if(p == 0)
+ {
+ return policies::raise_overflow_error<result_type>(function, 0, Policy());
+ }
+ if(p == 1)
+ {
+ return tools::min_value<result_type>();
+ }
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::ibeta_inv_ab_imp(
+ static_cast<value_type>(b),
+ static_cast<value_type>(x),
+ static_cast<value_type>(p),
+ static_cast<value_type>(1 - static_cast<value_type>(p)),
+ false, pol),
+ function);
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inva(RT1 b, RT2 x, RT3 q, const Policy& pol)
+{
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ static const char* function = "boost::math::ibetac_inva<%1%>(%1%,%1%,%1%)";
+ if(q == 1)
+ {
+ return policies::raise_overflow_error<result_type>(function, 0, Policy());
+ }
+ if(q == 0)
+ {
+ return tools::min_value<result_type>();
+ }
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::ibeta_inv_ab_imp(
+ static_cast<value_type>(b),
+ static_cast<value_type>(x),
+ static_cast<value_type>(1 - static_cast<value_type>(q)),
+ static_cast<value_type>(q),
+ false, pol),
+ function);
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_invb(RT1 a, RT2 x, RT3 p, const Policy& pol)
+{
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ static const char* function = "boost::math::ibeta_invb<%1%>(%1%,%1%,%1%)";
+ if(p == 0)
+ {
+ return tools::min_value<result_type>();
+ }
+ if(p == 1)
+ {
+ return policies::raise_overflow_error<result_type>(function, 0, Policy());
+ }
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::ibeta_inv_ab_imp(
+ static_cast<value_type>(a),
+ static_cast<value_type>(x),
+ static_cast<value_type>(p),
+ static_cast<value_type>(1 - static_cast<value_type>(p)),
+ true, pol),
+ function);
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_invb(RT1 a, RT2 x, RT3 q, const Policy& pol)
+{
+ static const char* function = "boost::math::ibeta_invb<%1%>(%1%, %1%, %1%)";
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ if(q == 1)
+ {
+ return tools::min_value<result_type>();
+ }
+ if(q == 0)
+ {
+ return policies::raise_overflow_error<result_type>(function, 0, Policy());
+ }
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::ibeta_inv_ab_imp(
+ static_cast<value_type>(a),
+ static_cast<value_type>(x),
+ static_cast<value_type>(1 - static_cast<value_type>(q)),
+ static_cast<value_type>(q),
+ true, pol),
+ function);
+}
+
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_inva(RT1 b, RT2 x, RT3 p)
+{
+ return boost::math::ibeta_inva(b, x, p, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inva(RT1 b, RT2 x, RT3 q)
+{
+ return boost::math::ibetac_inva(b, x, q, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_invb(RT1 a, RT2 x, RT3 p)
+{
+ return boost::math::ibeta_invb(a, x, p, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_invb(RT1 a, RT2 x, RT3 q)
+{
+ return boost::math::ibetac_invb(a, x, q, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_DETAIL_BETA_INV_AB
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inverse.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inverse.hpp
new file mode 100644
index 00000000000..a9fe8cd49cb
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/ibeta_inverse.hpp
@@ -0,0 +1,993 @@
+// Copyright John Maddock 2006.
+// Copyright Paul A. Bristow 2007
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_IBETA_INVERSE_HPP
+#define BOOST_MATH_SPECIAL_FUNCTIONS_IBETA_INVERSE_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/beta.hpp>
+#include <boost/math/special_functions/erf.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/special_functions/detail/t_distribution_inv.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+//
+// Helper object used by root finding
+// code to convert eta to x.
+//
+template <class T>
+struct temme_root_finder
+{
+ temme_root_finder(const T t_, const T a_) : t(t_), a(a_) {}
+
+ boost::math::tuple<T, T> operator()(T x)
+ {
+ BOOST_MATH_STD_USING // ADL of std names
+
+ T y = 1 - x;
+ if(y == 0)
+ {
+ T big = tools::max_value<T>() / 4;
+ return boost::math::make_tuple(static_cast<T>(-big), static_cast<T>(-big));
+ }
+ if(x == 0)
+ {
+ T big = tools::max_value<T>() / 4;
+ return boost::math::make_tuple(static_cast<T>(-big), big);
+ }
+ T f = log(x) + a * log(y) + t;
+ T f1 = (1 / x) - (a / (y));
+ return boost::math::make_tuple(f, f1);
+ }
+private:
+ T t, a;
+};
+//
+// See:
+// "Asymptotic Inversion of the Incomplete Beta Function"
+// N.M. Temme
+// Journal of Computation and Applied Mathematics 41 (1992) 145-157.
+// Section 2.
+//
+template <class T, class Policy>
+T temme_method_1_ibeta_inverse(T a, T b, T z, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // ADL of std names
+
+ const T r2 = sqrt(T(2));
+ //
+ // get the first approximation for eta from the inverse
+ // error function (Eq: 2.9 and 2.10).
+ //
+ T eta0 = boost::math::erfc_inv(2 * z, pol);
+ eta0 /= -sqrt(a / 2);
+
+ T terms[4] = { eta0 };
+ T workspace[7];
+ //
+ // calculate powers:
+ //
+ T B = b - a;
+ T B_2 = B * B;
+ T B_3 = B_2 * B;
+ //
+ // Calculate correction terms:
+ //
+
+ // See eq following 2.15:
+ workspace[0] = -B * r2 / 2;
+ workspace[1] = (1 - 2 * B) / 8;
+ workspace[2] = -(B * r2 / 48);
+ workspace[3] = T(-1) / 192;
+ workspace[4] = -B * r2 / 3840;
+ terms[1] = tools::evaluate_polynomial(workspace, eta0, 5);
+ // Eq Following 2.17:
+ workspace[0] = B * r2 * (3 * B - 2) / 12;
+ workspace[1] = (20 * B_2 - 12 * B + 1) / 128;
+ workspace[2] = B * r2 * (20 * B - 1) / 960;
+ workspace[3] = (16 * B_2 + 30 * B - 15) / 4608;
+ workspace[4] = B * r2 * (21 * B + 32) / 53760;
+ workspace[5] = (-32 * B_2 + 63) / 368640;
+ workspace[6] = -B * r2 * (120 * B + 17) / 25804480;
+ terms[2] = tools::evaluate_polynomial(workspace, eta0, 7);
+ // Eq Following 2.17:
+ workspace[0] = B * r2 * (-75 * B_2 + 80 * B - 16) / 480;
+ workspace[1] = (-1080 * B_3 + 868 * B_2 - 90 * B - 45) / 9216;
+ workspace[2] = B * r2 * (-1190 * B_2 + 84 * B + 373) / 53760;
+ workspace[3] = (-2240 * B_3 - 2508 * B_2 + 2100 * B - 165) / 368640;
+ terms[3] = tools::evaluate_polynomial(workspace, eta0, 4);
+ //
+ // Bring them together to get a final estimate for eta:
+ //
+ T eta = tools::evaluate_polynomial(terms, T(1/a), 4);
+ //
+ // now we need to convert eta to x, by solving the appropriate
+ // quadratic equation:
+ //
+ T eta_2 = eta * eta;
+ T c = -exp(-eta_2 / 2);
+ T x;
+ if(eta_2 == 0)
+ x = 0.5;
+ else
+ x = (1 + eta * sqrt((1 + c) / eta_2)) / 2;
+
+ BOOST_ASSERT(x >= 0);
+ BOOST_ASSERT(x <= 1);
+ BOOST_ASSERT(eta * (x - 0.5) >= 0);
+#ifdef BOOST_INSTRUMENT
+ std::cout << "Estimating x with Temme method 1: " << x << std::endl;
+#endif
+ return x;
+}
+//
+// See:
+// "Asymptotic Inversion of the Incomplete Beta Function"
+// N.M. Temme
+// Journal of Computation and Applied Mathematics 41 (1992) 145-157.
+// Section 3.
+//
+template <class T, class Policy>
+T temme_method_2_ibeta_inverse(T /*a*/, T /*b*/, T z, T r, T theta, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // ADL of std names
+
+ //
+ // Get first estimate for eta, see Eq 3.9 and 3.10,
+ // but note there is a typo in Eq 3.10:
+ //
+ T eta0 = boost::math::erfc_inv(2 * z, pol);
+ eta0 /= -sqrt(r / 2);
+
+ T s = sin(theta);
+ T c = cos(theta);
+ //
+ // Now we need to purturb eta0 to get eta, which we do by
+ // evaluating the polynomial in 1/r at the bottom of page 151,
+ // to do this we first need the error terms e1, e2 e3
+ // which we'll fill into the array "terms". Since these
+ // terms are themselves polynomials, we'll need another
+ // array "workspace" to calculate those...
+ //
+ T terms[4] = { eta0 };
+ T workspace[6];
+ //
+ // some powers of sin(theta)cos(theta) that we'll need later:
+ //
+ T sc = s * c;
+ T sc_2 = sc * sc;
+ T sc_3 = sc_2 * sc;
+ T sc_4 = sc_2 * sc_2;
+ T sc_5 = sc_2 * sc_3;
+ T sc_6 = sc_3 * sc_3;
+ T sc_7 = sc_4 * sc_3;
+ //
+ // Calculate e1 and put it in terms[1], see the middle of page 151:
+ //
+ workspace[0] = (2 * s * s - 1) / (3 * s * c);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co1[] = { -1, -5, 5 };
+ workspace[1] = -tools::evaluate_even_polynomial(co1, s, 3) / (36 * sc_2);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co2[] = { 1, 21, -69, 46 };
+ workspace[2] = tools::evaluate_even_polynomial(co2, s, 4) / (1620 * sc_3);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co3[] = { 7, -2, 33, -62, 31 };
+ workspace[3] = -tools::evaluate_even_polynomial(co3, s, 5) / (6480 * sc_4);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co4[] = { 25, -52, -17, 88, -115, 46 };
+ workspace[4] = tools::evaluate_even_polynomial(co4, s, 6) / (90720 * sc_5);
+ terms[1] = tools::evaluate_polynomial(workspace, eta0, 5);
+ //
+ // Now evaluate e2 and put it in terms[2]:
+ //
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co5[] = { 7, 12, -78, 52 };
+ workspace[0] = -tools::evaluate_even_polynomial(co5, s, 4) / (405 * sc_3);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co6[] = { -7, 2, 183, -370, 185 };
+ workspace[1] = tools::evaluate_even_polynomial(co6, s, 5) / (2592 * sc_4);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co7[] = { -533, 776, -1835, 10240, -13525, 5410 };
+ workspace[2] = -tools::evaluate_even_polynomial(co7, s, 6) / (204120 * sc_5);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co8[] = { -1579, 3747, -3372, -15821, 45588, -45213, 15071 };
+ workspace[3] = -tools::evaluate_even_polynomial(co8, s, 7) / (2099520 * sc_6);
+ terms[2] = tools::evaluate_polynomial(workspace, eta0, 4);
+ //
+ // And e3, and put it in terms[3]:
+ //
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co9[] = {449, -1259, -769, 6686, -9260, 3704 };
+ workspace[0] = tools::evaluate_even_polynomial(co9, s, 6) / (102060 * sc_5);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co10[] = { 63149, -151557, 140052, -727469, 2239932, -2251437, 750479 };
+ workspace[1] = -tools::evaluate_even_polynomial(co10, s, 7) / (20995200 * sc_6);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co11[] = { 29233, -78755, 105222, 146879, -1602610, 3195183, -2554139, 729754 };
+ workspace[2] = tools::evaluate_even_polynomial(co11, s, 8) / (36741600 * sc_7);
+ terms[3] = tools::evaluate_polynomial(workspace, eta0, 3);
+ //
+ // Bring the correction terms together to evaluate eta,
+ // this is the last equation on page 151:
+ //
+ T eta = tools::evaluate_polynomial(terms, T(1/r), 4);
+ //
+ // Now that we have eta we need to back solve for x,
+ // we seek the value of x that gives eta in Eq 3.2.
+ // The two methods used are described in section 5.
+ //
+ // Begin by defining a few variables we'll need later:
+ //
+ T x;
+ T s_2 = s * s;
+ T c_2 = c * c;
+ T alpha = c / s;
+ alpha *= alpha;
+ T lu = (-(eta * eta) / (2 * s_2) + log(s_2) + c_2 * log(c_2) / s_2);
+ //
+ // Temme doesn't specify what value to switch on here,
+ // but this seems to work pretty well:
+ //
+ if(fabs(eta) < 0.7)
+ {
+ //
+ // Small eta use the expansion Temme gives in the second equation
+ // of section 5, it's a polynomial in eta:
+ //
+ workspace[0] = s * s;
+ workspace[1] = s * c;
+ workspace[2] = (1 - 2 * workspace[0]) / 3;
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co12[] = { 1, -13, 13 };
+ workspace[3] = tools::evaluate_polynomial(co12, workspace[0], 3) / (36 * s * c);
+ static const BOOST_MATH_INT_TABLE_TYPE(T, int) co13[] = { 1, 21, -69, 46 };
+ workspace[4] = tools::evaluate_polynomial(co13, workspace[0], 4) / (270 * workspace[0] * c * c);
+ x = tools::evaluate_polynomial(workspace, eta, 5);
+#ifdef BOOST_INSTRUMENT
+ std::cout << "Estimating x with Temme method 2 (small eta): " << x << std::endl;
+#endif
+ }
+ else
+ {
+ //
+ // If eta is large we need to solve Eq 3.2 more directly,
+ // begin by getting an initial approximation for x from
+ // the last equation on page 155, this is a polynomial in u:
+ //
+ T u = exp(lu);
+ workspace[0] = u;
+ workspace[1] = alpha;
+ workspace[2] = 0;
+ workspace[3] = 3 * alpha * (3 * alpha + 1) / 6;
+ workspace[4] = 4 * alpha * (4 * alpha + 1) * (4 * alpha + 2) / 24;
+ workspace[5] = 5 * alpha * (5 * alpha + 1) * (5 * alpha + 2) * (5 * alpha + 3) / 120;
+ x = tools::evaluate_polynomial(workspace, u, 6);
+ //
+ // At this point we may or may not have the right answer, Eq-3.2 has
+ // two solutions for x for any given eta, however the mapping in 3.2
+ // is 1:1 with the sign of eta and x-sin^2(theta) being the same.
+ // So we can check if we have the right root of 3.2, and if not
+ // switch x for 1-x. This transformation is motivated by the fact
+ // that the distribution is *almost* symetric so 1-x will be in the right
+ // ball park for the solution:
+ //
+ if((x - s_2) * eta < 0)
+ x = 1 - x;
+#ifdef BOOST_INSTRUMENT
+ std::cout << "Estimating x with Temme method 2 (large eta): " << x << std::endl;
+#endif
+ }
+ //
+ // The final step is a few Newton-Raphson iterations to
+ // clean up our approximation for x, this is pretty cheap
+ // in general, and very cheap compared to an incomplete beta
+ // evaluation. The limits set on x come from the observation
+ // that the sign of eta and x-sin^2(theta) are the same.
+ //
+ T lower, upper;
+ if(eta < 0)
+ {
+ lower = 0;
+ upper = s_2;
+ }
+ else
+ {
+ lower = s_2;
+ upper = 1;
+ }
+ //
+ // If our initial approximation is out of bounds then bisect:
+ //
+ if((x < lower) || (x > upper))
+ x = (lower+upper) / 2;
+ //
+ // And iterate:
+ //
+ x = tools::newton_raphson_iterate(
+ temme_root_finder<T>(-lu, alpha), x, lower, upper, policies::digits<T, Policy>() / 2);
+
+ return x;
+}
+//
+// See:
+// "Asymptotic Inversion of the Incomplete Beta Function"
+// N.M. Temme
+// Journal of Computation and Applied Mathematics 41 (1992) 145-157.
+// Section 4.
+//
+template <class T, class Policy>
+T temme_method_3_ibeta_inverse(T a, T b, T p, T q, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // ADL of std names
+
+ //
+ // Begin by getting an initial approximation for the quantity
+ // eta from the dominant part of the incomplete beta:
+ //
+ T eta0;
+ if(p < q)
+ eta0 = boost::math::gamma_q_inv(b, p, pol);
+ else
+ eta0 = boost::math::gamma_p_inv(b, q, pol);
+ eta0 /= a;
+ //
+ // Define the variables and powers we'll need later on:
+ //
+ T mu = b / a;
+ T w = sqrt(1 + mu);
+ T w_2 = w * w;
+ T w_3 = w_2 * w;
+ T w_4 = w_2 * w_2;
+ T w_5 = w_3 * w_2;
+ T w_6 = w_3 * w_3;
+ T w_7 = w_4 * w_3;
+ T w_8 = w_4 * w_4;
+ T w_9 = w_5 * w_4;
+ T w_10 = w_5 * w_5;
+ T d = eta0 - mu;
+ T d_2 = d * d;
+ T d_3 = d_2 * d;
+ T d_4 = d_2 * d_2;
+ T w1 = w + 1;
+ T w1_2 = w1 * w1;
+ T w1_3 = w1 * w1_2;
+ T w1_4 = w1_2 * w1_2;
+ //
+ // Now we need to compute the purturbation error terms that
+ // convert eta0 to eta, these are all polynomials of polynomials.
+ // Probably these should be re-written to use tabulated data
+ // (see examples above), but it's less of a win in this case as we
+ // need to calculate the individual powers for the denominator terms
+ // anyway, so we might as well use them for the numerator-polynomials
+ // as well....
+ //
+ // Refer to p154-p155 for the details of these expansions:
+ //
+ T e1 = (w + 2) * (w - 1) / (3 * w);
+ e1 += (w_3 + 9 * w_2 + 21 * w + 5) * d / (36 * w_2 * w1);
+ e1 -= (w_4 - 13 * w_3 + 69 * w_2 + 167 * w + 46) * d_2 / (1620 * w1_2 * w_3);
+ e1 -= (7 * w_5 + 21 * w_4 + 70 * w_3 + 26 * w_2 - 93 * w - 31) * d_3 / (6480 * w1_3 * w_4);
+ e1 -= (75 * w_6 + 202 * w_5 + 188 * w_4 - 888 * w_3 - 1345 * w_2 + 118 * w + 138) * d_4 / (272160 * w1_4 * w_5);
+
+ T e2 = (28 * w_4 + 131 * w_3 + 402 * w_2 + 581 * w + 208) * (w - 1) / (1620 * w1 * w_3);
+ e2 -= (35 * w_6 - 154 * w_5 - 623 * w_4 - 1636 * w_3 - 3983 * w_2 - 3514 * w - 925) * d / (12960 * w1_2 * w_4);
+ e2 -= (2132 * w_7 + 7915 * w_6 + 16821 * w_5 + 35066 * w_4 + 87490 * w_3 + 141183 * w_2 + 95993 * w + 21640) * d_2 / (816480 * w_5 * w1_3);
+ e2 -= (11053 * w_8 + 53308 * w_7 + 117010 * w_6 + 163924 * w_5 + 116188 * w_4 - 258428 * w_3 - 677042 * w_2 - 481940 * w - 105497) * d_3 / (14696640 * w1_4 * w_6);
+
+ T e3 = -((3592 * w_7 + 8375 * w_6 - 1323 * w_5 - 29198 * w_4 - 89578 * w_3 - 154413 * w_2 - 116063 * w - 29632) * (w - 1)) / (816480 * w_5 * w1_2);
+ e3 -= (442043 * w_9 + 2054169 * w_8 + 3803094 * w_7 + 3470754 * w_6 + 2141568 * w_5 - 2393568 * w_4 - 19904934 * w_3 - 34714674 * w_2 - 23128299 * w - 5253353) * d / (146966400 * w_6 * w1_3);
+ e3 -= (116932 * w_10 + 819281 * w_9 + 2378172 * w_8 + 4341330 * w_7 + 6806004 * w_6 + 10622748 * w_5 + 18739500 * w_4 + 30651894 * w_3 + 30869976 * w_2 + 15431867 * w + 2919016) * d_2 / (146966400 * w1_4 * w_7);
+ //
+ // Combine eta0 and the error terms to compute eta (Second eqaution p155):
+ //
+ T eta = eta0 + e1 / a + e2 / (a * a) + e3 / (a * a * a);
+ //
+ // Now we need to solve Eq 4.2 to obtain x. For any given value of
+ // eta there are two solutions to this equation, and since the distribtion
+ // may be very skewed, these are not related by x ~ 1-x we used when
+ // implementing section 3 above. However we know that:
+ //
+ // cross < x <= 1 ; iff eta < mu
+ // x == cross ; iff eta == mu
+ // 0 <= x < cross ; iff eta > mu
+ //
+ // Where cross == 1 / (1 + mu)
+ // Many thanks to Prof Temme for clarifying this point.
+ //
+ // Therefore we'll just jump straight into Newton iterations
+ // to solve Eq 4.2 using these bounds, and simple bisection
+ // as the first guess, in practice this converges pretty quickly
+ // and we only need a few digits correct anyway:
+ //
+ if(eta <= 0)
+ eta = tools::min_value<T>();
+ T u = eta - mu * log(eta) + (1 + mu) * log(1 + mu) - mu;
+ T cross = 1 / (1 + mu);
+ T lower = eta < mu ? cross : 0;
+ T upper = eta < mu ? 1 : cross;
+ T x = (lower + upper) / 2;
+ x = tools::newton_raphson_iterate(
+ temme_root_finder<T>(u, mu), x, lower, upper, policies::digits<T, Policy>() / 2);
+#ifdef BOOST_INSTRUMENT
+ std::cout << "Estimating x with Temme method 3: " << x << std::endl;
+#endif
+ return x;
+}
+
+template <class T, class Policy>
+struct ibeta_roots
+{
+ ibeta_roots(T _a, T _b, T t, bool inv = false)
+ : a(_a), b(_b), target(t), invert(inv) {}
+
+ boost::math::tuple<T, T, T> operator()(T x)
+ {
+ BOOST_MATH_STD_USING // ADL of std names
+
+ BOOST_FPU_EXCEPTION_GUARD
+
+ T f1;
+ T y = 1 - x;
+ T f = ibeta_imp(a, b, x, Policy(), invert, true, &f1) - target;
+ if(invert)
+ f1 = -f1;
+ if(y == 0)
+ y = tools::min_value<T>() * 64;
+ if(x == 0)
+ x = tools::min_value<T>() * 64;
+
+ T f2 = f1 * (-y * a + (b - 2) * x + 1);
+ if(fabs(f2) < y * x * tools::max_value<T>())
+ f2 /= (y * x);
+ if(invert)
+ f2 = -f2;
+
+ // make sure we don't have a zero derivative:
+ if(f1 == 0)
+ f1 = (invert ? -1 : 1) * tools::min_value<T>() * 64;
+
+ return boost::math::make_tuple(f, f1, f2);
+ }
+private:
+ T a, b, target;
+ bool invert;
+};
+
+template <class T, class Policy>
+T ibeta_inv_imp(T a, T b, T p, T q, const Policy& pol, T* py)
+{
+ BOOST_MATH_STD_USING // For ADL of math functions.
+
+ //
+ // The flag invert is set to true if we swap a for b and p for q,
+ // in which case the result has to be subtracted from 1:
+ //
+ bool invert = false;
+ //
+ // Handle trivial cases first:
+ //
+ if(q == 0)
+ {
+ if(py) *py = 0;
+ return 1;
+ }
+ else if(p == 0)
+ {
+ if(py) *py = 1;
+ return 0;
+ }
+ else if(a == 1)
+ {
+ if(b == 1)
+ {
+ if(py) *py = 1 - p;
+ return p;
+ }
+ // Change things around so we can handle as b == 1 special case below:
+ std::swap(a, b);
+ std::swap(p, q);
+ invert = true;
+ }
+ //
+ // Depending upon which approximation method we use, we may end up
+ // calculating either x or y initially (where y = 1-x):
+ //
+ T x = 0; // Set to a safe zero to avoid a
+ // MSVC 2005 warning C4701: potentially uninitialized local variable 'x' used
+ // But code inspection appears to ensure that x IS assigned whatever the code path.
+ T y;
+
+ // For some of the methods we can put tighter bounds
+ // on the result than simply [0,1]:
+ //
+ T lower = 0;
+ T upper = 1;
+ //
+ // Student's T with b = 0.5 gets handled as a special case, swap
+ // around if the arguments are in the "wrong" order:
+ //
+ if(a == 0.5f)
+ {
+ if(b == 0.5f)
+ {
+ x = sin(p * constants::half_pi<T>());
+ x *= x;
+ if(py)
+ {
+ *py = sin(q * constants::half_pi<T>());
+ *py *= *py;
+ }
+ return x;
+ }
+ else if(b > 0.5f)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ invert = !invert;
+ }
+ }
+ //
+ // Select calculation method for the initial estimate:
+ //
+ if((b == 0.5f) && (a >= 0.5f) && (p != 1))
+ {
+ //
+ // We have a Student's T distribution:
+ x = find_ibeta_inv_from_t_dist(a, p, q, &y, pol);
+ }
+ else if(b == 1)
+ {
+ if(p < q)
+ {
+ if(a > 1)
+ {
+ x = pow(p, 1 / a);
+ y = -boost::math::expm1(log(p) / a, pol);
+ }
+ else
+ {
+ x = pow(p, 1 / a);
+ y = 1 - x;
+ }
+ }
+ else
+ {
+ x = exp(boost::math::log1p(-q, pol) / a);
+ y = -boost::math::expm1(boost::math::log1p(-q, pol) / a, pol);
+ }
+ if(invert)
+ std::swap(x, y);
+ if(py)
+ *py = y;
+ return x;
+ }
+ else if(a + b > 5)
+ {
+ //
+ // When a+b is large then we can use one of Prof Temme's
+ // asymptotic expansions, begin by swapping things around
+ // so that p < 0.5, we do this to avoid cancellations errors
+ // when p is large.
+ //
+ if(p > 0.5)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ invert = !invert;
+ }
+ T minv = (std::min)(a, b);
+ T maxv = (std::max)(a, b);
+ if((sqrt(minv) > (maxv - minv)) && (minv > 5))
+ {
+ //
+ // When a and b differ by a small amount
+ // the curve is quite symmetrical and we can use an error
+ // function to approximate the inverse. This is the cheapest
+ // of the three Temme expantions, and the calculated value
+ // for x will never be much larger than p, so we don't have
+ // to worry about cancellation as long as p is small.
+ //
+ x = temme_method_1_ibeta_inverse(a, b, p, pol);
+ y = 1 - x;
+ }
+ else
+ {
+ T r = a + b;
+ T theta = asin(sqrt(a / r));
+ T lambda = minv / r;
+ if((lambda >= 0.2) && (lambda <= 0.8) && (r >= 10))
+ {
+ //
+ // The second error function case is the next cheapest
+ // to use, it brakes down when the result is likely to be
+ // very small, if a+b is also small, but we can use a
+ // cheaper expansion there in any case. As before x won't
+ // be much larger than p, so as long as p is small we should
+ // be free of cancellation error.
+ //
+ T ppa = pow(p, 1/a);
+ if((ppa < 0.0025) && (a + b < 200))
+ {
+ x = ppa * pow(a * boost::math::beta(a, b, pol), 1/a);
+ }
+ else
+ x = temme_method_2_ibeta_inverse(a, b, p, r, theta, pol);
+ y = 1 - x;
+ }
+ else
+ {
+ //
+ // If we get here then a and b are very different in magnitude
+ // and we need to use the third of Temme's methods which
+ // involves inverting the incomplete gamma. This is much more
+ // expensive than the other methods. We also can only use this
+ // method when a > b, which can lead to cancellation errors
+ // if we really want y (as we will when x is close to 1), so
+ // a different expansion is used in that case.
+ //
+ if(a < b)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ invert = !invert;
+ }
+ //
+ // Try and compute the easy way first:
+ //
+ T bet = 0;
+ if(b < 2)
+ bet = boost::math::beta(a, b, pol);
+ if(bet != 0)
+ {
+ y = pow(b * q * bet, 1/b);
+ x = 1 - y;
+ }
+ else
+ y = 1;
+ if(y > 1e-5)
+ {
+ x = temme_method_3_ibeta_inverse(a, b, p, q, pol);
+ y = 1 - x;
+ }
+ }
+ }
+ }
+ else if((a < 1) && (b < 1))
+ {
+ //
+ // Both a and b less than 1,
+ // there is a point of inflection at xs:
+ //
+ T xs = (1 - a) / (2 - a - b);
+ //
+ // Now we need to ensure that we start our iteration from the
+ // right side of the inflection point:
+ //
+ T fs = boost::math::ibeta(a, b, xs, pol) - p;
+ if(fabs(fs) / p < tools::epsilon<T>() * 3)
+ {
+ // The result is at the point of inflection, best just return it:
+ *py = invert ? xs : 1 - xs;
+ return invert ? 1-xs : xs;
+ }
+ if(fs < 0)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ invert = !invert;
+ xs = 1 - xs;
+ }
+ T xg = pow(a * p * boost::math::beta(a, b, pol), 1/a);
+ x = xg / (1 + xg);
+ y = 1 / (1 + xg);
+ //
+ // And finally we know that our result is below the inflection
+ // point, so set an upper limit on our search:
+ //
+ if(x > xs)
+ x = xs;
+ upper = xs;
+ }
+ else if((a > 1) && (b > 1))
+ {
+ //
+ // Small a and b, both greater than 1,
+ // there is a point of inflection at xs,
+ // and it's complement is xs2, we must always
+ // start our iteration from the right side of the
+ // point of inflection.
+ //
+ T xs = (a - 1) / (a + b - 2);
+ T xs2 = (b - 1) / (a + b - 2);
+ T ps = boost::math::ibeta(a, b, xs, pol) - p;
+
+ if(ps < 0)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ std::swap(xs, xs2);
+ invert = !invert;
+ }
+ //
+ // Estimate x and y, using expm1 to get a good estimate
+ // for y when it's very small:
+ //
+ T lx = log(p * a * boost::math::beta(a, b, pol)) / a;
+ x = exp(lx);
+ y = x < 0.9 ? T(1 - x) : (T)(-boost::math::expm1(lx, pol));
+
+ if((b < a) && (x < 0.2))
+ {
+ //
+ // Under a limited range of circumstances we can improve
+ // our estimate for x, frankly it's clear if this has much effect!
+ //
+ T ap1 = a - 1;
+ T bm1 = b - 1;
+ T a_2 = a * a;
+ T a_3 = a * a_2;
+ T b_2 = b * b;
+ T terms[5] = { 0, 1 };
+ terms[2] = bm1 / ap1;
+ ap1 *= ap1;
+ terms[3] = bm1 * (3 * a * b + 5 * b + a_2 - a - 4) / (2 * (a + 2) * ap1);
+ ap1 *= (a + 1);
+ terms[4] = bm1 * (33 * a * b_2 + 31 * b_2 + 8 * a_2 * b_2 - 30 * a * b - 47 * b + 11 * a_2 * b + 6 * a_3 * b + 18 + 4 * a - a_3 + a_2 * a_2 - 10 * a_2)
+ / (3 * (a + 3) * (a + 2) * ap1);
+ x = tools::evaluate_polynomial(terms, x, 5);
+ }
+ //
+ // And finally we know that our result is below the inflection
+ // point, so set an upper limit on our search:
+ //
+ if(x > xs)
+ x = xs;
+ upper = xs;
+ }
+ else /*if((a <= 1) != (b <= 1))*/
+ {
+ //
+ // If all else fails we get here, only one of a and b
+ // is above 1, and a+b is small. Start by swapping
+ // things around so that we have a concave curve with b > a
+ // and no points of inflection in [0,1]. As long as we expect
+ // x to be small then we can use the simple (and cheap) power
+ // term to estimate x, but when we expect x to be large then
+ // this greatly underestimates x and leaves us trying to
+ // iterate "round the corner" which may take almost forever...
+ //
+ // We could use Temme's inverse gamma function case in that case,
+ // this works really rather well (albeit expensively) even though
+ // strictly speaking we're outside it's defined range.
+ //
+ // However it's expensive to compute, and an alternative approach
+ // which models the curve as a distorted quarter circle is much
+ // cheaper to compute, and still keeps the number of iterations
+ // required down to a reasonable level. With thanks to Prof Temme
+ // for this suggestion.
+ //
+ if(b < a)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ invert = !invert;
+ }
+ if(pow(p, 1/a) < 0.5)
+ {
+ x = pow(p * a * boost::math::beta(a, b, pol), 1 / a);
+ if(x == 0)
+ x = boost::math::tools::min_value<T>();
+ y = 1 - x;
+ }
+ else /*if(pow(q, 1/b) < 0.1)*/
+ {
+ // model a distorted quarter circle:
+ y = pow(1 - pow(p, b * boost::math::beta(a, b, pol)), 1/b);
+ if(y == 0)
+ y = boost::math::tools::min_value<T>();
+ x = 1 - y;
+ }
+ }
+
+ //
+ // Now we have a guess for x (and for y) we can set things up for
+ // iteration. If x > 0.5 it pays to swap things round:
+ //
+ if(x > 0.5)
+ {
+ std::swap(a, b);
+ std::swap(p, q);
+ std::swap(x, y);
+ invert = !invert;
+ T l = 1 - upper;
+ T u = 1 - lower;
+ lower = l;
+ upper = u;
+ }
+ //
+ // lower bound for our search:
+ //
+ // We're not interested in denormalised answers as these tend to
+ // these tend to take up lots of iterations, given that we can't get
+ // accurate derivatives in this area (they tend to be infinite).
+ //
+ if(lower == 0)
+ {
+ if(invert && (py == 0))
+ {
+ //
+ // We're not interested in answers smaller than machine epsilon:
+ //
+ lower = boost::math::tools::epsilon<T>();
+ if(x < lower)
+ x = lower;
+ }
+ else
+ lower = boost::math::tools::min_value<T>();
+ if(x < lower)
+ x = lower;
+ }
+ //
+ // Figure out how many digits to iterate towards:
+ //
+ int digits = boost::math::policies::digits<T, Policy>() / 2;
+ if((x < 1e-50) && ((a < 1) || (b < 1)))
+ {
+ //
+ // If we're in a region where the first derivative is very
+ // large, then we have to take care that the root-finder
+ // doesn't terminate prematurely. We'll bump the precision
+ // up to avoid this, but we have to take care not to set the
+ // precision too high or the last few iterations will just
+ // thrash around and convergence may be slow in this case.
+ // Try 3/4 of machine epsilon:
+ //
+ digits *= 3;
+ digits /= 2;
+ }
+ //
+ // Now iterate, we can use either p or q as the target here
+ // depending on which is smaller:
+ //
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+ x = boost::math::tools::halley_iterate(
+ boost::math::detail::ibeta_roots<T, Policy>(a, b, (p < q ? p : q), (p < q ? false : true)), x, lower, upper, digits, max_iter);
+ policies::check_root_iterations<T>("boost::math::ibeta<%1%>(%1%, %1%, %1%)", max_iter, pol);
+ //
+ // We don't really want these asserts here, but they are useful for sanity
+ // checking that we have the limits right, uncomment if you suspect bugs *only*.
+ //
+ //BOOST_ASSERT(x != upper);
+ //BOOST_ASSERT((x != lower) || (x == boost::math::tools::min_value<T>()) || (x == boost::math::tools::epsilon<T>()));
+ //
+ // Tidy up, if we "lower" was too high then zero is the best answer we have:
+ //
+ if(x == lower)
+ x = 0;
+ if(py)
+ *py = invert ? x : 1 - x;
+ return invert ? 1-x : x;
+}
+
+} // namespace detail
+
+template <class T1, class T2, class T3, class T4, class Policy>
+inline typename tools::promote_args<T1, T2, T3, T4>::type
+ ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol)
+{
+ static const char* function = "boost::math::ibeta_inv<%1%>(%1%,%1%,%1%)";
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2, T3, T4>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ if(a <= 0)
+ return policies::raise_domain_error<result_type>(function, "The argument a to the incomplete beta function inverse must be greater than zero (got a=%1%).", a, pol);
+ if(b <= 0)
+ return policies::raise_domain_error<result_type>(function, "The argument b to the incomplete beta function inverse must be greater than zero (got b=%1%).", b, pol);
+ if((p < 0) || (p > 1))
+ return policies::raise_domain_error<result_type>(function, "Argument p outside the range [0,1] in the incomplete beta function inverse (got p=%1%).", p, pol);
+
+ value_type rx, ry;
+
+ rx = detail::ibeta_inv_imp(
+ static_cast<value_type>(a),
+ static_cast<value_type>(b),
+ static_cast<value_type>(p),
+ static_cast<value_type>(1 - p),
+ forwarding_policy(), &ry);
+
+ if(py) *py = policies::checked_narrowing_cast<T4, forwarding_policy>(ry, function);
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(rx, function);
+}
+
+template <class T1, class T2, class T3, class T4>
+inline typename tools::promote_args<T1, T2, T3, T4>::type
+ ibeta_inv(T1 a, T2 b, T3 p, T4* py)
+{
+ return ibeta_inv(a, b, p, py, policies::policy<>());
+}
+
+template <class T1, class T2, class T3>
+inline typename tools::promote_args<T1, T2, T3>::type
+ ibeta_inv(T1 a, T2 b, T3 p)
+{
+ typedef typename tools::promote_args<T1, T2, T3>::type result_type;
+ return ibeta_inv(a, b, p, static_cast<result_type*>(0), policies::policy<>());
+}
+
+template <class T1, class T2, class T3, class Policy>
+inline typename tools::promote_args<T1, T2, T3>::type
+ ibeta_inv(T1 a, T2 b, T3 p, const Policy& pol)
+{
+ typedef typename tools::promote_args<T1, T2, T3>::type result_type;
+ return ibeta_inv(a, b, p, static_cast<result_type*>(0), pol);
+}
+
+template <class T1, class T2, class T3, class T4, class Policy>
+inline typename tools::promote_args<T1, T2, T3, T4>::type
+ ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol)
+{
+ static const char* function = "boost::math::ibetac_inv<%1%>(%1%,%1%,%1%)";
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2, T3, T4>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ if(a <= 0)
+ return policies::raise_domain_error<result_type>(function, "The argument a to the incomplete beta function inverse must be greater than zero (got a=%1%).", a, pol);
+ if(b <= 0)
+ return policies::raise_domain_error<result_type>(function, "The argument b to the incomplete beta function inverse must be greater than zero (got b=%1%).", b, pol);
+ if((q < 0) || (q > 1))
+ return policies::raise_domain_error<result_type>(function, "Argument q outside the range [0,1] in the incomplete beta function inverse (got q=%1%).", q, pol);
+
+ value_type rx, ry;
+
+ rx = detail::ibeta_inv_imp(
+ static_cast<value_type>(a),
+ static_cast<value_type>(b),
+ static_cast<value_type>(1 - q),
+ static_cast<value_type>(q),
+ forwarding_policy(), &ry);
+
+ if(py) *py = policies::checked_narrowing_cast<T4, forwarding_policy>(ry, function);
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(rx, function);
+}
+
+template <class T1, class T2, class T3, class T4>
+inline typename tools::promote_args<T1, T2, T3, T4>::type
+ ibetac_inv(T1 a, T2 b, T3 q, T4* py)
+{
+ return ibetac_inv(a, b, q, py, policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inv(RT1 a, RT2 b, RT3 q)
+{
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ return ibetac_inv(a, b, q, static_cast<result_type*>(0), policies::policy<>());
+}
+
+template <class RT1, class RT2, class RT3, class Policy>
+inline typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy& pol)
+{
+ typedef typename tools::promote_args<RT1, RT2, RT3>::type result_type;
+ return ibetac_inv(a, b, q, static_cast<result_type*>(0), pol);
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_inverse.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_inverse.hpp
new file mode 100644
index 00000000000..fd0189ca6d5
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_inverse.hpp
@@ -0,0 +1,551 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+#define BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/tuple.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/policies/error_handling.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail{
+
+template <class T>
+T find_inverse_s(T p, T q)
+{
+ //
+ // Computation of the Incomplete Gamma Function Ratios and their Inverse
+ // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+ // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+ // December 1986, Pages 377-393.
+ //
+ // See equation 32.
+ //
+ BOOST_MATH_STD_USING
+ T t;
+ if(p < 0.5)
+ {
+ t = sqrt(-2 * log(p));
+ }
+ else
+ {
+ t = sqrt(-2 * log(q));
+ }
+ static const double a[4] = { 3.31125922108741, 11.6616720288968, 4.28342155967104, 0.213623493715853 };
+ static const double b[5] = { 1, 6.61053765625462, 6.40691597760039, 1.27364489782223, 0.3611708101884203e-1 };
+ T s = t - tools::evaluate_polynomial(a, t) / tools::evaluate_polynomial(b, t);
+ if(p < 0.5)
+ s = -s;
+ return s;
+}
+
+template <class T>
+T didonato_SN(T a, T x, unsigned N, T tolerance = 0)
+{
+ //
+ // Computation of the Incomplete Gamma Function Ratios and their Inverse
+ // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+ // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+ // December 1986, Pages 377-393.
+ //
+ // See equation 34.
+ //
+ T sum = 1;
+ if(N >= 1)
+ {
+ T partial = x / (a + 1);
+ sum += partial;
+ for(unsigned i = 2; i <= N; ++i)
+ {
+ partial *= x / (a + i);
+ sum += partial;
+ if(partial < tolerance)
+ break;
+ }
+ }
+ return sum;
+}
+
+template <class T, class Policy>
+inline T didonato_FN(T p, T a, T x, unsigned N, T tolerance, const Policy& pol)
+{
+ //
+ // Computation of the Incomplete Gamma Function Ratios and their Inverse
+ // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+ // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+ // December 1986, Pages 377-393.
+ //
+ // See equation 34.
+ //
+ BOOST_MATH_STD_USING
+ T u = log(p) + boost::math::lgamma(a + 1, pol);
+ return exp((u + x - log(didonato_SN(a, x, N, tolerance))) / a);
+}
+
+template <class T, class Policy>
+T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits)
+{
+ //
+ // In order to understand what's going on here, you will
+ // need to refer to:
+ //
+ // Computation of the Incomplete Gamma Function Ratios and their Inverse
+ // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+ // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+ // December 1986, Pages 377-393.
+ //
+ BOOST_MATH_STD_USING
+
+ T result;
+ *p_has_10_digits = false;
+
+ if(a == 1)
+ {
+ result = -log(q);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if(a < 1)
+ {
+ T g = boost::math::tgamma(a, pol);
+ T b = q * g;
+ BOOST_MATH_INSTRUMENT_VARIABLE(g);
+ BOOST_MATH_INSTRUMENT_VARIABLE(b);
+ if((b > 0.6) || ((b >= 0.45) && (a >= 0.3)))
+ {
+ // DiDonato & Morris Eq 21:
+ //
+ // There is a slight variation from DiDonato and Morris here:
+ // the first form given here is unstable when p is close to 1,
+ // making it impossible to compute the inverse of Q(a,x) for small
+ // q. Fortunately the second form works perfectly well in this case.
+ //
+ T u;
+ if((b * q > 1e-8) && (q > 1e-5))
+ {
+ u = pow(p * g * a, 1 / a);
+ BOOST_MATH_INSTRUMENT_VARIABLE(u);
+ }
+ else
+ {
+ u = exp((-q / a) - constants::euler<T>());
+ BOOST_MATH_INSTRUMENT_VARIABLE(u);
+ }
+ result = u / (1 - (u / (a + 1)));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if((a < 0.3) && (b >= 0.35))
+ {
+ // DiDonato & Morris Eq 22:
+ T t = exp(-constants::euler<T>() - b);
+ T u = t * exp(t);
+ result = t * exp(u);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if((b > 0.15) || (a >= 0.3))
+ {
+ // DiDonato & Morris Eq 23:
+ T y = -log(b);
+ T u = y - (1 - a) * log(y);
+ result = y - (1 - a) * log(u) - log(1 + (1 - a) / (1 + u));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if (b > 0.1)
+ {
+ // DiDonato & Morris Eq 24:
+ T y = -log(b);
+ T u = y - (1 - a) * log(y);
+ result = y - (1 - a) * log(u) - log((u * u + 2 * (3 - a) * u + (2 - a) * (3 - a)) / (u * u + (5 - a) * u + 2));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ // DiDonato & Morris Eq 25:
+ T y = -log(b);
+ T c1 = (a - 1) * log(y);
+ T c1_2 = c1 * c1;
+ T c1_3 = c1_2 * c1;
+ T c1_4 = c1_2 * c1_2;
+ T a_2 = a * a;
+ T a_3 = a_2 * a;
+
+ T c2 = (a - 1) * (1 + c1);
+ T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2);
+ T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6);
+ T c5 = (a - 1) * (-(c1_4 / 4)
+ + (11 * a - 17) * c1_3 / 6
+ + (-3 * a_2 + 13 * a -13) * c1_2
+ + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2
+ + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12);
+
+ T y_2 = y * y;
+ T y_3 = y_2 * y;
+ T y_4 = y_2 * y_2;
+ result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ if(b < 1e-28f)
+ *p_has_10_digits = true;
+ }
+ }
+ else
+ {
+ // DiDonato and Morris Eq 31:
+ T s = find_inverse_s(p, q);
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(s);
+
+ T s_2 = s * s;
+ T s_3 = s_2 * s;
+ T s_4 = s_2 * s_2;
+ T s_5 = s_4 * s;
+ T ra = sqrt(a);
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(ra);
+
+ T w = a + s * ra + (s * s -1) / 3;
+ w += (s_3 - 7 * s) / (36 * ra);
+ w -= (3 * s_4 + 7 * s_2 - 16) / (810 * a);
+ w += (9 * s_5 + 256 * s_3 - 433 * s) / (38880 * a * ra);
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(w);
+
+ if((a >= 500) && (fabs(1 - w / a) < 1e-6))
+ {
+ result = w;
+ *p_has_10_digits = true;
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if (p > 0.5)
+ {
+ if(w < 3 * a)
+ {
+ result = w;
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ T D = (std::max)(T(2), T(a * (a - 1)));
+ T lg = boost::math::lgamma(a, pol);
+ T lb = log(q) + lg;
+ if(lb < -D * 2.3)
+ {
+ // DiDonato and Morris Eq 25:
+ T y = -lb;
+ T c1 = (a - 1) * log(y);
+ T c1_2 = c1 * c1;
+ T c1_3 = c1_2 * c1;
+ T c1_4 = c1_2 * c1_2;
+ T a_2 = a * a;
+ T a_3 = a_2 * a;
+
+ T c2 = (a - 1) * (1 + c1);
+ T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2);
+ T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6);
+ T c5 = (a - 1) * (-(c1_4 / 4)
+ + (11 * a - 17) * c1_3 / 6
+ + (-3 * a_2 + 13 * a -13) * c1_2
+ + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2
+ + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12);
+
+ T y_2 = y * y;
+ T y_3 = y_2 * y;
+ T y_4 = y_2 * y_2;
+ result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ // DiDonato and Morris Eq 33:
+ T u = -lb + (a - 1) * log(w) - log(1 + (1 - a) / (1 + w));
+ result = -lb + (a - 1) * log(u) - log(1 + (1 - a) / (1 + u));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ }
+ else
+ {
+ T z = w;
+ T ap1 = a + 1;
+ T ap2 = a + 2;
+ if(w < 0.15f * ap1)
+ {
+ // DiDonato and Morris Eq 35:
+ T v = log(p) + boost::math::lgamma(ap1, pol);
+ z = exp((v + w) / a);
+ s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol);
+ z = exp((v + z - s) / a);
+ s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol);
+ z = exp((v + z - s) / a);
+ s = boost::math::log1p(z / ap1 * (1 + z / ap2 * (1 + z / (a + 3))), pol);
+ z = exp((v + z - s) / a);
+ BOOST_MATH_INSTRUMENT_VARIABLE(z);
+ }
+
+ if((z <= 0.01 * ap1) || (z > 0.7 * ap1))
+ {
+ result = z;
+ if(z <= 0.002 * ap1)
+ *p_has_10_digits = true;
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ // DiDonato and Morris Eq 36:
+ T ls = log(didonato_SN(a, z, 100, T(1e-4)));
+ T v = log(p) + boost::math::lgamma(ap1, pol);
+ z = exp((v + z - ls) / a);
+ result = z * (1 - (a * log(z) - z - v + ls) / (a - z));
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ }
+ return result;
+}
+
+template <class T, class Policy>
+struct gamma_p_inverse_func
+{
+ gamma_p_inverse_func(T a_, T p_, bool inv) : a(a_), p(p_), invert(inv)
+ {
+ //
+ // If p is too near 1 then P(x) - p suffers from cancellation
+ // errors causing our root-finding algorithms to "thrash", better
+ // to invert in this case and calculate Q(x) - (1-p) instead.
+ //
+ // Of course if p is *very* close to 1, then the answer we get will
+ // be inaccurate anyway (because there's not enough information in p)
+ // but at least we will converge on the (inaccurate) answer quickly.
+ //
+ if(p > 0.9)
+ {
+ p = 1 - p;
+ invert = !invert;
+ }
+ }
+
+ boost::math::tuple<T, T, T> operator()(const T& x)const
+ {
+ BOOST_FPU_EXCEPTION_GUARD
+ //
+ // Calculate P(x) - p and the first two derivates, or if the invert
+ // flag is set, then Q(x) - q and it's derivatives.
+ //
+ typedef typename policies::evaluation<T, Policy>::type value_type;
+ // typedef typename lanczos::lanczos<T, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ BOOST_MATH_STD_USING // For ADL of std functions.
+
+ T f, f1;
+ value_type ft;
+ f = static_cast<T>(boost::math::detail::gamma_incomplete_imp(
+ static_cast<value_type>(a),
+ static_cast<value_type>(x),
+ true, invert,
+ forwarding_policy(), &ft));
+ f1 = static_cast<T>(ft);
+ T f2;
+ T div = (a - x - 1) / x;
+ f2 = f1;
+ if((fabs(div) > 1) && (tools::max_value<T>() / fabs(div) < f2))
+ {
+ // overflow:
+ f2 = -tools::max_value<T>() / 2;
+ }
+ else
+ {
+ f2 *= div;
+ }
+
+ if(invert)
+ {
+ f1 = -f1;
+ f2 = -f2;
+ }
+
+ return boost::math::make_tuple(static_cast<T>(f - p), f1, f2);
+ }
+private:
+ T a, p;
+ bool invert;
+};
+
+template <class T, class Policy>
+T gamma_p_inv_imp(T a, T p, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // ADL of std functions.
+
+ static const char* function = "boost::math::gamma_p_inv<%1%>(%1%, %1%)";
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(a);
+ BOOST_MATH_INSTRUMENT_VARIABLE(p);
+
+ if(a <= 0)
+ return policies::raise_domain_error<T>(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol);
+ if((p < 0) || (p > 1))
+ return policies::raise_domain_error<T>(function, "Probabilty must be in the range [0,1] in the incomplete gamma function inverse (got p=%1%).", p, pol);
+ if(p == 1)
+ return policies::raise_overflow_error<T>(function, 0, Policy());
+ if(p == 0)
+ return 0;
+ bool has_10_digits;
+ T guess = detail::find_inverse_gamma<T>(a, p, 1 - p, pol, &has_10_digits);
+ if((policies::digits<T, Policy>() <= 36) && has_10_digits)
+ return guess;
+ T lower = tools::min_value<T>();
+ if(guess <= lower)
+ guess = tools::min_value<T>();
+ BOOST_MATH_INSTRUMENT_VARIABLE(guess);
+ //
+ // Work out how many digits to converge to, normally this is
+ // 2/3 of the digits in T, but if the first derivative is very
+ // large convergence is slow, so we'll bump it up to full
+ // precision to prevent premature termination of the root-finding routine.
+ //
+ unsigned digits = policies::digits<T, Policy>();
+ if(digits < 30)
+ {
+ digits *= 2;
+ digits /= 3;
+ }
+ else
+ {
+ digits /= 2;
+ digits -= 1;
+ }
+ if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon<T>())))
+ digits = policies::digits<T, Policy>() - 2;
+ //
+ // Go ahead and iterate:
+ //
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+ guess = tools::halley_iterate(
+ detail::gamma_p_inverse_func<T, Policy>(a, p, false),
+ guess,
+ lower,
+ tools::max_value<T>(),
+ digits,
+ max_iter);
+ policies::check_root_iterations<T>(function, max_iter, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(guess);
+ if(guess == lower)
+ guess = policies::raise_underflow_error<T>(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol);
+ return guess;
+}
+
+template <class T, class Policy>
+T gamma_q_inv_imp(T a, T q, const Policy& pol)
+{
+ BOOST_MATH_STD_USING // ADL of std functions.
+
+ static const char* function = "boost::math::gamma_q_inv<%1%>(%1%, %1%)";
+
+ if(a <= 0)
+ return policies::raise_domain_error<T>(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol);
+ if((q < 0) || (q > 1))
+ return policies::raise_domain_error<T>(function, "Probabilty must be in the range [0,1] in the incomplete gamma function inverse (got q=%1%).", q, pol);
+ if(q == 0)
+ return policies::raise_overflow_error<T>(function, 0, Policy());
+ if(q == 1)
+ return 0;
+ bool has_10_digits;
+ T guess = detail::find_inverse_gamma<T>(a, 1 - q, q, pol, &has_10_digits);
+ if((policies::digits<T, Policy>() <= 36) && has_10_digits)
+ return guess;
+ T lower = tools::min_value<T>();
+ if(guess <= lower)
+ guess = tools::min_value<T>();
+ //
+ // Work out how many digits to converge to, normally this is
+ // 2/3 of the digits in T, but if the first derivative is very
+ // large convergence is slow, so we'll bump it up to full
+ // precision to prevent premature termination of the root-finding routine.
+ //
+ unsigned digits = policies::digits<T, Policy>();
+ if(digits < 30)
+ {
+ digits *= 2;
+ digits /= 3;
+ }
+ else
+ {
+ digits /= 2;
+ digits -= 1;
+ }
+ if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon<T>())))
+ digits = policies::digits<T, Policy>();
+ //
+ // Go ahead and iterate:
+ //
+ boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+ guess = tools::halley_iterate(
+ detail::gamma_p_inverse_func<T, Policy>(a, q, true),
+ guess,
+ lower,
+ tools::max_value<T>(),
+ digits,
+ max_iter);
+ policies::check_root_iterations<T>(function, max_iter, pol);
+ if(guess == lower)
+ guess = policies::raise_underflow_error<T>(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol);
+ return guess;
+}
+
+} // namespace detail
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p_inv(T1 a, T2 p, const Policy& pol)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ return detail::gamma_p_inv_imp(
+ static_cast<result_type>(a),
+ static_cast<result_type>(p), pol);
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_q_inv(T1 a, T2 p, const Policy& pol)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ return detail::gamma_q_inv_imp(
+ static_cast<result_type>(a),
+ static_cast<result_type>(p), pol);
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p_inv(T1 a, T2 p)
+{
+ return gamma_p_inv(a, p, policies::policy<>());
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_q_inv(T1 a, T2 p)
+{
+ return gamma_q_inv(a, p, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_large.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_large.hpp
new file mode 100644
index 00000000000..eb3d4ba93e7
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/igamma_large.hpp
@@ -0,0 +1,768 @@
+// Copyright John Maddock 2006.
+// 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 file implements the asymptotic expansions of the incomplete
+// gamma functions P(a, x) and Q(a, x), used when a is large and
+// x ~ a.
+//
+// The primary reference is:
+//
+// "The Asymptotic Expansion of the Incomplete Gamma Functions"
+// N. M. Temme.
+// Siam J. Math Anal. Vol 10 No 4, July 1979, p757.
+//
+// A different way of evaluating these expansions,
+// plus a lot of very useful background information is in:
+//
+// "A Set of Algorithms For the Incomplete Gamma Functions."
+// N. M. Temme.
+// Probability in the Engineering and Informational Sciences,
+// 8, 1994, 291.
+//
+// An alternative implementation is in:
+//
+// "Computation of the Incomplete Gamma Function Ratios and their Inverse."
+// A. R. Didonato and A. H. Morris.
+// ACM TOMS, Vol 12, No 4, Dec 1986, p377.
+//
+// There are various versions of the same code below, each accurate
+// to a different precision. To understand the code, refer to Didonato
+// and Morris, from Eq 17 and 18 onwards.
+//
+// The coefficients used here are not taken from Didonato and Morris:
+// the domain over which these expansions are used is slightly different
+// to theirs, and their constants are not quite accurate enough for
+// 128-bit long double's. Instead the coefficients were calculated
+// using the methods described by Temme p762 from Eq 3.8 onwards.
+// The values obtained agree with those obtained by Didonato and Morris
+// (at least to the first 30 digits that they provide).
+// At double precision the degrees of polynomial required for full
+// machine precision are close to those recomended to Didonato and Morris,
+// but of course many more terms are needed for larger types.
+//
+#ifndef BOOST_MATH_DETAIL_IGAMMA_LARGE
+#define BOOST_MATH_DETAIL_IGAMMA_LARGE
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+namespace boost{ namespace math{ namespace detail{
+
+// This version will never be called (at runtime), it's a stub used
+// when T is unsuitable to be passed to these routines:
+//
+template <class T, class Policy>
+inline T igamma_temme_large(T, T, const Policy& /* pol */, mpl::int_<0> const *)
+{
+ // stub function, should never actually be called
+ BOOST_ASSERT(0);
+ return 0;
+}
+//
+// This version is accurate for up to 64-bit mantissa's,
+// (80-bit long double, or 10^-20).
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, mpl::int_<64> const *)
+{
+ BOOST_MATH_STD_USING // ADL of std functions
+ T sigma = (x - a) / a;
+ T phi = -boost::math::log1pmx(sigma, pol);
+ T y = a * phi;
+ T z = sqrt(2 * phi);
+ if(x < a)
+ z = -z;
+
+ T workspace[13];
+
+ static const T C0[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.333333333333333333333),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0833333333333333333333),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0148148148148148148148),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00115740740740740740741),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000352733686067019400353),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0001787551440329218107),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.39192631785224377817e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.218544851067999216147e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.18540622107151599607e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.829671134095308600502e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.176659527368260793044e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.670785354340149858037e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.102618097842403080426e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.438203601845335318655e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.914769958223679023418e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.255141939949462497669e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.583077213255042506746e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.243619480206674162437e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.502766928011417558909e-11),
+ };
+ workspace[0] = tools::evaluate_polynomial(C0, z);
+
+ static const T C1[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00185185185185185185185),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00347222222222222222222),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00264550264550264550265),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000990226337448559670782),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000205761316872427983539),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.40187757201646090535e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.18098550334489977837e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.764916091608111008464e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.161209008945634460038e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.464712780280743434226e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.137863344691572095931e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.575254560351770496402e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.119516285997781473243e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.175432417197476476238e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.100915437106004126275e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.416279299184258263623e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.856390702649298063807e-10),
+ };
+ workspace[1] = tools::evaluate_polynomial(C1, z);
+
+ static const T C2[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00413359788359788359788),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00268132716049382716049),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000771604938271604938272),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.200938786008230452675e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000107366532263651605215),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.529234488291201254164e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.127606351886187277134e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.342357873409613807419e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.137219573090629332056e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.629899213838005502291e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.142806142060642417916e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.204770984219908660149e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.140925299108675210533e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.622897408492202203356e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.136704883966171134993e-8),
+ };
+ workspace[2] = tools::evaluate_polynomial(C2, z);
+
+ static const T C3[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000649434156378600823045),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000229472093621399176955),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000469189494395255712128),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000267720632062838852962),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.756180167188397641073e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.239650511386729665193e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.110826541153473023615e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.56749528269915965675e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.142309007324358839146e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.278610802915281422406e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.169584040919302772899e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.809946490538808236335e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.191111684859736540607e-7),
+ };
+ workspace[3] = tools::evaluate_polynomial(C3, z);
+
+ static const T C4[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000861888290916711698605),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000784039221720066627474),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000299072480303190179733),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.146384525788434181781e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.664149821546512218666e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.396836504717943466443e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.113757269706784190981e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.250749722623753280165e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.169541495365583060147e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.890750753220530968883e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.229293483400080487057e-6),
+ };
+ workspace[4] = tools::evaluate_polynomial(C4, z);
+
+ static const T C5[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000336798553366358150309),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.697281375836585777429e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277275324495939207873),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000199325705161888477003),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.679778047793720783882e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.141906292064396701483e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.135940481897686932785e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.801847025633420153972e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.229148117650809517038e-5),
+ };
+ workspace[5] = tools::evaluate_polynomial(C5, z);
+
+ static const T C6[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000531307936463992223166),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000592166437353693882865),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000270878209671804482771),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.790235323266032787212e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.815396936756196875093e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.561168275310624965004e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.183291165828433755673e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.307961345060330478256e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.346515536880360908674e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.20291327396058603727e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.57887928631490037089e-6),
+ };
+ workspace[6] = tools::evaluate_polynomial(C6, z);
+
+ static const T C7[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000344367606892377671254),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.517179090826059219337e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000334931610811422363117),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000281269515476323702274),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000109765822446847310235),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.127410090954844853795e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.277444515115636441571e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.182634888057113326614e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.578769494973505239894e-5),
+ };
+ workspace[7] = tools::evaluate_polynomial(C7, z);
+
+ static const T C8[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000652623918595309418922),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000839498720672087279993),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000438297098541721005061),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.696909145842055197137e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000166448466420675478374),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000127835176797692185853),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.462995326369130429061e-4),
+ };
+ workspace[8] = tools::evaluate_polynomial(C8, z);
+
+ static const T C9[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000596761290192746250124),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.720489541602001055909e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000678230883766732836162),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0006401475260262758451),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277501076343287044992),
+ };
+ workspace[9] = tools::evaluate_polynomial(C9, z);
+
+ static const T C10[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00133244544948006563713),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0019144384985654775265),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00110893691345966373396),
+ };
+ workspace[10] = tools::evaluate_polynomial(C10, z);
+
+ static const T C11[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00157972766073083495909),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000162516262783915816899),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00206334210355432762645),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00213896861856890981541),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00101085593912630031708),
+ };
+ workspace[11] = tools::evaluate_polynomial(C11, z);
+
+ static const T C12[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00407251211951401664727),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00640336283380806979482),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00404101610816766177474),
+ };
+ workspace[12] = tools::evaluate_polynomial(C12, z);
+
+ T result = tools::evaluate_polynomial<13, T, T>(workspace, 1/a);
+ result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+ if(x < a)
+ result = -result;
+
+ result += boost::math::erfc(sqrt(y), pol) / 2;
+
+ return result;
+}
+//
+// This one is accurate for 53-bit mantissa's
+// (IEEE double precision or 10^-17).
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, mpl::int_<53> const *)
+{
+ BOOST_MATH_STD_USING // ADL of std functions
+ T sigma = (x - a) / a;
+ T phi = -boost::math::log1pmx(sigma, pol);
+ T y = a * phi;
+ T z = sqrt(2 * phi);
+ if(x < a)
+ z = -z;
+
+ T workspace[10];
+
+ static const T C0[] = {
+ static_cast<T>(-0.33333333333333333L),
+ static_cast<T>(0.083333333333333333L),
+ static_cast<T>(-0.014814814814814815L),
+ static_cast<T>(0.0011574074074074074L),
+ static_cast<T>(0.0003527336860670194L),
+ static_cast<T>(-0.00017875514403292181L),
+ static_cast<T>(0.39192631785224378e-4L),
+ static_cast<T>(-0.21854485106799922e-5L),
+ static_cast<T>(-0.185406221071516e-5L),
+ static_cast<T>(0.8296711340953086e-6L),
+ static_cast<T>(-0.17665952736826079e-6L),
+ static_cast<T>(0.67078535434014986e-8L),
+ static_cast<T>(0.10261809784240308e-7L),
+ static_cast<T>(-0.43820360184533532e-8L),
+ static_cast<T>(0.91476995822367902e-9L),
+ };
+ workspace[0] = tools::evaluate_polynomial(C0, z);
+
+ static const T C1[] = {
+ static_cast<T>(-0.0018518518518518519L),
+ static_cast<T>(-0.0034722222222222222L),
+ static_cast<T>(0.0026455026455026455L),
+ static_cast<T>(-0.00099022633744855967L),
+ static_cast<T>(0.00020576131687242798L),
+ static_cast<T>(-0.40187757201646091e-6L),
+ static_cast<T>(-0.18098550334489978e-4L),
+ static_cast<T>(0.76491609160811101e-5L),
+ static_cast<T>(-0.16120900894563446e-5L),
+ static_cast<T>(0.46471278028074343e-8L),
+ static_cast<T>(0.1378633446915721e-6L),
+ static_cast<T>(-0.5752545603517705e-7L),
+ static_cast<T>(0.11951628599778147e-7L),
+ };
+ workspace[1] = tools::evaluate_polynomial(C1, z);
+
+ static const T C2[] = {
+ static_cast<T>(0.0041335978835978836L),
+ static_cast<T>(-0.0026813271604938272L),
+ static_cast<T>(0.00077160493827160494L),
+ static_cast<T>(0.20093878600823045e-5L),
+ static_cast<T>(-0.00010736653226365161L),
+ static_cast<T>(0.52923448829120125e-4L),
+ static_cast<T>(-0.12760635188618728e-4L),
+ static_cast<T>(0.34235787340961381e-7L),
+ static_cast<T>(0.13721957309062933e-5L),
+ static_cast<T>(-0.6298992138380055e-6L),
+ static_cast<T>(0.14280614206064242e-6L),
+ };
+ workspace[2] = tools::evaluate_polynomial(C2, z);
+
+ static const T C3[] = {
+ static_cast<T>(0.00064943415637860082L),
+ static_cast<T>(0.00022947209362139918L),
+ static_cast<T>(-0.00046918949439525571L),
+ static_cast<T>(0.00026772063206283885L),
+ static_cast<T>(-0.75618016718839764e-4L),
+ static_cast<T>(-0.23965051138672967e-6L),
+ static_cast<T>(0.11082654115347302e-4L),
+ static_cast<T>(-0.56749528269915966e-5L),
+ static_cast<T>(0.14230900732435884e-5L),
+ };
+ workspace[3] = tools::evaluate_polynomial(C3, z);
+
+ static const T C4[] = {
+ static_cast<T>(-0.0008618882909167117L),
+ static_cast<T>(0.00078403922172006663L),
+ static_cast<T>(-0.00029907248030319018L),
+ static_cast<T>(-0.14638452578843418e-5L),
+ static_cast<T>(0.66414982154651222e-4L),
+ static_cast<T>(-0.39683650471794347e-4L),
+ static_cast<T>(0.11375726970678419e-4L),
+ };
+ workspace[4] = tools::evaluate_polynomial(C4, z);
+
+ static const T C5[] = {
+ static_cast<T>(-0.00033679855336635815L),
+ static_cast<T>(-0.69728137583658578e-4L),
+ static_cast<T>(0.00027727532449593921L),
+ static_cast<T>(-0.00019932570516188848L),
+ static_cast<T>(0.67977804779372078e-4L),
+ static_cast<T>(0.1419062920643967e-6L),
+ static_cast<T>(-0.13594048189768693e-4L),
+ static_cast<T>(0.80184702563342015e-5L),
+ static_cast<T>(-0.22914811765080952e-5L),
+ };
+ workspace[5] = tools::evaluate_polynomial(C5, z);
+
+ static const T C6[] = {
+ static_cast<T>(0.00053130793646399222L),
+ static_cast<T>(-0.00059216643735369388L),
+ static_cast<T>(0.00027087820967180448L),
+ static_cast<T>(0.79023532326603279e-6L),
+ static_cast<T>(-0.81539693675619688e-4L),
+ static_cast<T>(0.56116827531062497e-4L),
+ static_cast<T>(-0.18329116582843376e-4L),
+ };
+ workspace[6] = tools::evaluate_polynomial(C6, z);
+
+ static const T C7[] = {
+ static_cast<T>(0.00034436760689237767L),
+ static_cast<T>(0.51717909082605922e-4L),
+ static_cast<T>(-0.00033493161081142236L),
+ static_cast<T>(0.0002812695154763237L),
+ static_cast<T>(-0.00010976582244684731L),
+ };
+ workspace[7] = tools::evaluate_polynomial(C7, z);
+
+ static const T C8[] = {
+ static_cast<T>(-0.00065262391859530942L),
+ static_cast<T>(0.00083949872067208728L),
+ static_cast<T>(-0.00043829709854172101L),
+ };
+ workspace[8] = tools::evaluate_polynomial(C8, z);
+ workspace[9] = static_cast<T>(-0.00059676129019274625L);
+
+ T result = tools::evaluate_polynomial<10, T, T>(workspace, 1/a);
+ result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+ if(x < a)
+ result = -result;
+
+ result += boost::math::erfc(sqrt(y), pol) / 2;
+
+ return result;
+}
+//
+// This one is accurate for 24-bit mantissa's
+// (IEEE float precision, or 10^-8)
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, mpl::int_<24> const *)
+{
+ BOOST_MATH_STD_USING // ADL of std functions
+ T sigma = (x - a) / a;
+ T phi = -boost::math::log1pmx(sigma, pol);
+ T y = a * phi;
+ T z = sqrt(2 * phi);
+ if(x < a)
+ z = -z;
+
+ T workspace[3];
+
+ static const T C0[] = {
+ static_cast<T>(-0.333333333L),
+ static_cast<T>(0.0833333333L),
+ static_cast<T>(-0.0148148148L),
+ static_cast<T>(0.00115740741L),
+ static_cast<T>(0.000352733686L),
+ static_cast<T>(-0.000178755144L),
+ static_cast<T>(0.391926318e-4L),
+ };
+ workspace[0] = tools::evaluate_polynomial(C0, z);
+
+ static const T C1[] = {
+ static_cast<T>(-0.00185185185L),
+ static_cast<T>(-0.00347222222L),
+ static_cast<T>(0.00264550265L),
+ static_cast<T>(-0.000990226337L),
+ static_cast<T>(0.000205761317L),
+ };
+ workspace[1] = tools::evaluate_polynomial(C1, z);
+
+ static const T C2[] = {
+ static_cast<T>(0.00413359788L),
+ static_cast<T>(-0.00268132716L),
+ static_cast<T>(0.000771604938L),
+ };
+ workspace[2] = tools::evaluate_polynomial(C2, z);
+
+ T result = tools::evaluate_polynomial(workspace, 1/a);
+ result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+ if(x < a)
+ result = -result;
+
+ result += boost::math::erfc(sqrt(y), pol) / 2;
+
+ return result;
+}
+//
+// And finally, a version for 113-bit mantissa's
+// (128-bit long doubles, or 10^-34).
+// Note this one has been optimised for a > 200
+// It's use for a < 200 is not recomended, that would
+// require many more terms in the polynomials.
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, mpl::int_<113> const *)
+{
+ BOOST_MATH_STD_USING // ADL of std functions
+ T sigma = (x - a) / a;
+ T phi = -boost::math::log1pmx(sigma, pol);
+ T y = a * phi;
+ T z = sqrt(2 * phi);
+ if(x < a)
+ z = -z;
+
+ T workspace[14];
+
+ static const T C0[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.333333333333333333333333333333333333),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0833333333333333333333333333333333333),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0148148148148148148148148148148148148),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00115740740740740740740740740740740741),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003527336860670194003527336860670194),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000178755144032921810699588477366255144),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.391926317852243778169704095630021556e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.218544851067999216147364295512443661e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.185406221071515996070179883622956325e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.829671134095308600501624213166443227e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.17665952736826079304360054245742403e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.670785354340149858036939710029613572e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.102618097842403080425739573227252951e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.438203601845335318655297462244719123e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.914769958223679023418248817633113681e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.255141939949462497668779537993887013e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.583077213255042506746408945040035798e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.243619480206674162436940696707789943e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.502766928011417558909054985925744366e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.110043920319561347708374174497293411e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.337176326240098537882769884169200185e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.13923887224181620659193661848957998e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.285348938070474432039669099052828299e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.513911183424257261899064580300494205e-15),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.197522882943494428353962401580710912e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.809952115670456133407115668702575255e-15),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.165225312163981618191514820265351162e-15),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.253054300974788842327061090060267385e-17),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.116869397385595765888230876507793475e-16),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.477003704982048475822167804084816597e-17),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.969912605905623712420709685898585354e-18),
+ };
+ workspace[0] = tools::evaluate_polynomial(C0, z);
+
+ static const T C1[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00185185185185185185185185185185185185),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00347222222222222222222222222222222222),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026455026455026455026455026455026455),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000990226337448559670781893004115226337),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000205761316872427983539094650205761317),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.401877572016460905349794238683127572e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.180985503344899778370285914867533523e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.76491609160811100846374214980916921e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.16120900894563446003775221882217767e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.464712780280743434226135033938722401e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.137863344691572095931187533077488877e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.575254560351770496402194531835048307e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.119516285997781473243076536699698169e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.175432417197476476237547551202312502e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.100915437106004126274577504686681675e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.416279299184258263623372347219858628e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.856390702649298063807431562579670208e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.606721510160475861512701762169919581e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.716249896481148539007961017165545733e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.293318664377143711740636683615595403e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.599669636568368872330374527568788909e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.216717865273233141017100472779701734e-15),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.497833997236926164052815522048108548e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.202916288237134247736694804325894226e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.413125571381061004935108332558187111e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.828651623988309644380188591057589316e-18),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.341003088693333279336339355910600992e-15),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.138541953028939715357034547426313703e-15),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.281234665322887466568860332727259483e-16),
+ };
+ workspace[1] = tools::evaluate_polynomial(C1, z);
+
+ static const T C2[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0041335978835978835978835978835978836),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00268132716049382716049382716049382716),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000771604938271604938271604938271604938),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.200938786008230452674897119341563786e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000107366532263651605215391223621676297),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.529234488291201254164217127180090143e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.127606351886187277133779191392360117e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.34235787340961380741902003904747389e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.137219573090629332055943852926020279e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.629899213838005502290672234278391876e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.142806142060642417915846008822771748e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.204770984219908660149195854409200226e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.140925299108675210532930244154315272e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.622897408492202203356394293530327112e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.136704883966171134992724380284402402e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.942835615901467819547711211663208075e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.128722524000893180595479368872770442e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.556459561343633211465414765894951439e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.119759355463669810035898150310311343e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.416897822518386350403836626692480096e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.109406404278845944099299008640802908e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.4662239946390135746326204922464679e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.990510576390690597844122258212382301e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.189318767683735145056885183170630169e-16),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.885922187259112726176031067028740667e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.373782039804640545306560251777191937e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.786883363903515525774088394065960751e-15),
+ };
+ workspace[2] = tools::evaluate_polynomial(C2, z);
+
+ static const T C3[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000649434156378600823045267489711934156),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000229472093621399176954732510288065844),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000469189494395255712128140111679206329),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000267720632062838852962309752433209223),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.756180167188397641072538191879755666e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.239650511386729665193314027333231723e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.110826541153473023614770299726861227e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.567495282699159656749963105701560205e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.14230900732435883914551894470580433e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.278610802915281422405802158211174452e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.16958404091930277289864168795820267e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.809946490538808236335278504852724081e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.191111684859736540606728140872727635e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.239286204398081179686413514022282056e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.206201318154887984369925818486654549e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.946049666185513217375417988510192814e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.215410497757749078380130268468744512e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.138882333681390304603424682490735291e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.218947616819639394064123400466489455e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.979099895117168512568262802255883368e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.217821918801809621153859472011393244e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.62088195734079014258166361684972205e-16),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.212697836327973697696702537114614471e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.934468879151743333127396765626749473e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.204536712267828493249215913063207436e-13),
+ };
+ workspace[3] = tools::evaluate_polynomial(C3, z);
+
+ static const T C4[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000861888290916711698604702719929057378),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00078403922172006662747403488144228885),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000299072480303190179733389609932819809),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.146384525788434181781232535690697556e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.664149821546512218665853782451862013e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.396836504717943466443123507595386882e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.113757269706784190980552042885831759e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.250749722623753280165221942390057007e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.169541495365583060147164356781525752e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.890750753220530968882898422505515924e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.229293483400080487057216364891158518e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.295679413754404904696572852500004588e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.288658297427087836297341274604184504e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.141897394378032193894774303903982717e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.344635804994648970659527720474194356e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.230245171745280671320192735850147087e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.394092330280464052750697640085291799e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.186023389685045019134258533045185639e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.435632300505661804380678327446262424e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.127860010162962312660550463349930726e-14),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.467927502665791946200382739991760062e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.214924647061348285410535341910721086e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.490881561480965216323649688463984082e-12),
+ };
+ workspace[4] = tools::evaluate_polynomial(C4, z);
+
+ static const T C5[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000336798553366358150308767592718210002),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.697281375836585777429398828575783308e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00027727532449593920787336425196507501),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000199325705161888477003360405280844238),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.679778047793720783881640176604435742e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.141906292064396701483392727105575757e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.135940481897686932784583938837504469e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.80184702563342015397192571980419684e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.229148117650809517038048790128781806e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.325247355129845395166230137750005047e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.346528464910852649559195496827579815e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.184471871911713432765322367374920978e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.482409670378941807563762631738989002e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.179894667217435153025754291716644314e-13),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.630619450001352343517516981425944698e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.316241762877456793773762181540969623e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.784092425369742929000839303523267545e-9),
+ };
+ workspace[5] = tools::evaluate_polynomial(C5, z);
+
+ static const T C6[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00053130793646399222316574854297762391),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000592166437353693882864836225604401187),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000270878209671804482771279183488328692),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.790235323266032787212032944390816666e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.815396936756196875092890088464682624e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.561168275310624965003775619041471695e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.183291165828433755673259749374098313e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.307961345060330478256414192546677006e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.346515536880360908673728529745376913e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.202913273960586037269527254582695285e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.578879286314900370889997586203187687e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.233863067382665698933480579231637609e-12),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.88286007463304835250508524317926246e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.474359588804081278032150770595852426e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.125454150207103824457130611214783073e-7),
+ };
+ workspace[6] = tools::evaluate_polynomial(C6, z);
+
+ static const T C7[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000344367606892377671254279625108523655),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.517179090826059219337057843002058823e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000334931610811422363116635090580012327),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000281269515476323702273722110707777978),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000109765822446847310235396824500789005),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.127410090954844853794579954588107623e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.277444515115636441570715073933712622e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.182634888057113326614324442681892723e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.578769494973505239894178121070843383e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.493875893393627039981813418398565502e-9),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.105953670140260427338098566209633945e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.616671437611040747858836254004890765e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.175629733590604619378669693914265388e-6),
+ };
+ workspace[7] = tools::evaluate_polynomial(C7, z);
+
+ static const T C8[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000652623918595309418922034919726622692),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000839498720672087279993357516764983445),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000438297098541721005061087953050560377),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.696909145842055197136911097362072702e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00016644846642067547837384572662326101),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000127835176797692185853344001461664247),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.462995326369130429061361032704489636e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.455790986792270771162749294232219616e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.105952711258051954718238500312872328e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.678334290486516662273073740749269432e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.210754766662588042469972680229376445e-5),
+ };
+ workspace[8] = tools::evaluate_polynomial(C8, z);
+
+ static const T C9[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000596761290192746250124390067179459605),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.720489541602001055908571930225015052e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000678230883766732836161951166000673426),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000640147526026275845100045652582354779),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000277501076343287044992374518205845463),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.181970083804651510461686554030325202e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.847950711706850318239732559632810086e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.610519208250153101764709122740859458e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.210739201834048624082975255893773306e-4),
+ };
+ workspace[9] = tools::evaluate_polynomial(C9, z);
+
+ static const T C10[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00133244544948006563712694993432717968),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00191443849856547752650089885832852254),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0011089369134596637339607446329267522),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.993240412264229896742295262075817566e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000508745012930931989848393025305956774),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00042735056665392884328432271160040444),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000168588537679107988033552814662382059),
+ };
+ workspace[10] = tools::evaluate_polynomial(C10, z);
+
+ static const T C11[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157972766073083495908785631307733022),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000162516262783915816898635123980270998),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00206334210355432762645284467690276817),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00213896861856890981541061922797693947),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00101085593912630031708085801712479376),
+ };
+ workspace[11] = tools::evaluate_polynomial(C11, z);
+
+ static const T C12[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00407251211951401664727281097914544601),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00640336283380806979482363809026579583),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00404101610816766177473974858518094879),
+ };
+ workspace[12] = tools::evaluate_polynomial(C12, z);
+ workspace[13] = -0.0059475779383993002845382844736066323L;
+
+ T result = tools::evaluate_polynomial(workspace, T(1/a));
+ result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+ if(x < a)
+ result = -result;
+
+ result += boost::math::erfc(sqrt(y), pol) / 2;
+
+ return result;
+}
+
+} // namespace detail
+} // namespace math
+} // namespace math
+
+
+#endif // BOOST_MATH_DETAIL_IGAMMA_LARGE
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/lanczos_sse2.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/lanczos_sse2.hpp
new file mode 100644
index 00000000000..edef3a04129
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/lanczos_sse2.hpp
@@ -0,0 +1,204 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2
+#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <emmintrin.h>
+
+#if defined(__GNUC__) || defined(__PGI)
+#define ALIGN16 __attribute__((__aligned__(16)))
+#else
+#define ALIGN16 __declspec(align(16))
+#endif
+
+namespace boost{ namespace math{ namespace lanczos{
+
+template <>
+inline double lanczos13m53::lanczos_sum<double>(const double& x)
+{
+ static const ALIGN16 double coeff[26] = {
+ static_cast<double>(2.506628274631000270164908177133837338626L),
+ static_cast<double>(1u),
+ static_cast<double>(210.8242777515793458725097339207133627117L),
+ static_cast<double>(66u),
+ static_cast<double>(8071.672002365816210638002902272250613822L),
+ static_cast<double>(1925u),
+ static_cast<double>(186056.2653952234950402949897160456992822L),
+ static_cast<double>(32670u),
+ static_cast<double>(2876370.628935372441225409051620849613599L),
+ static_cast<double>(357423u),
+ static_cast<double>(31426415.58540019438061423162831820536287L),
+ static_cast<double>(2637558u),
+ static_cast<double>(248874557.8620541565114603864132294232163L),
+ static_cast<double>(13339535u),
+ static_cast<double>(1439720407.311721673663223072794912393972L),
+ static_cast<double>(45995730u),
+ static_cast<double>(6039542586.35202800506429164430729792107L),
+ static_cast<double>(105258076u),
+ static_cast<double>(17921034426.03720969991975575445893111267L),
+ static_cast<double>(150917976u),
+ static_cast<double>(35711959237.35566804944018545154716670596L),
+ static_cast<double>(120543840u),
+ static_cast<double>(42919803642.64909876895789904700198885093L),
+ static_cast<double>(39916800u),
+ static_cast<double>(23531376880.41075968857200767445163675473L),
+ static_cast<double>(0u)
+ };
+ __m128d vx = _mm_load1_pd(&x);
+ __m128d sum_even = _mm_load_pd(coeff);
+ __m128d sum_odd = _mm_load_pd(coeff+2);
+ __m128d nc_odd, nc_even;
+ __m128d vx2 = _mm_mul_pd(vx, vx);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 4);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 6);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 8);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 10);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 12);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 14);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 16);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 18);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 20);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 22);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 24);
+ sum_odd = _mm_mul_pd(sum_odd, vx);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_even = _mm_add_pd(sum_even, sum_odd);
+
+
+ double ALIGN16 t[2];
+ _mm_store_pd(t, sum_even);
+
+ return t[0] / t[1];
+}
+
+template <>
+inline double lanczos13m53::lanczos_sum_expG_scaled<double>(const double& x)
+{
+ static const ALIGN16 double coeff[26] = {
+ static_cast<double>(0.006061842346248906525783753964555936883222L),
+ static_cast<double>(1u),
+ static_cast<double>(0.5098416655656676188125178644804694509993L),
+ static_cast<double>(66u),
+ static_cast<double>(19.51992788247617482847860966235652136208L),
+ static_cast<double>(1925u),
+ static_cast<double>(449.9445569063168119446858607650988409623L),
+ static_cast<double>(32670u),
+ static_cast<double>(6955.999602515376140356310115515198987526L),
+ static_cast<double>(357423u),
+ static_cast<double>(75999.29304014542649875303443598909137092L),
+ static_cast<double>(2637558u),
+ static_cast<double>(601859.6171681098786670226533699352302507L),
+ static_cast<double>(13339535u),
+ static_cast<double>(3481712.15498064590882071018964774556468L),
+ static_cast<double>(45995730u),
+ static_cast<double>(14605578.08768506808414169982791359218571L),
+ static_cast<double>(105258076u),
+ static_cast<double>(43338889.32467613834773723740590533316085L),
+ static_cast<double>(150917976u),
+ static_cast<double>(86363131.28813859145546927288977868422342L),
+ static_cast<double>(120543840u),
+ static_cast<double>(103794043.1163445451906271053616070238554L),
+ static_cast<double>(39916800u),
+ static_cast<double>(56906521.91347156388090791033559122686859L),
+ static_cast<double>(0u)
+ };
+ __m128d vx = _mm_load1_pd(&x);
+ __m128d sum_even = _mm_load_pd(coeff);
+ __m128d sum_odd = _mm_load_pd(coeff+2);
+ __m128d nc_odd, nc_even;
+ __m128d vx2 = _mm_mul_pd(vx, vx);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 4);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 6);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 8);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 10);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 12);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 14);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 16);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 18);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 20);
+ sum_odd = _mm_mul_pd(sum_odd, vx2);
+ nc_odd = _mm_load_pd(coeff + 22);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+ sum_even = _mm_mul_pd(sum_even, vx2);
+ nc_even = _mm_load_pd(coeff + 24);
+ sum_odd = _mm_mul_pd(sum_odd, vx);
+ sum_even = _mm_add_pd(sum_even, nc_even);
+ sum_even = _mm_add_pd(sum_even, sum_odd);
+
+
+ double ALIGN16 t[2];
+ _mm_store_pd(t, sum_even);
+
+ return t[0] / t[1];
+}
+
+} // namespace lanczos
+} // namespace math
+} // namespace boost
+
+#undef ALIGN16
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/lgamma_small.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/lgamma_small.hpp
new file mode 100644
index 00000000000..e65f8b7e98e
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/lgamma_small.hpp
@@ -0,0 +1,522 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL
+#define BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/big_constant.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+//
+// These need forward declaring to keep GCC happy:
+//
+template <class T, class Policy, class Lanczos>
+T gamma_imp(T z, const Policy& pol, const Lanczos& l);
+template <class T, class Policy>
+T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos& l);
+
+//
+// lgamma for small arguments:
+//
+template <class T, class Policy, class Lanczos>
+T lgamma_small_imp(T z, T zm1, T zm2, const mpl::int_<64>&, const Policy& /* l */, const Lanczos&)
+{
+ // This version uses rational approximations for small
+ // values of z accurate enough for 64-bit mantissas
+ // (80-bit long doubles), works well for 53-bit doubles as well.
+ // Lanczos is only used to select the Lanczos function.
+
+ BOOST_MATH_STD_USING // for ADL of std names
+ T result = 0;
+ if(z < tools::epsilon<T>())
+ {
+ result = -log(z);
+ }
+ else if((zm1 == 0) || (zm2 == 0))
+ {
+ // nothing to do, result is zero....
+ }
+ else if(z > 2)
+ {
+ //
+ // Begin by performing argument reduction until
+ // z is in [2,3):
+ //
+ if(z >= 3)
+ {
+ do
+ {
+ z -= 1;
+ zm2 -= 1;
+ result += log(z);
+ }while(z >= 3);
+ // Update zm2, we need it below:
+ zm2 = z - 2;
+ }
+
+ //
+ // Use the following form:
+ //
+ // lgamma(z) = (z-2)(z+1)(Y + R(z-2))
+ //
+ // where R(z-2) is a rational approximation optimised for
+ // low absolute error - as long as it's absolute error
+ // is small compared to the constant Y - then any rounding
+ // error in it's computation will get wiped out.
+ //
+ // R(z-2) has the following properties:
+ //
+ // At double: Max error found: 4.231e-18
+ // At long double: Max error found: 1.987e-21
+ // Maximum Deviation Found (approximation error): 5.900e-24
+ //
+ static const T P[] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.180355685678449379109e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25126649619989678683e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.494103151567532234274e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.172491608709613993966e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.259453563205438108893e-3)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.541009869215204396339e-3)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.324588649825948492091e-4))
+ };
+ static const T Q[] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.196202987197795200688e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.148019669424231326694e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.541391432071720958364e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.988504251128010129477e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.82130967464889339326e-2)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.224936291922115757597e-3)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.223352763208617092964e-6))
+ };
+
+ static const float Y = 0.158963680267333984375e0f;
+
+ T r = zm2 * (z + 1);
+ T R = tools::evaluate_polynomial(P, zm2);
+ R /= tools::evaluate_polynomial(Q, zm2);
+
+ result += r * Y + r * R;
+ }
+ else
+ {
+ //
+ // If z is less than 1 use recurrance to shift to
+ // z in the interval [1,2]:
+ //
+ if(z < 1)
+ {
+ result += -log(z);
+ zm2 = zm1;
+ zm1 = z;
+ z += 1;
+ }
+ //
+ // Two approximations, on for z in [1,1.5] and
+ // one for z in [1.5,2]:
+ //
+ if(z <= 1.5)
+ {
+ //
+ // Use the following form:
+ //
+ // lgamma(z) = (z-1)(z-2)(Y + R(z-1))
+ //
+ // where R(z-1) is a rational approximation optimised for
+ // low absolute error - as long as it's absolute error
+ // is small compared to the constant Y - then any rounding
+ // error in it's computation will get wiped out.
+ //
+ // R(z-1) has the following properties:
+ //
+ // At double precision: Max error found: 1.230011e-17
+ // At 80-bit long double precision: Max error found: 5.631355e-21
+ // Maximum Deviation Found: 3.139e-021
+ // Expected Error Term: 3.139e-021
+
+ //
+ static const float Y = 0.52815341949462890625f;
+
+ static const T P[] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.490622454069039543534e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.969117530159521214579e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.414983358359495381969e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.406567124211938417342e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.158413586390692192217e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.240149820648571559892e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100346687696279557415e-2))
+ };
+ static const T Q[] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.302349829846463038743e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.348739585360723852576e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.191415588274426679201e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.507137738614363510846e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.577039722690451849648e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.195768102601107189171e-2))
+ };
+
+ T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1);
+ T prefix = zm1 * zm2;
+
+ result += prefix * Y + prefix * r;
+ }
+ else
+ {
+ //
+ // Use the following form:
+ //
+ // lgamma(z) = (2-z)(1-z)(Y + R(2-z))
+ //
+ // where R(2-z) is a rational approximation optimised for
+ // low absolute error - as long as it's absolute error
+ // is small compared to the constant Y - then any rounding
+ // error in it's computation will get wiped out.
+ //
+ // R(2-z) has the following properties:
+ //
+ // At double precision, max error found: 1.797565e-17
+ // At 80-bit long double precision, max error found: 9.306419e-21
+ // Maximum Deviation Found: 2.151e-021
+ // Expected Error Term: 2.150e-021
+ //
+ static const float Y = 0.452017307281494140625f;
+
+ static const T P[] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.292329721830270012337e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.144216267757192309184e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.142440390738631274135e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.542809694055053558157e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.850535976868336437746e-2)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.431171342679297331241e-3))
+ };
+ static const T Q[] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.150169356054485044494e1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.846973248876495016101e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.220095151814995745555e0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25582797155975869989e-1)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100666795539143372762e-2)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.827193521891290553639e-6))
+ };
+ T r = zm2 * zm1;
+ T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2));
+
+ result += r * Y + r * R;
+ }
+ }
+ return result;
+}
+template <class T, class Policy, class Lanczos>
+T lgamma_small_imp(T z, T zm1, T zm2, const mpl::int_<113>&, const Policy& /* l */, const Lanczos&)
+{
+ //
+ // This version uses rational approximations for small
+ // values of z accurate enough for 113-bit mantissas
+ // (128-bit long doubles).
+ //
+ BOOST_MATH_STD_USING // for ADL of std names
+ T result = 0;
+ if(z < tools::epsilon<T>())
+ {
+ result = -log(z);
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ else if((zm1 == 0) || (zm2 == 0))
+ {
+ // nothing to do, result is zero....
+ }
+ else if(z > 2)
+ {
+ //
+ // Begin by performing argument reduction until
+ // z is in [2,3):
+ //
+ if(z >= 3)
+ {
+ do
+ {
+ z -= 1;
+ result += log(z);
+ }while(z >= 3);
+ zm2 = z - 2;
+ }
+ BOOST_MATH_INSTRUMENT_CODE(zm2);
+ BOOST_MATH_INSTRUMENT_CODE(z);
+ BOOST_MATH_INSTRUMENT_CODE(result);
+
+ //
+ // Use the following form:
+ //
+ // lgamma(z) = (z-2)(z+1)(Y + R(z-2))
+ //
+ // where R(z-2) is a rational approximation optimised for
+ // low absolute error - as long as it's absolute error
+ // is small compared to the constant Y - then any rounding
+ // error in it's computation will get wiped out.
+ //
+ // Maximum Deviation Found (approximation error) 3.73e-37
+
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.018035568567844937910504030027467476655),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.013841458273109517271750705401202404195),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.062031842739486600078866923383017722399),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.052518418329052161202007865149435256093),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.01881718142472784129191838493267755758),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0025104830367021839316463675028524702846),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00021043176101831873281848891452678568311),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00010249622350908722793327719494037981166),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.11381479670982006841716879074288176994e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.49999811718089980992888533630523892389e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.70529798686542184668416911331718963364e-8)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.5877485070422317542808137697939233685),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.8797959228352591788629602533153837126),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.8030885955284082026405495275461180977),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.69774331297747390169238306148355428436),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.17261566063277623942044077039756583802),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.02729301254544230229429621192443000121),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026776425891195270663133581960016620433),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00015244249160486584591370355730402168106),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.43997034032479866020546814475414346627e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.46295080708455613044541885534408170934e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.93326638207459533682980757982834180952e-11),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.42316456553164995177177407325292867513e-13)
+ };
+
+ T R = tools::evaluate_polynomial(P, zm2);
+ R /= tools::evaluate_polynomial(Q, zm2);
+
+ static const float Y = 0.158963680267333984375F;
+
+ T r = zm2 * (z + 1);
+
+ result += r * Y + r * R;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ else
+ {
+ //
+ // If z is less than 1 use recurrance to shift to
+ // z in the interval [1,2]:
+ //
+ if(z < 1)
+ {
+ result += -log(z);
+ zm2 = zm1;
+ zm1 = z;
+ z += 1;
+ }
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ BOOST_MATH_INSTRUMENT_CODE(z);
+ BOOST_MATH_INSTRUMENT_CODE(zm2);
+ //
+ // Three approximations, on for z in [1,1.35], [1.35,1.625] and [1.625,1]
+ //
+ if(z <= 1.35)
+ {
+ //
+ // Use the following form:
+ //
+ // lgamma(z) = (z-1)(z-2)(Y + R(z-1))
+ //
+ // where R(z-1) is a rational approximation optimised for
+ // low absolute error - as long as it's absolute error
+ // is small compared to the constant Y - then any rounding
+ // error in it's computation will get wiped out.
+ //
+ // R(z-1) has the following properties:
+ //
+ // Maximum Deviation Found (approximation error) 1.659e-36
+ // Expected Error Term (theoretical error) 1.343e-36
+ // Max error found at 128-bit long double precision 1.007e-35
+ //
+ static const float Y = 0.54076099395751953125f;
+
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.036454670944013329356512090082402429697),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.066235835556476033710068679907798799959),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.67492399795577182387312206593595565371),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -1.4345555263962411429855341651960000166),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -1.4894319559821365820516771951249649563),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.87210277668067964629483299712322411566),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.29602090537771744401524080430529369136),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0561832587517836908929331992218879676),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0053236785487328044334381502530383140443),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00018629360291358130461736386077971890789),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.10164985672213178500790406939467614498e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.13680157145361387405588201461036338274e-8)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 4.9106336261005990534095838574132225599),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 10.258804800866438510889341082793078432),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 11.88588976846826108836629960537466889),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 8.3455000546999704314454891036700998428),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 3.6428823682421746343233362007194282703),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.97465989807254572142266753052776132252),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.15121052897097822172763084966793352524),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.012017363555383555123769849654484594893),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003583032812720649835431669893011257277)
+ };
+
+ T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1);
+ T prefix = zm1 * zm2;
+
+ result += prefix * Y + prefix * r;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ else if(z <= 1.625)
+ {
+ //
+ // Use the following form:
+ //
+ // lgamma(z) = (2-z)(1-z)(Y + R(2-z))
+ //
+ // where R(2-z) is a rational approximation optimised for
+ // low absolute error - as long as it's absolute error
+ // is small compared to the constant Y - then any rounding
+ // error in it's computation will get wiped out.
+ //
+ // R(2-z) has the following properties:
+ //
+ // Max error found at 128-bit long double precision 9.634e-36
+ // Maximum Deviation Found (approximation error) 1.538e-37
+ // Expected Error Term (theoretical error) 2.350e-38
+ //
+ static const float Y = 0.483787059783935546875f;
+
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.017977422421608624353488126610933005432),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.18484528905298309555089509029244135703),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.40401251514859546989565001431430884082),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.40277179799147356461954182877921388182),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.21993421441282936476709677700477598816),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.069595742223850248095697771331107571011),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.012681481427699686635516772923547347328),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0012489322866834830413292771335113136034),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.57058739515423112045108068834668269608e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.8207548771933585614380644961342925976e-6)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -2.9629552288944259229543137757200262073),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 3.7118380799042118987185957298964772755),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -2.5569815272165399297600586376727357187),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0546764918220835097855665680632153367),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.26574021300894401276478730940980810831),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.03996289731752081380552901986471233462),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033398680924544836817826046380586480873),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00013288854760548251757651556792598235735),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.17194794958274081373243161848194745111e-5)
+ };
+ T r = zm2 * zm1;
+ T R = tools::evaluate_polynomial(P, T(0.625 - zm1)) / tools::evaluate_polynomial(Q, T(0.625 - zm1));
+
+ result += r * Y + r * R;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ else
+ {
+ //
+ // Same form as above.
+ //
+ // Max error found (at 128-bit long double precision) 1.831e-35
+ // Maximum Deviation Found (approximation error) 8.588e-36
+ // Expected Error Term (theoretical error) 1.458e-36
+ //
+ static const float Y = 0.443811893463134765625f;
+
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.021027558364667626231512090082402429494),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.15128811104498736604523586803722368377),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.26249631480066246699388544451126410278),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.21148748610533489823742352180628489742),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.093964130697489071999873506148104370633),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.024292059227009051652542804957550866827),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0036284453226534839926304745756906117066),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0002939230129315195346843036254392485984),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.11088589183158123733132268042570710338e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.13240510580220763969511741896361984162e-6)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -2.4240003754444040525462170802796471996),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.4868383476933178722203278602342786002),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -1.4047068395206343375520721509193698547),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.47583809087867443858344765659065773369),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.09865724264554556400463655444270700132),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.012238223514176587501074150988445109735),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00084625068418239194670614419707491797097),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.2796574430456237061420839429225710602e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.30202973883316730694433702165188835331e-6)
+ };
+ // (2 - x) * (1 - x) * (c + R(2 - x))
+ T r = zm2 * zm1;
+ T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2));
+
+ result += r * Y + r * R;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ }
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ return result;
+}
+template <class T, class Policy, class Lanczos>
+T lgamma_small_imp(T z, T zm1, T zm2, const mpl::int_<0>&, const Policy& pol, const Lanczos&)
+{
+ //
+ // No rational approximations are available because either
+ // T has no numeric_limits support (so we can't tell how
+ // many digits it has), or T has more digits than we know
+ // what to do with.... we do have a Lanczos approximation
+ // though, and that can be used to keep errors under control.
+ //
+ BOOST_MATH_STD_USING // for ADL of std names
+ T result = 0;
+ if(z < tools::epsilon<T>())
+ {
+ result = -log(z);
+ }
+ else if(z < 0.5)
+ {
+ // taking the log of tgamma reduces the error, no danger of overflow here:
+ result = log(gamma_imp(z, pol, Lanczos()));
+ }
+ else if(z >= 3)
+ {
+ // taking the log of tgamma reduces the error, no danger of overflow here:
+ result = log(gamma_imp(z, pol, Lanczos()));
+ }
+ else if(z >= 1.5)
+ {
+ // special case near 2:
+ T dz = zm2;
+ result = dz * log((z + Lanczos::g() - T(0.5)) / boost::math::constants::e<T>());
+ result += boost::math::log1p(dz / (Lanczos::g() + T(1.5)), pol) * T(1.5);
+ result += boost::math::log1p(Lanczos::lanczos_sum_near_2(dz), pol);
+ }
+ else
+ {
+ // special case near 1:
+ T dz = zm1;
+ result = dz * log((z + Lanczos::g() - T(0.5)) / boost::math::constants::e<T>());
+ result += boost::math::log1p(dz / (Lanczos::g() + T(0.5)), pol) / 2;
+ result += boost::math::log1p(Lanczos::lanczos_sum_near_1(dz), pol);
+ }
+ return result;
+}
+
+}}} // namespaces
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/round_fwd.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/round_fwd.hpp
new file mode 100644
index 00000000000..8c45a7d75a4
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/round_fwd.hpp
@@ -0,0 +1,93 @@
+// Copyright John Maddock 2008.
+
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_ROUND_FWD_HPP
+#define BOOST_MATH_SPECIAL_ROUND_FWD_HPP
+
+#include <boost/config.hpp>
+#include <boost/math/tools/promotion.hpp>
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+namespace boost
+{
+ namespace math
+ {
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol);
+ template <class T>
+ typename tools::promote_args<T>::type trunc(const T& v);
+ template <class T, class Policy>
+ int itrunc(const T& v, const Policy& pol);
+ template <class T>
+ int itrunc(const T& v);
+ template <class T, class Policy>
+ long ltrunc(const T& v, const Policy& pol);
+ template <class T>
+ long ltrunc(const T& v);
+#ifdef BOOST_HAS_LONG_LONG
+ template <class T, class Policy>
+ boost::long_long_type lltrunc(const T& v, const Policy& pol);
+ template <class T>
+ boost::long_long_type lltrunc(const T& v);
+#endif
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type round(const T& v, const Policy& pol);
+ template <class T>
+ typename tools::promote_args<T>::type round(const T& v);
+ template <class T, class Policy>
+ int iround(const T& v, const Policy& pol);
+ template <class T>
+ int iround(const T& v);
+ template <class T, class Policy>
+ long lround(const T& v, const Policy& pol);
+ template <class T>
+ long lround(const T& v);
+#ifdef BOOST_HAS_LONG_LONG
+ template <class T, class Policy>
+ boost::long_long_type llround(const T& v, const Policy& pol);
+ template <class T>
+ boost::long_long_type llround(const T& v);
+#endif
+ template <class T, class Policy>
+ T modf(const T& v, T* ipart, const Policy& pol);
+ template <class T>
+ T modf(const T& v, T* ipart);
+ template <class T, class Policy>
+ T modf(const T& v, int* ipart, const Policy& pol);
+ template <class T>
+ T modf(const T& v, int* ipart);
+ template <class T, class Policy>
+ T modf(const T& v, long* ipart, const Policy& pol);
+ template <class T>
+ T modf(const T& v, long* ipart);
+#ifdef BOOST_HAS_LONG_LONG
+ template <class T, class Policy>
+ T modf(const T& v, boost::long_long_type* ipart, const Policy& pol);
+ template <class T>
+ T modf(const T& v, boost::long_long_type* ipart);
+#endif
+
+ }
+}
+
+#undef BOOST_MATH_STD_USING
+#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE\
+ using boost::math::round;\
+ using boost::math::iround;\
+ using boost::math::lround;\
+ using boost::math::trunc;\
+ using boost::math::itrunc;\
+ using boost::math::ltrunc;\
+ using boost::math::modf;
+
+
+#endif // BOOST_MATH_SPECIAL_ROUND_FWD_HPP
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/t_distribution_inv.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/t_distribution_inv.hpp
new file mode 100644
index 00000000000..72f6f0c6468
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/t_distribution_inv.hpp
@@ -0,0 +1,549 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2007
+// 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)
+
+#ifndef BOOST_MATH_SF_DETAIL_INV_T_HPP
+#define BOOST_MATH_SF_DETAIL_INV_T_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/cbrt.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+//
+// The main method used is due to Hill:
+//
+// G. W. Hill, Algorithm 396, Student's t-Quantiles,
+// Communications of the ACM, 13(10): 619-620, Oct., 1970.
+//
+template <class T, class Policy>
+T inverse_students_t_hill(T ndf, T u, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ BOOST_ASSERT(u <= 0.5);
+
+ T a, b, c, d, q, x, y;
+
+ if (ndf > 1e20f)
+ return -boost::math::erfc_inv(2 * u, pol) * constants::root_two<T>();
+
+ a = 1 / (ndf - 0.5f);
+ b = 48 / (a * a);
+ c = ((20700 * a / b - 98) * a - 16) * a + 96.36f;
+ d = ((94.5f / (b + c) - 3) / b + 1) * sqrt(a * constants::pi<T>() / 2) * ndf;
+ y = pow(d * 2 * u, 2 / ndf);
+
+ if (y > (0.05f + a))
+ {
+ //
+ // Asymptotic inverse expansion about normal:
+ //
+ x = -boost::math::erfc_inv(2 * u, pol) * constants::root_two<T>();
+ y = x * x;
+
+ if (ndf < 5)
+ c += 0.3f * (ndf - 4.5f) * (x + 0.6f);
+ c += (((0.05f * d * x - 5) * x - 7) * x - 2) * x + b;
+ y = (((((0.4f * y + 6.3f) * y + 36) * y + 94.5f) / c - y - 3) / b + 1) * x;
+ y = boost::math::expm1(a * y * y, pol);
+ }
+ else
+ {
+ y = ((1 / (((ndf + 6) / (ndf * y) - 0.089f * d - 0.822f)
+ * (ndf + 2) * 3) + 0.5 / (ndf + 4)) * y - 1)
+ * (ndf + 1) / (ndf + 2) + 1 / y;
+ }
+ q = sqrt(ndf * y);
+
+ return -q;
+}
+//
+// Tail and body series are due to Shaw:
+//
+// www.mth.kcl.ac.uk/~shaww/web_page/papers/Tdistribution06.pdf
+//
+// Shaw, W.T., 2006, "Sampling Student's T distribution - use of
+// the inverse cumulative distribution function."
+// Journal of Computational Finance, Vol 9 Issue 4, pp 37-73, Summer 2006
+//
+template <class T, class Policy>
+T inverse_students_t_tail_series(T df, T v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ // Tail series expansion, see section 6 of Shaw's paper.
+ // w is calculated using Eq 60:
+ T w = boost::math::tgamma_delta_ratio(df / 2, constants::half<T>(), pol)
+ * sqrt(df * constants::pi<T>()) * v;
+ // define some variables:
+ T np2 = df + 2;
+ T np4 = df + 4;
+ T np6 = df + 6;
+ //
+ // Calculate the coefficients d(k), these depend only on the
+ // number of degrees of freedom df, so at least in theory
+ // we could tabulate these for fixed df, see p15 of Shaw:
+ //
+ T d[7] = { 1, };
+ d[1] = -(df + 1) / (2 * np2);
+ np2 *= (df + 2);
+ d[2] = -df * (df + 1) * (df + 3) / (8 * np2 * np4);
+ np2 *= df + 2;
+ d[3] = -df * (df + 1) * (df + 5) * (((3 * df) + 7) * df -2) / (48 * np2 * np4 * np6);
+ np2 *= (df + 2);
+ np4 *= (df + 4);
+ d[4] = -df * (df + 1) * (df + 7) *
+ ( (((((15 * df) + 154) * df + 465) * df + 286) * df - 336) * df + 64 )
+ / (384 * np2 * np4 * np6 * (df + 8));
+ np2 *= (df + 2);
+ d[5] = -df * (df + 1) * (df + 3) * (df + 9)
+ * (((((((35 * df + 452) * df + 1573) * df + 600) * df - 2020) * df) + 928) * df -128)
+ / (1280 * np2 * np4 * np6 * (df + 8) * (df + 10));
+ np2 *= (df + 2);
+ np4 *= (df + 4);
+ np6 *= (df + 6);
+ d[6] = -df * (df + 1) * (df + 11)
+ * ((((((((((((945 * df) + 31506) * df + 425858) * df + 2980236) * df + 11266745) * df + 20675018) * df + 7747124) * df - 22574632) * df - 8565600) * df + 18108416) * df - 7099392) * df + 884736)
+ / (46080 * np2 * np4 * np6 * (df + 8) * (df + 10) * (df +12));
+ //
+ // Now bring everthing together to provide the result,
+ // this is Eq 62 of Shaw:
+ //
+ T rn = sqrt(df);
+ T div = pow(rn * w, 1 / df);
+ T power = div * div;
+ T result = tools::evaluate_polynomial<7, T, T>(d, power);
+ result *= rn;
+ result /= div;
+ return -result;
+}
+
+template <class T, class Policy>
+T inverse_students_t_body_series(T df, T u, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ //
+ // Body series for small N:
+ //
+ // Start with Eq 56 of Shaw:
+ //
+ T v = boost::math::tgamma_delta_ratio(df / 2, constants::half<T>(), pol)
+ * sqrt(df * constants::pi<T>()) * (u - constants::half<T>());
+ //
+ // Workspace for the polynomial coefficients:
+ //
+ T c[11] = { 0, 1, };
+ //
+ // Figure out what the coefficients are, note these depend
+ // only on the degrees of freedom (Eq 57 of Shaw):
+ //
+ T in = 1 / df;
+ c[2] = 0.16666666666666666667 + 0.16666666666666666667 * in;
+ c[3] = (0.0083333333333333333333 * in
+ + 0.066666666666666666667) * in
+ + 0.058333333333333333333;
+ c[4] = ((0.00019841269841269841270 * in
+ + 0.0017857142857142857143) * in
+ + 0.026785714285714285714) * in
+ + 0.025198412698412698413;
+ c[5] = (((2.7557319223985890653e-6 * in
+ + 0.00037477954144620811287) * in
+ - 0.0011078042328042328042) * in
+ + 0.010559964726631393298) * in
+ + 0.012039792768959435626;
+ c[6] = ((((2.5052108385441718775e-8 * in
+ - 0.000062705427288760622094) * in
+ + 0.00059458674042007375341) * in
+ - 0.0016095979637646304313) * in
+ + 0.0061039211560044893378) * in
+ + 0.0038370059724226390893;
+ c[7] = (((((1.6059043836821614599e-10 * in
+ + 0.000015401265401265401265) * in
+ - 0.00016376804137220803887) * in
+ + 0.00069084207973096861986) * in
+ - 0.0012579159844784844785) * in
+ + 0.0010898206731540064873) * in
+ + 0.0032177478835464946576;
+ c[8] = ((((((7.6471637318198164759e-13 * in
+ - 3.9851014346715404916e-6) * in
+ + 0.000049255746366361445727) * in
+ - 0.00024947258047043099953) * in
+ + 0.00064513046951456342991) * in
+ - 0.00076245135440323932387) * in
+ + 0.000033530976880017885309) * in
+ + 0.0017438262298340009980;
+ c[9] = (((((((2.8114572543455207632e-15 * in
+ + 1.0914179173496789432e-6) * in
+ - 0.000015303004486655377567) * in
+ + 0.000090867107935219902229) * in
+ - 0.00029133414466938067350) * in
+ + 0.00051406605788341121363) * in
+ - 0.00036307660358786885787) * in
+ - 0.00031101086326318780412) * in
+ + 0.00096472747321388644237;
+ c[10] = ((((((((8.2206352466243297170e-18 * in
+ - 3.1239569599829868045e-7) * in
+ + 4.8903045291975346210e-6) * in
+ - 0.000033202652391372058698) * in
+ + 0.00012645437628698076975) * in
+ - 0.00028690924218514613987) * in
+ + 0.00035764655430568632777) * in
+ - 0.00010230378073700412687) * in
+ - 0.00036942667800009661203) * in
+ + 0.00054229262813129686486;
+ //
+ // The result is then a polynomial in v (see Eq 56 of Shaw):
+ //
+ return tools::evaluate_odd_polynomial<11, T, T>(c, v);
+}
+
+template <class T, class Policy>
+T inverse_students_t(T df, T u, T v, const Policy& pol, bool* pexact = 0)
+{
+ //
+ // df = number of degrees of freedom.
+ // u = probablity.
+ // v = 1 - u.
+ // l = lanczos type to use.
+ //
+ BOOST_MATH_STD_USING
+ bool invert = false;
+ T result = 0;
+ if(pexact)
+ *pexact = false;
+ if(u > v)
+ {
+ // function is symmetric, invert it:
+ std::swap(u, v);
+ invert = true;
+ }
+ if((floor(df) == df) && (df < 20))
+ {
+ //
+ // we have integer degrees of freedom, try for the special
+ // cases first:
+ //
+ T tolerance = ldexp(1.0f, (2 * policies::digits<T, Policy>()) / 3);
+
+ switch(itrunc(df, Policy()))
+ {
+ case 1:
+ {
+ //
+ // df = 1 is the same as the Cauchy distribution, see
+ // Shaw Eq 35:
+ //
+ if(u == 0.5)
+ result = 0;
+ else
+ result = -cos(constants::pi<T>() * u) / sin(constants::pi<T>() * u);
+ if(pexact)
+ *pexact = true;
+ break;
+ }
+ case 2:
+ {
+ //
+ // df = 2 has an exact result, see Shaw Eq 36:
+ //
+ result =(2 * u - 1) / sqrt(2 * u * v);
+ if(pexact)
+ *pexact = true;
+ break;
+ }
+ case 4:
+ {
+ //
+ // df = 4 has an exact result, see Shaw Eq 38 & 39:
+ //
+ T alpha = 4 * u * v;
+ T root_alpha = sqrt(alpha);
+ T r = 4 * cos(acos(root_alpha) / 3) / root_alpha;
+ T x = sqrt(r - 4);
+ result = u - 0.5f < 0 ? (T)-x : x;
+ if(pexact)
+ *pexact = true;
+ break;
+ }
+ case 6:
+ {
+ //
+ // We get numeric overflow in this area:
+ //
+ if(u < 1e-150)
+ return (invert ? -1 : 1) * inverse_students_t_hill(df, u, pol);
+ //
+ // Newton-Raphson iteration of a polynomial case,
+ // choice of seed value is taken from Shaw's online
+ // supplement:
+ //
+ T a = 4 * (u - u * u);//1 - 4 * (u - 0.5f) * (u - 0.5f);
+ T b = boost::math::cbrt(a);
+ static const T c = 0.85498797333834849467655443627193;
+ T p = 6 * (1 + c * (1 / b - 1));
+ T p0;
+ do{
+ T p2 = p * p;
+ T p4 = p2 * p2;
+ T p5 = p * p4;
+ p0 = p;
+ // next term is given by Eq 41:
+ p = 2 * (8 * a * p5 - 270 * p2 + 2187) / (5 * (4 * a * p4 - 216 * p - 243));
+ }while(fabs((p - p0) / p) > tolerance);
+ //
+ // Use Eq 45 to extract the result:
+ //
+ p = sqrt(p - df);
+ result = (u - 0.5f) < 0 ? (T)-p : p;
+ break;
+ }
+#if 0
+ //
+ // These are Shaw's "exact" but iterative solutions
+ // for even df, the numerical accuracy of these is
+ // rather less than Hill's method, so these are disabled
+ // for now, which is a shame because they are reasonably
+ // quick to evaluate...
+ //
+ case 8:
+ {
+ //
+ // Newton-Raphson iteration of a polynomial case,
+ // choice of seed value is taken from Shaw's online
+ // supplement:
+ //
+ static const T c8 = 0.85994765706259820318168359251872L;
+ T a = 4 * (u - u * u); //1 - 4 * (u - 0.5f) * (u - 0.5f);
+ T b = pow(a, T(1) / 4);
+ T p = 8 * (1 + c8 * (1 / b - 1));
+ T p0 = p;
+ do{
+ T p5 = p * p;
+ p5 *= p5 * p;
+ p0 = p;
+ // Next term is given by Eq 42:
+ p = 2 * (3 * p + (640 * (160 + p * (24 + p * (p + 4)))) / (-5120 + p * (-2048 - 960 * p + a * p5))) / 7;
+ }while(fabs((p - p0) / p) > tolerance);
+ //
+ // Use Eq 45 to extract the result:
+ //
+ p = sqrt(p - df);
+ result = (u - 0.5f) < 0 ? -p : p;
+ break;
+ }
+ case 10:
+ {
+ //
+ // Newton-Raphson iteration of a polynomial case,
+ // choice of seed value is taken from Shaw's online
+ // supplement:
+ //
+ static const T c10 = 0.86781292867813396759105692122285L;
+ T a = 4 * (u - u * u); //1 - 4 * (u - 0.5f) * (u - 0.5f);
+ T b = pow(a, T(1) / 5);
+ T p = 10 * (1 + c10 * (1 / b - 1));
+ T p0;
+ do{
+ T p6 = p * p;
+ p6 *= p6 * p6;
+ p0 = p;
+ // Next term given by Eq 43:
+ p = (8 * p) / 9 + (218750 * (21875 + 4 * p * (625 + p * (75 + 2 * p * (5 + p))))) /
+ (9 * (-68359375 + 8 * p * (-2343750 + p * (-546875 - 175000 * p + 8 * a * p6))));
+ }while(fabs((p - p0) / p) > tolerance);
+ //
+ // Use Eq 45 to extract the result:
+ //
+ p = sqrt(p - df);
+ result = (u - 0.5f) < 0 ? -p : p;
+ break;
+ }
+#endif
+ default:
+ goto calculate_real;
+ }
+ }
+ else
+ {
+calculate_real:
+ if(df > 0x10000000)
+ {
+ result = -boost::math::erfc_inv(2 * u, pol) * constants::root_two<T>();
+ if((pexact) && (df >= 1e20))
+ *pexact = true;
+ }
+ else if(df < 3)
+ {
+ //
+ // Use a roughly linear scheme to choose between Shaw's
+ // tail series and body series:
+ //
+ T crossover = 0.2742f - df * 0.0242143f;
+ if(u > crossover)
+ {
+ result = boost::math::detail::inverse_students_t_body_series(df, u, pol);
+ }
+ else
+ {
+ result = boost::math::detail::inverse_students_t_tail_series(df, u, pol);
+ }
+ }
+ else
+ {
+ //
+ // Use Hill's method except in the exteme tails
+ // where we use Shaw's tail series.
+ // The crossover point is roughly exponential in -df:
+ //
+ T crossover = ldexp(1.0f, iround(T(df / -0.654f), typename policies::normalise<Policy, policies::rounding_error<policies::ignore_error> >::type()));
+ if(u > crossover)
+ {
+ result = boost::math::detail::inverse_students_t_hill(df, u, pol);
+ }
+ else
+ {
+ result = boost::math::detail::inverse_students_t_tail_series(df, u, pol);
+ }
+ }
+ }
+ return invert ? (T)-result : result;
+}
+
+template <class T, class Policy>
+inline T find_ibeta_inv_from_t_dist(T a, T p, T /*q*/, T* py, const Policy& pol)
+{
+ T u = p / 2;
+ T v = 1 - u;
+ T df = a * 2;
+ T t = boost::math::detail::inverse_students_t(df, u, v, pol);
+ *py = t * t / (df + t * t);
+ return df / (df + t * t);
+}
+
+template <class T, class Policy>
+inline T fast_students_t_quantile_imp(T df, T p, const Policy& pol, const mpl::false_*)
+{
+ BOOST_MATH_STD_USING
+ //
+ // Need to use inverse incomplete beta to get
+ // required precision so not so fast:
+ //
+ T probability = (p > 0.5) ? 1 - p : p;
+ T t, x, y(0);
+ x = ibeta_inv(df / 2, T(0.5), 2 * probability, &y, pol);
+ if(df * y > tools::max_value<T>() * x)
+ t = policies::raise_overflow_error<T>("boost::math::students_t_quantile<%1%>(%1%,%1%)", 0, pol);
+ else
+ t = sqrt(df * y / x);
+ //
+ // Figure out sign based on the size of p:
+ //
+ if(p < 0.5)
+ t = -t;
+ return t;
+}
+
+template <class T, class Policy>
+T fast_students_t_quantile_imp(T df, T p, const Policy& pol, const mpl::true_*)
+{
+ BOOST_MATH_STD_USING
+ bool invert = false;
+ if((df < 2) && (floor(df) != df))
+ return boost::math::detail::fast_students_t_quantile_imp(df, p, pol, static_cast<mpl::false_*>(0));
+ if(p > 0.5)
+ {
+ p = 1 - p;
+ invert = true;
+ }
+ //
+ // Get an estimate of the result:
+ //
+ bool exact;
+ T t = inverse_students_t(df, p, T(1-p), pol, &exact);
+ if((t == 0) || exact)
+ return invert ? -t : t; // can't do better!
+ //
+ // Change variables to inverse incomplete beta:
+ //
+ T t2 = t * t;
+ T xb = df / (df + t2);
+ T y = t2 / (df + t2);
+ T a = df / 2;
+ //
+ // t can be so large that x underflows,
+ // just return our estimate in that case:
+ //
+ if(xb == 0)
+ return t;
+ //
+ // Get incomplete beta and it's derivative:
+ //
+ T f1;
+ T f0 = xb < y ? ibeta_imp(a, constants::half<T>(), xb, pol, false, true, &f1)
+ : ibeta_imp(constants::half<T>(), a, y, pol, true, true, &f1);
+
+ // Get cdf from incomplete beta result:
+ T p0 = f0 / 2 - p;
+ // Get pdf from derivative:
+ T p1 = f1 * sqrt(y * xb * xb * xb / df);
+ //
+ // Second derivative divided by p1:
+ //
+ // yacas gives:
+ //
+ // In> PrettyForm(Simplify(D(t) (1 + t^2/v) ^ (-(v+1)/2)))
+ //
+ // | | v + 1 | |
+ // | -| ----- + 1 | |
+ // | | 2 | |
+ // -| | 2 | |
+ // | | t | |
+ // | | -- + 1 | |
+ // | ( v + 1 ) * | v | * t |
+ // ---------------------------------------------
+ // v
+ //
+ // Which after some manipulation is:
+ //
+ // -p1 * t * (df + 1) / (t^2 + df)
+ //
+ T p2 = t * (df + 1) / (t * t + df);
+ // Halley step:
+ t = fabs(t);
+ t += p0 / (p1 + p0 * p2 / 2);
+ return !invert ? -t : t;
+}
+
+template <class T, class Policy>
+inline T fast_students_t_quantile(T df, T p, const Policy& pol)
+{
+ typedef typename policies::evaluation<T, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ typedef mpl::bool_<
+ (std::numeric_limits<T>::digits <= 53)
+ &&
+ (std::numeric_limits<T>::is_specialized)
+ &&
+ (std::numeric_limits<T>::radix == 2)
+ > tag_type;
+ return policies::checked_narrowing_cast<T, forwarding_policy>(fast_students_t_quantile_imp(static_cast<value_type>(df), static_cast<value_type>(p), pol, static_cast<tag_type*>(0)), "boost::math::students_t_quantile<%1%>(%1%,%1%,%1%)");
+}
+
+}}} // namespaces
+
+#endif // BOOST_MATH_SF_DETAIL_INV_T_HPP
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_bernoulli.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_bernoulli.hpp
new file mode 100644
index 00000000000..03c376678db
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_bernoulli.hpp
@@ -0,0 +1,700 @@
+
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2013 Nikhar Agrawal
+// Copyright 2013 Christopher Kormanyos
+// Copyright 2013 John Maddock
+// Copyright 2013 Paul Bristow
+// Distributed under 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)
+
+#ifndef BOOST_MATH_UNCHECKED_BERNOULLI_HPP
+#define BOOST_MATH_UNCHECKED_BERNOULLI_HPP
+
+#include <limits>
+#include <cmath>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+namespace boost { namespace math {
+
+namespace detail {
+
+template <unsigned N>
+struct max_bernoulli_index
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 17);
+};
+
+template <>
+struct max_bernoulli_index<1>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 32);
+};
+
+template <>
+struct max_bernoulli_index<2>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 129);
+};
+
+template <>
+struct max_bernoulli_index<3>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 1156);
+};
+
+template <>
+struct max_bernoulli_index<4>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 11);
+};
+
+template <class T>
+struct bernoulli_imp_variant
+{
+ static const unsigned value =
+ (std::numeric_limits<T>::max_exponent == 128)
+ && (std::numeric_limits<T>::radix == 2)
+ && (std::numeric_limits<T>::digits <= std::numeric_limits<float>::digits)
+ && (boost::is_convertible<float, T>::value) ? 1 :
+ (
+ (std::numeric_limits<T>::max_exponent == 1024)
+ && (std::numeric_limits<T>::radix == 2)
+ && (std::numeric_limits<T>::digits <= std::numeric_limits<double>::digits)
+ && (boost::is_convertible<double, T>::value) ? 2 :
+ (
+ (std::numeric_limits<T>::max_exponent == 16384)
+ && (std::numeric_limits<T>::radix == 2)
+ && (std::numeric_limits<T>::digits <= std::numeric_limits<long double>::digits)
+ && (boost::is_convertible<long double, T>::value) ? 3 : (!is_convertible<boost::int64_t, T>::value ? 4 : 0)
+ )
+ );
+};
+
+} // namespace detail
+
+template <class T>
+struct max_bernoulli_b2n : public detail::max_bernoulli_index<detail::bernoulli_imp_variant<T>::value>{};
+
+namespace detail{
+
+template <class T>
+inline T unchecked_bernoulli_imp(std::size_t n, const mpl::int_<0>& )
+{
+ static const boost::array<boost::int64_t, 1 + max_bernoulli_b2n<T>::value> numerators =
+ {{
+ boost::int64_t( +1LL),
+ boost::int64_t( +1LL),
+ boost::int64_t( -1LL),
+ boost::int64_t( +1LL),
+ boost::int64_t( -1LL),
+ boost::int64_t( +5LL),
+ boost::int64_t( -691LL),
+ boost::int64_t( +7LL),
+ boost::int64_t( -3617LL),
+ boost::int64_t( +43867LL),
+ boost::int64_t( -174611LL),
+ boost::int64_t( +854513LL),
+ boost::int64_t( -236364091LL),
+ boost::int64_t( +8553103LL),
+ boost::int64_t( -23749461029LL),
+ boost::int64_t(+8615841276005LL),
+ boost::int64_t(-7709321041217LL),
+ boost::int64_t(+2577687858367LL)
+ }};
+
+ static const boost::array<boost::int64_t, 1 + max_bernoulli_b2n<T>::value> denominators =
+ {{
+ boost::int64_t( 1LL),
+ boost::int64_t( 6LL),
+ boost::int64_t( 30LL),
+ boost::int64_t( 42LL),
+ boost::int64_t( 30LL),
+ boost::int64_t( 66LL),
+ boost::int64_t( 2730LL),
+ boost::int64_t( 6LL),
+ boost::int64_t( 510LL),
+ boost::int64_t( 798LL),
+ boost::int64_t( 330LL),
+ boost::int64_t( 138LL),
+ boost::int64_t( 2730LL),
+ boost::int64_t( 6LL),
+ boost::int64_t( 870LL),
+ boost::int64_t( 14322LL),
+ boost::int64_t( 510LL),
+ boost::int64_t( 6LL)
+ }};
+ return T(numerators[n]) / denominators[n];
+}
+
+template <class T>
+inline T unchecked_bernoulli_imp(std::size_t n, const mpl::int_<1>& )
+{
+ static const boost::array<float, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+ {{
+ +1.00000000000000000000000000000000000000000F,
+ +0.166666666666666666666666666666666666666667F,
+ -0.0333333333333333333333333333333333333333333F,
+ +0.0238095238095238095238095238095238095238095F,
+ -0.0333333333333333333333333333333333333333333F,
+ +0.0757575757575757575757575757575757575757576F,
+ -0.253113553113553113553113553113553113553114F,
+ +1.16666666666666666666666666666666666666667F,
+ -7.09215686274509803921568627450980392156863F,
+ +54.9711779448621553884711779448621553884712F,
+ -529.124242424242424242424242424242424242424F,
+ +6192.12318840579710144927536231884057971014F,
+ -86580.2531135531135531135531135531135531136F,
+ +1.42551716666666666666666666666666666666667e6F,
+ -2.72982310678160919540229885057471264367816e7F,
+ +6.01580873900642368384303868174835916771401e8F,
+ -1.51163157670921568627450980392156862745098e10F,
+ +4.29614643061166666666666666666666666666667e11F,
+ -1.37116552050883327721590879485616327721591e13F,
+ +4.88332318973593166666666666666666666666667e14F,
+ -1.92965793419400681486326681448632668144863e16F,
+ +8.41693047573682615000553709856035437430786e17F,
+ -4.03380718540594554130768115942028985507246e19F,
+ +2.11507486380819916056014539007092198581560e21F,
+ -1.20866265222965259346027311937082525317819e23F,
+ +7.50086674607696436685572007575757575757576e24F,
+ -5.03877810148106891413789303052201257861635e26F,
+ +3.65287764848181233351104308429711779448622e28F,
+ -2.84987693024508822262691464329106781609195e30F,
+ +2.38654274996836276446459819192192149717514e32F,
+ -2.13999492572253336658107447651910973926742e34F,
+ +2.05009757234780975699217330956723102516667e36F,
+ -2.09380059113463784090951852900279701847092e38F,
+ }};
+
+ return bernoulli_data[n];
+}
+
+
+template <class T>
+inline T unchecked_bernoulli_imp(std::size_t n, const mpl::int_<2>& )
+{
+ static const boost::array<double, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+ {{
+ +1.00000000000000000000000000000000000000000,
+ +0.166666666666666666666666666666666666666667,
+ -0.0333333333333333333333333333333333333333333,
+ +0.0238095238095238095238095238095238095238095,
+ -0.0333333333333333333333333333333333333333333,
+ +0.0757575757575757575757575757575757575757576,
+ -0.253113553113553113553113553113553113553114,
+ +1.16666666666666666666666666666666666666667,
+ -7.09215686274509803921568627450980392156863,
+ +54.9711779448621553884711779448621553884712,
+ -529.124242424242424242424242424242424242424,
+ +6192.12318840579710144927536231884057971014,
+ -86580.2531135531135531135531135531135531136,
+ +1.42551716666666666666666666666666666666667e6,
+ -2.72982310678160919540229885057471264367816e7,
+ +6.01580873900642368384303868174835916771401e8,
+ -1.51163157670921568627450980392156862745098e10,
+ +4.29614643061166666666666666666666666666667e11,
+ -1.37116552050883327721590879485616327721591e13,
+ +4.88332318973593166666666666666666666666667e14,
+ -1.92965793419400681486326681448632668144863e16,
+ +8.41693047573682615000553709856035437430786e17,
+ -4.03380718540594554130768115942028985507246e19,
+ +2.11507486380819916056014539007092198581560e21,
+ -1.20866265222965259346027311937082525317819e23,
+ +7.50086674607696436685572007575757575757576e24,
+ -5.03877810148106891413789303052201257861635e26,
+ +3.65287764848181233351104308429711779448622e28,
+ -2.84987693024508822262691464329106781609195e30,
+ +2.38654274996836276446459819192192149717514e32,
+ -2.13999492572253336658107447651910973926742e34,
+ +2.05009757234780975699217330956723102516667e36,
+ -2.09380059113463784090951852900279701847092e38,
+ +2.27526964884635155596492603527692645814700e40,
+ -2.62577102862395760473030497361582020814490e42,
+ +3.21250821027180325182047923042649852435219e44,
+ -4.15982781667947109139170744952623589366896e46,
+ +5.69206954820352800238834562191210586444805e48,
+ -8.21836294197845756922906534686173330145509e50,
+ +1.25029043271669930167323398297028955241772e53,
+ -2.00155832332483702749253291988132987687242e55,
+ +3.36749829153643742333966769033387530162196e57,
+ -5.94709705031354477186604968440515408405791e59,
+ +1.10119103236279775595641307904376916046305e62,
+ -2.13552595452535011886583850190410656789733e64,
+ +4.33288969866411924196166130593792062184514e66,
+ -9.18855282416693282262005552155018971389604e68,
+ +2.03468967763290744934550279902200200659751e71,
+ -4.70038339580357310785752555350060606545967e73,
+ +1.13180434454842492706751862577339342678904e76,
+ -2.83822495706937069592641563364817647382847e78,
+ +7.40642489796788506297508271409209841768797e80,
+ -2.00964548027566044834656196727153631868673e83,
+ +5.66571700508059414457193460305193569614195e85,
+ -1.65845111541362169158237133743199123014950e88,
+ +5.03688599504923774192894219151801548124424e90,
+ -1.58614682376581863693634015729664387827410e93,
+ +5.17567436175456269840732406825071225612408e95,
+ -1.74889218402171173396900258776181591451415e98,
+ +6.11605199949521852558245252642641677807677e100,
+ -2.21227769127078349422883234567129324455732e103,
+ +8.27227767987709698542210624599845957312047e105,
+ -3.19589251114157095835916343691808148735263e108,
+ +1.27500822233877929823100243029266798669572e111,
+ -5.25009230867741338994028246245651754469199e113,
+ +2.23018178942416252098692981988387281437383e116,
+ -9.76845219309552044386335133989802393011669e118,
+ +4.40983619784529542722726228748131691918758e121,
+ -2.05085708864640888397293377275830154864566e124,
+ +9.82144332797912771075729696020975210414919e126,
+ -4.84126007982088805087891967099634127611305e129,
+ +2.45530888014809826097834674040886903996737e132,
+ -1.28069268040847475487825132786017857218118e135,
+ +6.86761671046685811921018885984644004360924e137,
+ -3.78464685819691046949789954163795568144895e140,
+ +2.14261012506652915508713231351482720966602e143,
+ -1.24567271371836950070196429616376072194583e146,
+ +7.43457875510001525436796683940520613117807e148,
+ -4.55357953046417048940633332233212748767721e151,
+ +2.86121128168588683453638472510172325229190e154,
+ -1.84377235520338697276882026536287854875414e157,
+ +1.21811545362210466995013165065995213558174e160,
+ -8.24821871853141215484818457296893447301419e162,
+ +5.72258779378329433296516498142978615918685e165,
+ -4.06685305250591047267679693831158655602196e168,
+ +2.95960920646420500628752695815851870426379e171,
+ -2.20495225651894575090311752273445984836379e174,
+ +1.68125970728895998058311525151360665754464e177,
+ -1.31167362135569576486452806355817153004431e180,
+ +1.04678940094780380821832853929823089643829e183,
+ -8.54328935788337077185982546299082774593270e185,
+ +7.12878213224865423522884066771438224721245e188,
+ -6.08029314555358993000847118686477458461988e191,
+ +5.29967764248499239300942910043247266228490e194,
+ -4.71942591687458626443646229013379911103761e197,
+ +4.29284137914029810894168296541074669045521e200,
+ -3.98767449682322074434477655542938795106651e203,
+ +3.78197804193588827138944181161393327898220e206,
+ -3.66142336836811912436858082151197348755196e209,
+ +3.61760902723728623488554609298914089477541e212,
+ -3.64707726451913543621383088655499449048682e215,
+ +3.75087554364544090983452410104814189306842e218,
+ -3.93458672964390282694891288533713429355657e221,
+ +4.20882111481900820046571171111494898242731e224,
+ -4.59022962206179186559802940573325591059371e227,
+ +5.10317257726295759279198185106496768539760e230,
+ -5.78227623036569554015377271242917142512200e233,
+ +6.67624821678358810322637794412809363451080e236,
+ -7.85353076444504163225916259639312444428230e239,
+ +9.41068940670587255245443288258762485293948e242,
+ -1.14849338734651839938498599206805592548354e246,
+ +1.42729587428487856771416320087122499897180e249,
+ -1.80595595869093090142285728117654560926719e252,
+ +2.32615353076608052161297985184708876161736e255,
+ -3.04957517154995947681942819261542593785327e258,
+ +4.06858060764339734424012124124937318633684e261,
+ -5.52310313219743616252320044093186392324280e264,
+ +7.62772793964343924869949690204961215533859e267,
+ -1.07155711196978863132793524001065396932667e271,
+ +1.53102008959691884453440916153355334355847e274,
+ -2.22448916821798346676602348865048510824835e277,
+ +3.28626791906901391668189736436895275365183e280,
+ -4.93559289559603449020711938191575963496999e283,
+ +7.53495712008325067212266049779283956727824e286,
+ -1.16914851545841777278088924731655041783900e290,
+ +1.84352614678389394126646201597702232396492e293,
+ -2.95368261729680829728014917350525183485207e296,
+ +4.80793212775015697668878704043264072227967e299,
+ -7.95021250458852528538243631671158693036798e302,
+ +1.33527841873546338750122832017820518292039e306
+ }};
+
+ return bernoulli_data[n];
+}
+
+template <class T>
+inline T unchecked_bernoulli_imp(std::size_t n, const mpl::int_<3>& )
+{
+ static const boost::array<long double, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+ {{
+ +1.00000000000000000000000000000000000000000L,
+ +0.166666666666666666666666666666666666666667L,
+ -0.0333333333333333333333333333333333333333333L,
+ +0.0238095238095238095238095238095238095238095L,
+ -0.0333333333333333333333333333333333333333333L,
+ +0.0757575757575757575757575757575757575757576L,
+ -0.253113553113553113553113553113553113553114L,
+ +1.16666666666666666666666666666666666666667L,
+ -7.09215686274509803921568627450980392156863L,
+ +54.9711779448621553884711779448621553884712L,
+ -529.124242424242424242424242424242424242424L,
+ +6192.12318840579710144927536231884057971014L,
+ -86580.2531135531135531135531135531135531136L,
+ +1.42551716666666666666666666666666666666667E6L,
+ -2.72982310678160919540229885057471264367816E7L,
+ +6.01580873900642368384303868174835916771401E8L,
+ -1.51163157670921568627450980392156862745098E10L,
+ +4.29614643061166666666666666666666666666667E11L,
+ -1.37116552050883327721590879485616327721591E13L,
+ +4.88332318973593166666666666666666666666667E14L,
+ -1.92965793419400681486326681448632668144863E16L,
+ +8.41693047573682615000553709856035437430786E17L,
+ -4.03380718540594554130768115942028985507246E19L,
+ +2.11507486380819916056014539007092198581560E21L,
+ -1.20866265222965259346027311937082525317819E23L,
+ +7.50086674607696436685572007575757575757576E24L,
+ -5.03877810148106891413789303052201257861635E26L,
+ +3.65287764848181233351104308429711779448622E28L,
+ -2.84987693024508822262691464329106781609195E30L,
+ +2.38654274996836276446459819192192149717514E32L,
+ -2.13999492572253336658107447651910973926742E34L,
+ +2.05009757234780975699217330956723102516667E36L,
+ -2.09380059113463784090951852900279701847092E38L,
+ +2.27526964884635155596492603527692645814700E40L,
+ -2.62577102862395760473030497361582020814490E42L,
+ +3.21250821027180325182047923042649852435219E44L,
+ -4.15982781667947109139170744952623589366896E46L,
+ +5.69206954820352800238834562191210586444805E48L,
+ -8.21836294197845756922906534686173330145509E50L,
+ +1.25029043271669930167323398297028955241772E53L,
+ -2.00155832332483702749253291988132987687242E55L,
+ +3.36749829153643742333966769033387530162196E57L,
+ -5.94709705031354477186604968440515408405791E59L,
+ +1.10119103236279775595641307904376916046305E62L,
+ -2.13552595452535011886583850190410656789733E64L,
+ +4.33288969866411924196166130593792062184514E66L,
+ -9.18855282416693282262005552155018971389604E68L,
+ +2.03468967763290744934550279902200200659751E71L,
+ -4.70038339580357310785752555350060606545967E73L,
+ +1.13180434454842492706751862577339342678904E76L,
+ -2.83822495706937069592641563364817647382847E78L,
+ +7.40642489796788506297508271409209841768797E80L,
+ -2.00964548027566044834656196727153631868673E83L,
+ +5.66571700508059414457193460305193569614195E85L,
+ -1.65845111541362169158237133743199123014950E88L,
+ +5.03688599504923774192894219151801548124424E90L,
+ -1.58614682376581863693634015729664387827410E93L,
+ +5.17567436175456269840732406825071225612408E95L,
+ -1.74889218402171173396900258776181591451415E98L,
+ +6.11605199949521852558245252642641677807677E100L,
+ -2.21227769127078349422883234567129324455732E103L,
+ +8.27227767987709698542210624599845957312047E105L,
+ -3.19589251114157095835916343691808148735263E108L,
+ +1.27500822233877929823100243029266798669572E111L,
+ -5.25009230867741338994028246245651754469199E113L,
+ +2.23018178942416252098692981988387281437383E116L,
+ -9.76845219309552044386335133989802393011669E118L,
+ +4.40983619784529542722726228748131691918758E121L,
+ -2.05085708864640888397293377275830154864566E124L,
+ +9.82144332797912771075729696020975210414919E126L,
+ -4.84126007982088805087891967099634127611305E129L,
+ +2.45530888014809826097834674040886903996737E132L,
+ -1.28069268040847475487825132786017857218118E135L,
+ +6.86761671046685811921018885984644004360924E137L,
+ -3.78464685819691046949789954163795568144895E140L,
+ +2.14261012506652915508713231351482720966602E143L,
+ -1.24567271371836950070196429616376072194583E146L,
+ +7.43457875510001525436796683940520613117807E148L,
+ -4.55357953046417048940633332233212748767721E151L,
+ +2.86121128168588683453638472510172325229190E154L,
+ -1.84377235520338697276882026536287854875414E157L,
+ +1.21811545362210466995013165065995213558174E160L,
+ -8.24821871853141215484818457296893447301419E162L,
+ +5.72258779378329433296516498142978615918685E165L,
+ -4.06685305250591047267679693831158655602196E168L,
+ +2.95960920646420500628752695815851870426379E171L,
+ -2.20495225651894575090311752273445984836379E174L,
+ +1.68125970728895998058311525151360665754464E177L,
+ -1.31167362135569576486452806355817153004431E180L,
+ +1.04678940094780380821832853929823089643829E183L,
+ -8.54328935788337077185982546299082774593270E185L,
+ +7.12878213224865423522884066771438224721245E188L,
+ -6.08029314555358993000847118686477458461988E191L,
+ +5.29967764248499239300942910043247266228490E194L,
+ -4.71942591687458626443646229013379911103761E197L,
+ +4.29284137914029810894168296541074669045521E200L,
+ -3.98767449682322074434477655542938795106651E203L,
+ +3.78197804193588827138944181161393327898220E206L,
+ -3.66142336836811912436858082151197348755196E209L,
+ +3.61760902723728623488554609298914089477541E212L,
+ -3.64707726451913543621383088655499449048682E215L,
+ +3.75087554364544090983452410104814189306842E218L,
+ -3.93458672964390282694891288533713429355657E221L,
+ +4.20882111481900820046571171111494898242731E224L,
+ -4.59022962206179186559802940573325591059371E227L,
+ +5.10317257726295759279198185106496768539760E230L,
+ -5.78227623036569554015377271242917142512200E233L,
+ +6.67624821678358810322637794412809363451080E236L,
+ -7.85353076444504163225916259639312444428230E239L,
+ +9.41068940670587255245443288258762485293948E242L,
+ -1.14849338734651839938498599206805592548354E246L,
+ +1.42729587428487856771416320087122499897180E249L,
+ -1.80595595869093090142285728117654560926719E252L,
+ +2.32615353076608052161297985184708876161736E255L,
+ -3.04957517154995947681942819261542593785327E258L,
+ +4.06858060764339734424012124124937318633684E261L,
+ -5.52310313219743616252320044093186392324280E264L,
+ +7.62772793964343924869949690204961215533859E267L,
+ -1.07155711196978863132793524001065396932667E271L,
+ +1.53102008959691884453440916153355334355847E274L,
+ -2.22448916821798346676602348865048510824835E277L,
+ +3.28626791906901391668189736436895275365183E280L,
+ -4.93559289559603449020711938191575963496999E283L,
+ +7.53495712008325067212266049779283956727824E286L,
+ -1.16914851545841777278088924731655041783900E290L,
+ +1.84352614678389394126646201597702232396492E293L,
+ -2.95368261729680829728014917350525183485207E296L,
+ +4.80793212775015697668878704043264072227967E299L,
+ -7.95021250458852528538243631671158693036798E302L,
+ +1.33527841873546338750122832017820518292039E306L,
+#if LDBL_MAX_EXP == 16384
+ // Entries 260 - 600 http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C258%2C600%2C2}]
+ -2.277640649601959593875058983506938037019e309L,
+ 3.945184036046326234163525556422667595884e312L,
+ -6.938525772130602106071724989641405550473e315L,
+ 1.238896367577564823729057820219210929986e319L,
+ -2.245542599169309759499987966025604480745e322L,
+ 4.131213176073842359732511639489669404266e325L,
+ -7.713581346815269584960928069762882771369e328L,
+ 1.461536066837669600638613788471335541313e332L,
+ -2.809904606225532896862935642992712059631e335L,
+ 5.480957121318876639512096994413992284327e338L,
+ -1.084573284087686110518125291186079616320e342L,
+ 2.176980775647663539729165173863716459962e345L,
+ -4.431998786117553751947439433256752608068e348L,
+ 9.150625657715535047417756278073770096073e351L,
+ -1.915867353003157351316577579148683133613e355L,
+ 4.067256303542212258698836003682016040629e358L,
+ -8.754223791037736616228150209910348734629e361L,
+ 1.910173688735533667244373747124109379826e365L,
+ -4.225001320265091714631115064713174404607e368L,
+ 9.471959352547827678466770796787503034505e371L,
+ -2.152149973279986829719817376756088198573e375L,
+ 4.955485775334221051344839716507812871361e378L,
+ -1.156225941759134696630956889716381968142e382L,
+ 2.733406597646137698610991926705098514017e385L,
+ -6.546868135325176947099912523279938546333e388L,
+ 1.588524912441221472814692121069821695547e392L,
+ -3.904354800861715180218598151050191841308e395L,
+ 9.719938686092045781827273411668132975319e398L,
+ -2.450763621049522051234479737511375679283e402L,
+ 6.257892098396815305085674126334317095277e405L,
+ -1.618113552083806592527989531636955084420e409L,
+ 4.236528795217618357348618613216833722648e412L,
+ -1.123047068199051008086174989124136878992e416L,
+ 3.013971787525654770217283559392286666886e419L,
+ -8.188437573221553030375681429202969070420e422L,
+ 2.251910591336716809153958146725775718707e426L,
+ -6.268411292043789823075314151509139413399e429L,
+ 1.765990845202322642693572112511312471527e433L,
+ -5.035154436231331651259071296731160882240e436L,
+ 1.452779356460483245253765356664402207266e440L,
+ -4.241490890130137339052414960684151515166e443L,
+ 1.252966001692427774088293833338841893293e447L,
+ -3.744830047478272947978103227876747240343e450L,
+ 1.132315806695710930595876001089232216024e454L,
+ -3.463510845942701805991786197773934662578e457L,
+ 1.071643382649675572086865465873916611537e461L,
+ -3.353824475439933688957233489984711465335e464L,
+ 1.061594257145875875963152734129803268488e468L,
+ -3.398420969215528955528654193586189805265e471L,
+ 1.100192502000434096206138068020551065890e475L,
+ -3.601686379213993374332690210094863486472e478L,
+ 1.192235170430164900533187239994513019475e482L,
+ -3.990342751779668381699052942504119409180e485L,
+ 1.350281800938769780891258894167663309221e489L,
+ -4.619325443466054312873093650888507562249e492L,
+ 1.597522243968586548227514639959727696694e496L,
+ -5.584753729092155108530929002119620487652e499L,
+ 1.973443623104646193229794524759543752089e503L,
+ -7.048295441989615807045620880311201930244e506L,
+ 2.544236702499719094591873151590280263560e510L,
+ -9.281551595258615205927443367289948150345e513L,
+ 3.421757163154453657766296828520235351572e517L,
+ -1.274733639384538364282697627345068947433e521L,
+ 4.798524805311016034711205886780460173566e524L,
+ -1.825116948422858388787806917284878870034e528L,
+ 7.013667442807288452441777981425055613982e531L,
+ -2.723003862685989740898815670978399383114e535L,
+ 1.068014853917260290630122222858884658850e539L,
+ -4.231650952273697842269381683768681118533e542L,
+ 1.693650052202594386658903598564772900388e546L,
+ -6.846944855806453360616258582310883597678e549L,
+ 2.795809132238082267120232174243715559601e553L,
+ -1.153012972808983269106716828311318981951e557L,
+ 4.802368854268746357511997492039592697149e560L,
+ -2.019995255271910836389761734035403905781e564L,
+ 8.580207235032617856059250643095019760968e567L,
+ -3.680247942263468164408192134916355198549e571L,
+ 1.593924457586765331397457407661306895942e575L,
+ -6.970267175232643679233530367569943057501e578L,
+ 3.077528087427698518703282907890556154309e582L,
+ -1.371846760052887888926055417297342106614e586L,
+ 6.173627360829553396851763207025505289166e589L,
+ -2.804703130495506384463249394043486916669e593L,
+ 1.286250900087150126167490951216207186092e597L,
+ -5.954394420063617872366818601092036543220e600L,
+ 2.782297785278756426177542270854984091406e604L,
+ -1.312214674935307746141207680066262384215e608L,
+ 6.246299145383554153167974732783934504370e611L,
+ -3.000812007679574430883792565577444226490e615L,
+ 1.454904877136007844493861746476079537075e619L,
+ -7.118558521873800304612781121044077357278e622L,
+ 3.514739820897817389472822276832677887997e626L,
+ -1.751137068816377401163011262831890828437e630L,
+ 8.803498091818800678575314081978951179602e633L,
+ -4.465612911700593572269200981612564161010e637L,
+ 2.285494565287530681465757798517033542888e641L,
+ -1.180145168917737098025683613598595411329e645L,
+ 6.147941849198393232663105284575149616925e648L,
+ -3.231069156963603593233679426198974663352e652L,
+ 1.713042725635435041806895849197608270935e656L,
+ -9.161761363270648920537613435771882898051e659L,
+ 4.942675965960539112005679080810117766825e663L,
+ -2.689684712697383518131267222872386600031e667L,
+ 1.476320014229917759615308193449511534656e671L,
+ -8.173037740864781506597184122049453514594e674L,
+ 4.563462313190521363235182420178784459580e678L,
+ -2.569790015236158475703055501886439298708e682L,
+ 1.459410219452119981958355737832022375085e686L,
+ -8.358304882556983795372406183642486436653e689L,
+ 4.827305091483557818593092377664570208355e693L,
+ -2.811394311081493166793414157061950132403e697L,
+ 1.651026863340675349245561261339568827739e701L,
+ -9.776578579336866764167878646459810047899e704L,
+ 5.837207965197521880181236529616560780535e708L,
+ -3.513938957938032127105389702846371181520e712L,
+ 2.132747371360190507595748444536911078788e716L,
+ -1.305047363239192640729466563372665311602e720L,
+ 8.050825342678337497636292798039996484780e723L,
+ -5.006884161223862543665524155681082112689e727L,
+ 3.139016066011452177570812014513491361235e731L,
+ -1.983829535212711378291469356666001365873e735L,
+ 1.263822427649676371257598052486237628698e739L,
+ -8.115678659900522918802121684491754629503e742L,
+ 5.252995164972075271667364371449050412435e746L,
+ -3.427038125662404660056511738625477058135e750L,
+ 2.253446011834352733279946306835940729858e754L,
+ -1.493407341897034717876962786798831719683e758L,
+ 9.974681322653365118752729509398728354442e761L,
+ -6.714230142773850863927710112350816379426e765L,
+ 4.554668668931723346600337564274944733530e769L,
+ -3.113635386023220127834102980385275379533e773L,
+ 2.144945411287666204679363498162954050208e777L,
+ -1.488982121181387164932397544378555256016e781L,
+ 1.041537218854627455352298173588983048748e785L,
+ -7.341073881786613676177562822942175683993e788L,
+ 5.213524272587199574980117351016322518428e792L,
+ -3.730592531776514409283897139216167197989e796L,
+ 2.689592876341877079083449497724049500175e800L,
+ -1.953643788231947582529884602972233135002e804L,
+ 1.429691073080500563348668321308878246277e808L,
+ -1.054059177095488639836063073070536825675e812L,
+ 7.828919160938693948399336431565350676613e815L,
+ -5.857884457184396382550955498026762014753e819L,
+ 4.415401588264172474136969345712659422380e823L,
+ -3.352573884181287635796498822858109969161e827L,
+ 2.564210385719224000156548240934108974447e831L,
+ -1.975534392116037602837941409848663077528e835L,
+ 1.533062123975940045180943006948008486466e839L,
+ -1.198306160488763291730059994812781226903e843L,
+ 9.434034267770711698676321369174735725321e846L,
+ -7.480619200038505368468483892246806488879e850L,
+ 5.974161898439971564124576801455052907638e854L,
+ -4.805125663714699771668630995361572639386e858L,
+ 3.892332138028039952403812726744593073776e862L,
+ -3.175276505779699340738548328810180869575e866L,
+ 2.608608681939322393581069188271626122519e870L,
+ -2.158148554392732439392868052394994052628e874L,
+ 1.797993483301448477700600221980862686033e878L,
+ -1.508407575089108597171576068862286462909e882L,
+ 1.274273406242459482708930389008701147244e886L,
+ -1.083950475353171986748233157909397370193e890L,
+ 9.284292630726328432038470356821265395331e893L,
+ -8.007012115449516364480417355063446317414e897L,
+ 6.952871948429568933888979915833266241471e901L,
+ -6.078828929473797621198666799700739891205e905L,
+ 5.350908089710964244671334224708057812633e909L,
+ -4.742168072503284973969982758434401589090e913L,
+ 4.231149239401967697257534662010605751136e917L,
+ -3.800684612827828851942743291026898158947e921L,
+ 3.436984796314246158361599955909956583986e925L,
+ -3.128930718993658356398482705317381808301e929L,
+ //
+ // 602-1300: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C602%2C1300%2C2}]
+ 2.867524740577223817164663595437919813239e933L, -2.645462974939090580963101220449509725942e937L, 2.456800827789169780295419018499543141869e941L, -2.296690549725790064673528302231294870532e945L, 2.161174697699793265715182091764676666457e949L, -2.047023224586087259305754002882269123194e953L, 1.951604806042481282712736234132803700277e957L, -1.872785206668284042110390583158639495143e961L, 1.808847160923282257302788929692654262867e965L, -1.758427529634609613399327744595257497188e969L, 1.720468488019528147087036246754294757647e973L, -1.694180279355332648057740852839804839425e977L, 1.679013685251183870616469618951463869496e981L, -1.674640861433092946269144173974414945664e985L, 1.680943600147858322148767806987527412112e989L, -1.698008433134805056489370119323402510305e993L, 1.726128304411348354183882648263448448633e997L, -1.765810838736918108045764015629875016219e1001L, 1.817793526882665071123822455897912718293e1005L, -1.883066459765807128944897377914669600374e1009L, 1.962903588035940537938222992228124233567e1013L, -2.058903881920696086033171142046100185783e1017L, 2.173044241735786946064676598703393618281e1021L, -2.307746591425236218893160658331303115253e1025L, 2.465962312241418731528973526597433097256e1029L, -2.651278087802503406316742676403301581549e1033L, 2.868048395658440423778896607880692085708e1037L, -3.121561373094393453726645989392054731637e1041L, 3.418246710091027042099932753084126095820e1045L, -3.765936717592482928796920675282930034018e1049L, 4.174194967165213973474293718362757753877e1053L, -4.654731142471753017867105249805137855862e1057L, 5.221926310090434518253178454907900079787e1061L, -5.893500145664015254409680930288710794031e1065L, 6.691361332576333738130720616841706994101e1069L, -7.642695184575063524608775697714741180954e1073L, 8.781359617440634128952082759434723165820e1077L, -1.014968338800868135594698909567734048618e1082L, 1.180079105471061498849752479044520598414e1086L, -1.380162016721660241308046692646452732446e1090L, 1.623685158291375662775444238282343536948e1094L, -1.921404880943289359290531906131400049399e1098L, 2.287040419533950152851434188305457266969e1102L, -2.738162880206032093123060939173765335255e1106L, 3.297371307848643161532227459901386725801e1110L, -3.993854689967542662299211323085023297602e1114L, 4.865474805885735467044047308902313673643e1118L, -5.961554732739027308247618738765152679497e1122L, 7.346627151757492821447573639763873833441e1126L, -9.105493288459908620636712748727395637965e1130L, 1.135007867626164861991621396462821975167e1135L, -1.422876214067403769204874786137232627418e1139L, 1.793912271573925309173135913914667878908e1143L, -2.274542916104231188526120123855259514144e1147L, 2.900273688809987694128857655036783261991e1151L, -3.719022795563122339874875448447744493398e1155L, 4.795753420982845153626611023078973364321e1159L, -6.218937220186281310109009529226561379773e1163L, 8.109611247999584815668395828940708619394e1167L, -1.063412316303440216539797215354141158589e1172L, 1.402214363674117662460496032135704328989e1176L, -1.859223235464558752766840772026058694872e1180L, 2.478828203789903637835992128856742276028e1184L, -3.323169416193176673655321536761413885767e1188L, 4.479640207312477092938541546776915956580e1192L, -6.071721672924085739424644485636889518799e1196L, 8.274698015123579607850404326757887762270e1200L, -1.133855131459773018024052539697784205966e1205L, 1.562146222050424344025824344480153248984e1209L, -2.163904570724750459592352173471446831752e1213L, 3.013703210722669908901286635073603018696e1217L, -4.219903244242308803914269531001720703294e1221L, 5.940703220571043642186808904696174833998e1225L, -8.408147464216029127243257448169774333631e1229L, 1.196419999747411909144144315499654470715e1234L, -1.711518922741148710381740436694440587059e1238L, 2.461434539630850545757453894977350505251e1242L, -3.558748530932574002484841810677232366801e1246L, 5.172525606281917297657859608800373729529e1250L, -7.557850217376323621984784308774476917753e1254L, 1.110141075986004209769735296234549704181e1259L, -1.639216556732622481406083885926912451281e1263L, 2.433138328152562628385514545400044125983e1267L, -3.630476645219033020888837165221286413171e1271L, 5.445289518636306992942604775585977779418e1275L, -8.209806424989072060381590985042272020067e1279L, 1.244209849774134691374848390346442737613e1284L, -1.895384488692308848372754844910263931874e1288L, 2.902272596647764894203369746806169285113e1292L, -4.466944174025026625137032739317650862593e1296L, 6.910485739507636504313238347702354354916e1300L, -1.074550085668784170644854815272144687769e1305L, 1.679419258904938802199084915274175753529e1309L, -2.638155207645646220849795321076977230763e1313L, 4.165284786632654168563096850610185378233e1317L, -6.609774274649031371770290191295685774584e1321L, 1.054194100570841329575393359295845860860e1326L, -1.689822316104196916970708778265725885275e1330L, 2.722340957904912685605914893019783431164e1334L, -4.407776313964403233676810178851005163725e1338L, 7.172436210641903635864868181569129834361e1342L, -1.172947440100495955246356688225986736990e1347L, 1.927745674072824377954824961348211728006e1351L, -3.184013467435655962214317208087993711563e1355L, 5.285045125125832341263897233405196808096e1359L, -8.815883582819232027207118521581424783107e1363L, 1.477818368424505276711779171224799759099e1368L, -2.489482576496570159333357550363134602876e1372L, 4.214292881345076419678976329218843808204e1376L, -7.169068531615459070909644981451297906220e1380L, 1.225513133750594558180516896275774441895e1385L, -2.105160827387119480607950260289853896637e1389L, 3.633787605672960549893307203363402915249e1393L, -6.302830804027849515239463308430185990705e1397L, 1.098521433860299633481449685364914115468e1402L, -1.923858597401607622723144320370279518600e1406L, 3.385512828549942051667348582951554570164e1410L, -5.986286250836771248147827011780631183980e1414L, 1.063572794668186370728928272374836554300e1419L, -1.898666684876492795233907174493757572290e1423L, 3.405627002840442789235393111726609930533e1427L, -6.137724140284450036591063946055819333244e1431L, 1.111411024660941507986132154479364267486e1436L, -2.022060876221034821890406900217875915949e1440L, 3.696248025817144690840539132103538834108e1444L, -6.788448439024998306316860676030442691610e1448L, 1.252615233049059554031883468823648511657e1453L, -2.322190433141265975888955985950824418729e1457L, 4.325200102353909846882217732999001735342e1461L, -8.093531903011880118699218269369570178812e1465L, 1.521558881878323790120983450270946857209e1470L, -2.873780311010933807686415826253380907421e1474L, 5.452903697278823304173192839252276211670e1478L, -1.039457922537509500320638240809547113575e1483L, 1.990610112724715126895008793014214505760e1487L, -3.829667853173777076954453401761025071562e1491L, 7.401624504283011888971231756333356050310e1495L, -1.437075122764477911733220492562365990710e1500L, 2.802940275035867428066581228962104019228e1504L, -5.491938363067613321364335249495394164430e1508L, 1.080961960603953462180593404647115933651e1513L, -2.137290931892412298654741768897581319007e1517L, 4.245031321673807283498263276791307370788e1521L, -8.469499523038763989328773224520912663309e1525L, 1.697421812794203793865032206191322699261e1530L, -3.417217332563937242285349373774004020539e1534L, 6.910378594841763785923780822895851271770e1538L, -1.403696282437585785557998429691459557649e1543L, 2.864060533055333035232343601021192111053e1547L, -5.869818290384811353182423286543086530728e1551L, 1.208359745327224593486268988808338456906e1556L, -2.498576742140453770373914215325521001990e1560L, 5.189311407347546310078739863704346083861e1564L, -1.082537954843916294257278789980768336964e1569L, 2.268238255751421312559806122980932952706e1573L, -4.773557403917983369065731568732198697502e1577L, 1.009019097334998841920279535262007639746e1582L, -2.142181266523235177327239693359275472557e1586L, 4.567814904130855969979178320003286614868e1590L, -9.782550516204803195398428611221899469345e1594L, 2.104180123097086948576304557651398411373e1599L, -4.545658958087323864004652894518442709646e1603L, 9.862563944609427542603740078470901803131e1607L, -2.149105846582226970866569209122813809019e1612L, 4.703235567543888152049628411354542509156e1616L, -1.033719212601584878353206879472796545848e1621L, 2.281767401903848796732740825793310514456e1625L, -5.058236070813950229238666252351966279306e1629L, 1.126112519657857205642546937554224492775e1634L, -2.517766761987679577706779689880657777343e1638L, 5.653225190181653388317503182908983211029e1642L, -1.274735955461074142223278576503188429497e1647L, 2.886578974679460464298863945016671299242e1651L, -6.564203307141426181809363135003467581753e1655L, 1.499036144473064593308260681782048262301e1660L, -3.437714715599902386917108442954580869236e1664L, 7.916830957072777234152907034541325149479e1668L, -1.830850567422571420661248197094782575285e1673L, 4.251778280827419894527511469762091846660e1677L, -9.915182507286989818033146623995507108134e1681L, 2.321878208636697663781227497233334385222e1686L, -5.459879022461660582811365437190884471726e1690L, 1.289222044549922720398543474297554204559e1695L, -3.056819658344217799458557578658863826289e1699L, 7.277891759142725294172926258364455941365e1703L, -1.739928293433385104144012025546489673795e1708L, 4.176797408823713136137404972612780406904e1712L, -1.006788178307821554781930741698052910780e1717L, 2.436754569909644399766538111317379484511e1721L, -5.921896599028498715774458493117079340155e1725L, 1.445045688171565118619109316933316429671e1730L, -3.540547766876069233350621578795319652040e1734L, 8.710114552028472554054293344204504325978e1738L, -2.151484527880464463303897113553085899101e1743L, 5.335928195512405709733771642389502809087e1747L, -1.328726408335015910030370523083559660016e1752L, 3.322090527232917400247098823651437597786e1756L, -8.339387326241218096865362177688582376376e1760L, 2.101842203781264395369771906884644062395e1765L, -5.318704469415522036482913743767085545209e1769L, 1.351288005941730688647540059088127991581e1774L, -3.446853546858473171100748720136784228698e1778L, 8.827284762030783576089954173424852998700e1782L, -2.269642226090373319660782216907175419317e1787L, 5.858820683661708553422363777419430816755e1791L, -1.518385813684321665045387969920683656625e1796L, 3.950661327164595923092260035122668890334e1800L, -1.031976516347387969958181456058243183780e1805L, 2.706317892325103782207094286049104555552e1809L, -7.125140422584701175967252533378906957380e1813L, 1.883260203116768075569432925204868418472e1818L, -4.997193687108743666000994570700725873035e1822L, 1.331182722092654526185433799891693838871e1827L, -3.559930289076558484535632566755216035553e1831L, 9.557281027056970446117541983785660301558e1835L, -2.575805002229372523547972911961335317502e1840L, 6.969058431277067406841032797913179025984e1844L, -1.892842481279278678390672746902260183506e1849L, 5.160964211693777744707760614147460787285e1853L, -1.412602588198037643242529860614298968137e1858L, 3.881313379962387603749693387037174052146e1862L, -1.070542170988009009334148472388319844527e1867L, 2.964094312414144330805731101996829908435e1871L, -8.238350132106899955856124602934281976453e1875L, 2.298504171050560756192352106062598639825e1880L, -6.437303944649223478093890316531995121228e1884L, 1.809727811843121957353712606428292269805e1889L, -5.107047553992257935533518628886728031061e1893L, 1.446674478990385642488446075734631327506e1898L, -4.113513327511444762766719175770513771122e1902L, 1.174067517257431444028448391638451935667e1907L, -3.363630086409895071362533854123306097827e1911L, 9.672868956071838221096869293070568259792e1915L, -2.792101741911955365960369780457612630184e1920L, 8.089710604557382430162031502761771390568e1924L, -2.352650988877130983061761312962677887796e1929L, 6.867549079740051556501575104006222995568e1933L, -2.012161201632998475706904405535757516336e1938L, 5.917489529279588702317256137229398357271e1942L, -1.746718667239329545125902248821502764273e1947L, 5.175069416058975040990816515838893249437e1951L, -1.538913401594651457295303469904084052963e1956L, 4.593185746210984655636051293374195150815e1960L, -1.375981868450401919299150690829612124045e1965L, 4.137207965217520410530508053863759216958e1969L, -1.248518564582257710069294326648626362439e1974L, 3.781575291117895093413381897917341286951e1978L, -1.149575999691408110085856948595444100435e1983L, 3.507413095836612229403470531176947165451e1987L, -1.074032838410645352804690949680310176413e1992L, 3.300857202456564870338466973024760446263e1996L, -1.018149578840803516349758843017979498322e2001L, 3.151876950233613792531594490714752800621e2005L, -9.792574827376149360558532022944033224780e2009L, 3.053456145978161645823454710737904504036e2014L, -9.555442346102849014299990542596620094035e2018L, 3.001037449298122384017009412541525703002e2023L, -9.459120112371096268275049056229023773120e2027L, 2.992168042152196502453442556462819104060e2032L, -9.498922680869041470681858599915282791899e2036L, 3.026307717971075309746179763189393755074e2041L, -9.676079238806159594565350708123427510151e2045L, 3.104778286352798464772361361434013339088e2050L, -9.997786802782252742109475924344598057966e2054L, 3.230847952724856366943939804248186203776e2059L, -1.047769651900498931701604323213605884945e2064L, 3.409958102134053489747140426163802214042e2068L, -1.113687894644055086152064258459886518528e2073L, 3.650114509271160332136458711252217684956e2077L, -1.200536387553969483433239131469825141412e2082L, 3.962482337718333099498977337189304099484e2086L, -1.312441206957064803437100929905979391106e2091L, 4.362246723746013772563799740886664288515e2095L, -1.454975881895253548422481637083633839534e2100L, 4.869831412214692119172895822285084162147e2104L, -1.635618419512383251104125916207188960680e2109L, 5.512611314145041257838234038980389596534e2113L, -1.864392957231340288547618808749072127289e2118L, 6.327317613106621547060670091824665547127e2122L, -2.154772001506498703267302897994526372056e2127L, 7.363426139490286496267931634843475368903e2131L, -2.524950643808031915843604894357998905460e2136L, 8.687956390288096215918373666581638675156e2140L, -2.999656978200020459428228924242615592768e2145L, 1.039231328851609224822335039430898644149e2150L, -3.612742437616019936358910410005123924796e2154L, 1.260211309932738404790711574105022002093e2159L, -4.410916378453971105434385837025433805752e2163L, 1.549140617923265948720013792673729394719e2168L, -5.459173749226782924959103886664322964926e2172L, 1.930343307630952098252884031069043541182e2177L, -6.848749229218425353808144618581305978045e2181L, 2.438117138001365487681440577590059588102e2186L, -8.708873656769794358508423272379627581292e2190L, 3.121268068338199458891764932384819739714e2195L, -1.122430216307539309816165910733145404999e2200L, 4.049900779207199370582177687160985635615e2204L, -1.466167983141158219266077836130256565915e2209L, 5.325678718693772500250292767751070974887e2213L, -1.940955845102272053048140384364058448998e2218L, 7.097467198361219669927211698104447309186e2222L, -2.603968771680987683436428778397387110896e2227L, 9.585403285394812946713320044815117440444e2231L, -3.540176030547640510648455468270569908446e2236L, 1.311827683984025111744358347783996339730e2241L, -4.877124229155333857009747836542843294702e2245L, 1.819213075760490882591173222316749809951e2250L, -6.808221630329265915405178596748950929642e2254L, 2.556299969544109052724772800143396857058e2259L, -9.629763347675306704861859899230073979116e2263L, 3.639508580119285595844040783082958425575e2268L, -1.380037493555816309137481185927387732499e2273L, 5.249980712165216709135893538080020409581e2277L, -2.003737844109055078145975651407367170529e2282L, 7.672522280806944397358668566379646540213e2286L, -2.947454993639165318799389781921184991045e2291L, 1.135966912801707623489383623092951142963e2296L, -4.392293711194501621873299212059053651432e2300L, 1.703813210168560937608104155973968112409e2305L, -6.630636743874062041158387022015853902938e2309L, 2.588742636486379690203698247275411406029e2314L, -1.013959594068423546627946242481463893979e2319L, 3.984265821528043268586235974854766821078e2323L, -1.570614519682157047612769672066387881154e2328L, 6.211297381339606877062824459742129064477e2332L, -2.464246931985476159686671650962783785426e2337L, 9.807833742601662212615240518855757197483e2341L, -3.916036434571217691317276306031837539092e2346L, 1.568566392975837368624727722120313955274e2351L, -6.302885887601142677858008037129298948063e2355L, 2.540704455306077495480843691828334210014e2360L, -1.027412480318234348899627142408950111875e2365L, 4.167823618450297116765978030480648316769e2369L, -1.696076602731914277275203926124423530377e2374L, 6.923904505633301788461482786634220738504e2378L, -2.835463065742506394026733592206185459035e2383L, 1.164828772275756526225951620927486307632e2388L, -4.800242878545012539781545966693324656699e2392L, 1.984381759611877246529319121941597679107e2397L, -8.228979942542641498511023600269641046627e2401L, 3.423130231367101727862739208673375060101e2406L, -1.428418168129733054582191895023094524495e2411L, 5.979153801634459282232521647160044877770e2415L, -2.510581926948409809562349588087762800160e2420L, 1.057443785053915411991029410076722022815e2425L, -4.467723713549428749678277264414266162837e2429L, 1.893474116528533144079731251913008472748e2434L, -8.049601965052954947260081891142509464888e2438L, 3.432648527503971149009691133946275281368e2443L, -1.468324699963694393989960228042259134294e2448L,
+ //
+ // 1302-1600: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1302%2C1600%2C2}]
+ 6.300146502435743791500010801885493871234e2452L, -2.711520667146768856688291798851999580833e2457L, 1.170595555513900137297344452318266434006e2462L, -5.069095411973246242900074508988493530542e2466L, 2.201819284807954055092117706033113168896e2471L, -9.593088725189386197503123561368325167085e2475L, 4.192362385909155628936230811010649614060e2480L, -1.837725836941968309866675158105812946762e2485L, 8.080201101491972605313807752565294881374e2489L, -3.563536075527215702966392543784039539240e2494L, 1.576361051321107275181955665159661781175e2499L, -6.994292466180175594372663323941761853364e2503L, 3.112744353537336702834647901141392426258e2508L, -1.389481328370627358752727485697345194612e2513L, 6.221134636655213696041740685131223999953e2517L, -2.793779613656947577224654924852010601105e2522L, 1.258399062987759035354039924686781081603e2527L, -5.685208194704131918461885165870560583895e2531L, 2.576167857759537340210434756292816456179e2536L, -1.170846052338591953257169251219597581763e2541L, 5.337296787116189575571202979672747140313e2545L, -2.440264475369219459038748840841422948951e2550L, 1.119037151526195093932933161706501865175e2555L, -5.146858829220973887154576240993607686435e2559L, 2.374259791963193693837576781321391741634e2564L, -1.098501215269400934956638118646657823799e2569L, 5.097500369683616795005376807036889542869e2573L, -2.372446971688020647583535886090779018865e2578L, 1.107430282014636546248612381377039463753e2583L, -5.184597227131050012643138079903381280471e2587L, 2.434392040100910394476893838832599310265e2592L, -1.146412753331162872665743308094817095949e2597L, 5.414578104816988124950636101250217797539e2601L, -2.564835392810685332173156758121489913946e2606L, 1.218495070518549208066544111736985586178e2611L, -5.805713573821806672815019495319510297824e2615L, 2.774298194574319430697819781128985128618e2620L, -1.329580186505564627453485444017911980430e2625L, 6.390545858902318479863947547243743500916e2629L, -3.080502542499571035376377703435361520427e2634L, 1.489236104239976282318361008292980814533e2639L, -7.220413839991892382038608955317126799684e2643L, 3.510874916591640642524021216241607185085e2648L, -1.712070118580404599831061485055269100525e2653L, 8.372956919832386730490070625622785478703e2657L, -4.106629146981883685523102256292669054596e2662L, 2.019945438530802964718619732330776495740e2667L, -9.964133277392242111939720494354938982970e2671L, 4.929278642971447854669801547226335041410e2676L, -2.445509657169810919463982615395074704130e2681L, 1.216734421265677299127016883839223226884e2686L, -6.071008437677720186241562251151490713584e2690L, 3.037824949882992896564570441252792097027e2695L, -1.524402878612630565501569310883356490225e2700L, 7.671320530781999359200097739951316234193e2704L, -3.871436167706734376478728954716915204399e2709L, 1.959313530432202158587932399068682252335e2714L, -9.944063618400630821320953821427307024297e2718L, 5.061161998202463346818982228476199873781e2723L, -2.583219090831132705328958245740715185448e2728L, 1.322193991367293532684189527174543501836e2733L, -6.786569982732483290873213417465458376706e2737L, 3.493212334804776543395067018414547811062e2742L, -1.803090099978261928508495412750404640933e2747L, 9.333100843930216567894508007158644926767e2751L, -4.844499031405982604449146511179496492045e2756L, 2.521648090959971240812330574936006906830e2761L, -1.316227870932708474838173333385377250286e2766L, 6.889488826832738674261056521130795910494e2770L, -3.616184242864384509259984293501533623932e2775L, 1.903356124758119137116543283603627028779e2780L, -1.004601544584640657081847200643996069583e2785L, 5.317043885597842225603585588404817559596e2789L, -2.821938866752488868682751438901900485500e2794L, 1.501842023003449590337997900945924161741e2799L, -8.014908048137216649348740300633172710524e2803L, 4.289126235121619907138036129192558937445e2808L, -2.301619137231461344870820700320913118444e2813L, 1.238485136850053215006962645111854705210e2818L, -6.682503731149007943059244518074044280490e2822L, 3.615572393938012932030234169574978859655e2827L, -1.961565108627429629104703146282982075623e2832L, 1.067123259692924564435881096382837264046e2837L, -5.821179870182035246401397327057170726418e2841L, 3.184127229476322727732208017279268211356e2846L, -1.746429902183019597973436257300843998825e2851L, 9.604873565299766333876882842813498685054e2855L, -5.296759978724702692134960752308186890356e2860L, 2.928906353338652198977536576170287112391e2865L, -1.623961162577704769945821804737884742792e2870L, 9.028574047002736235613238355032484299017e2874L, -5.033087486357905828950503441308068892610e2879L, 2.813325650062267479031371852434194635210e2884L, -1.576791132296320840138263753339056345362e2889L, 8.861258343945925667272164531504265693289e2893L, -4.993236404321511029440212686547068244002e2898L, 2.821192993950901287717082243608730217471e2903L, -1.598254169674379493385730199445427966752e2908L, 9.078617590346932363947095804057608979359e2912L, -5.170742114456472142154347566092068443393e2917L, 2.952866185102528847516095880416675972086e2922L, -1.690794578626103552690094140317813413244e2927L, 9.707168799669516048238542260085175133847e2931L, -5.587884732306715493795271931175883605707e2936L, 3.225179489154957423492905957887744116530e2941L, -1.866424419669188178697802576490431604300e2946L, 1.082967626854618222657109354056973072044e2951L, -6.300392007169862865282706277272018077291e2955L, 3.675066377245428685118763485986517510658e2960L, -2.149348371085132073107516253339849053182e2965L, 1.260349351812619395000600434630904474324e2970L, -7.409963623771231302980906971935254993610e2974L, 4.367980758467862686643231700861155889684e2979L, -2.581566823350789671250829457603555544100e2984L, 1.529757357568342629912560827243282062227e2989L, -9.088595394263364554625061567617375176719e2993L, 5.413829169254585648363594604231030415354e2998L, -3.233288119606092759447005827969216281573e3003L, 1.936042437734875803183915765854038424658e3008L, -1.162289934202291715747729318797398221667e3013L, 6.995870350500567071550614251287615697508e3017L, -4.221776496490106417392945233048068288503e3022L, 2.554309239868912570382343877718991746122e3027L, -1.549440871550119801225143558087410562418e3032L, 9.423199525954784955533959981278992475051e3036L, -5.745689660772387668861183913170050552119e3041L, 3.512407521007240798565045328376471603253e3046L, -2.152708113797517364614914569890010876143e3051L, 1.322761289733739440340237168659770154654e3056L, -8.148777388506488753591136948542248584098e3060L, 5.032880858479326069741729004270784264612e3065L, -3.116396010103058126269735274818345780360e3070L, 1.934634831148214353514796782480703021435e3075L, -1.204077166243116651938489240924641810276e3080L, 7.513065583444964704795707060501161621868e3084L, -4.699873512563164914493150520500838535415e3089L, 2.947541197349762411713872934523813866703e3094L, -1.853262416286420077763886100673646141885e3099L, 1.168196427912100545575264493997591040800e3104L, -7.382362285873345348505276546404015842875e3108L, 4.677071041058096429847797962954927487730e3113L, -2.970642034084362431442183248944824506476e3118L, 1.891572688282564476274920103912259755482e3123L, -1.207509963440193713810418554061532113326e3128L, 7.727731208240101791845515599659441557781e3132L, -4.957988488048495669466804712012179891532e3137L, 3.188965862446236259925047956715566822864e3142L, -2.056286895821370106507670239256782411337e3147L, 1.329246918771714093479509313343886287414e3152L, -8.614188519577835653765633797787633659253e3156L,
+ //
+ // 1602-1900: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1602%2C1900%2C2}]
+ 5.596396533621874175909933615343145642161e3161L, -3.644908483469388437457938883454376864180e3166L, 2.379838409026860469990569665632800095988e3171L, -1.557720925267669865362152155022069166772e3176L, 1.022143420270029721682551084917730373739e3181L, -6.723767358891570842116651998814252095792e3185L, 4.433950491570308179905446963723780229747e3190L, -2.931196854668917448553150023532223509373e3195L, 1.942557068752664549549945921392100172355e3200L, -1.290553202978622786891265558106235068695e3205L, 8.595082329732118303768775883557789195136e3209L, -5.738453265222970049867280061719670658457e3214L, 3.840687915100689856736926915331157331684e3219L, -2.576862441955523551149886625900059307506e3224L, 1.733166107320377310388765047659987844208e3229L, -1.168569552450178559412843683052610870569e3234L, 7.898289836694980777809433306209459851871e3238L, -5.351485909164216694400535493924387979018e3243L, 3.634772439350395177931952925644409735777e3248L, -2.474801048002975145046569303233576339695e3253L, 1.689126939254790850063878942448569759390e3258L, -1.155691524500722774057997965355407962525e3263L, 7.926435404542361405718288670391575676323e3267L, -5.449654814183048796524718620178906854846e3272L, 3.755898589900254795894812942275711835138e3277L, -2.594843902682143854622514329649211211808e3282L, 1.797048752397789969347915328338360264536e3287L, -1.247551415074438712713815166107969504456e3292L, 8.681719521514448143910215886388510318746e3296L, -6.056203898213120922016159444227958572276e3301L, 4.234882876331814099029781995617143573641e3306L, -2.968432911643338866295929748049749932906e3311L, 2.085723508930484816454740610260790948864e3316L, -1.469023169879432026361623513301566735138e3321L, 1.037150346505052892302077637883522696572e3326L, -7.339977067836656769144838365069396168014e3330L, 5.206985412168234130596004552956337839140e3335L, -3.702673773319239583641029108403509825141e3340L, 2.639251227995760315076225206168354089692e3345L, -1.885736353072698581595150856674914203383e3350L, 1.350563292338261784288559687678302458996e3355L, -9.695749980998301526113046898985991802000e3359L, 6.977167462628398202151721319169989304520e3364L, -5.032768280399753942925624560483352299263e3369L, 3.638844963651800168080623511900705036698e3374L, -2.637228631269251606169613775399022890118e3379L, 1.915836351653767108720464847696767898597e3384L, -1.395064293615007319328267865803567670760e3389L, 1.018249052614943190644465556486933211307e3394L, -7.449662162606857550867922631658930320805e3398L, 5.463119632208085241594107781601567713991e3403L, -4.015736541676989144201935890497836963875e3408L, 2.958754190183866660901503059509579790900e3413L, -2.185096074054288399312733179064098492511e3418L, 1.617517444557020250864919655301189186103e3423L, -1.200170662015511746748935675940010250555e3428L, 8.925888349899029449015791684428724952411e3432L, -6.653851763691885517669938275618991145962e3437L, 4.971722031098457895973348076474071155918e3442L, -3.723500582577984967442020337848702786829e3447L, 2.795153783541721373364976034391375710110e3452L, -2.103141577212720698169118819883801186873e3457L, 1.586129575320959267959148073466004084241e3462L, -1.198988457279648730711646682156242973137e3467L, 9.084402368157025658430300252246526602197e3471L, -6.898927494435965163817354296023108913714e3476L, 5.251332286149361587885046891266325872375e3481L, -4.006442950956739933884502808470603581850e3486L, 3.063718202820270282280659950794978994604e3491L, -2.348215284130973783732145823834807395920e3496L, 1.803952490148087317330011096671019781340e3501L, -1.389022326803437345760911068933754707688e3506L, 1.071986115818329525986099441493200866389e3511L, -8.292085224650940719705699485423856363908e3515L, 6.428829064452939640541475198655560890344e3520L, -4.995654440302797445368056643032307686314e3525L, 3.890847042582299188849273838681034339406e3530L, -3.037288555751484681537442833929275697351e3535L, 2.376385803695694695338601696534348875191e3540L, -1.863527130251861900692886008704804849076e3545L, 1.464674913498036269270793715104706378182e3550L, -1.153804954579033578659954846698233083197e3555L, 9.109783835348935092264268296199541780964e3559L, -7.208869193983001804305451104827153729326e3564L, 5.717530734277611949162917337810749919265e3569L, -4.544970302634007326980094771330550661605e3574L, 3.621042850825283032134228901678636353355e3579L, -2.891447067949778492831490654980043715471e3584L, 2.314060419397710657435821461707043283167e3589L, -1.856140759923563235273220981623595304434e3594L, 1.492185412981476596273279338314204171587e3599L, -1.202290032627175365810126250991853594801e3604L, 9.708881154579770196658265042625239421053e3608L, -7.857809850747029705680072304049448493252e3613L, 6.373898598298513400228819113197728735438e3618L, -5.181780406472117449048907989647202286666e3623L, 4.222036621953044040518942750638183171221e3628L, -3.447728386429130175025813550845575613047e3633L, 2.821701521717856346224159586852612710800e3638L, -2.314488376711998526455043944505424906920e3643L, 1.902671298033180765286213227393060711096e3648L, -1.567603736821312488140289549008391847440e3653L, 1.294408945316538946551785312385509945367e3658L, -1.071194533081615830960091702262923009420e3663L, 8.884351908108581551151252566466606126397e3667L, -7.384866682828103669170236267589653324531e3672L, 6.152023838008155718180876735217718355563e3677L, -5.136304310431705506236573876510219357975e3682L, 4.297736808124296434723193397876220759378e3687L, -3.603994887745884762510172194982172483480e3692L, 3.028884745605031552399167746007361297342e3697L, -2.551141302205187365552982635794121855138e3702L, 2.153467982869535549299173317536193051608e3707L, -1.821769476343602094059466497311600827296e3712L, 1.544537580582347892980177956984101211006e3717L, -1.312358705945937257247030754517293537539e3722L, 1.117518229297781388884979995402355617235e3727L, -9.536820860779441793021624381677086661097e3731L, 8.156400668831968026931547065507466530546e3736L, -6.990984948728184142718575396052260691181e3741L, 6.005124901126818071638224144541102727563e3746L, -5.169500241880947716732682089328427995109e3751L, 4.459815478235310026240134567325749844182e3756L, -3.855902253361684187081283218890336962427e3761L, 3.340988024176995223515640815937037040546e3766L, -2.901099226680215736735094376078800376829e3771L, 2.524573363444334459448089563912567842927e3776L, -2.201659455716348555524529213295341212492e3781L, 1.924190302190936448078364755844591374353e3786L, -1.685313186099770223843319514432495898517e3791L, 1.479268235966730475749985741048766689808e3796L, -1.301205702893883803117530921635013780575e3801L, 1.147035071153450453405384269242743907426e3806L, -1.013300250456366849150496776951686112298e3811L, 8.970761720605591762300958007557533865346e3815L, -7.958829781488943084496783248922217392838e3820L, 7.076146954685024795720193943027902028642e3825L, -6.304798526260409199660290516451546966159e3830L, 5.629519616664188107056583939722984509867e3835L, -5.037281594099054092767959480843344929292e3840L, 4.516946091316834843581919268794683123349e3845L, -4.058975118925834202620358386772092359951e3850L, 3.655187798978978909014603682039470653549e3855L, -3.298555903041546671060101785513812175322e3860L, 2.983031738662727912016882399515879119620e3865L, -2.703403043317732979516341931451317866898e3870L, 2.455170460800096241793872443768546335444e3875L, -2.234443928432490538417605502448376856290e3880L, 2.037854924078003280537856980560782325730e3885L, -1.862482033918775734840779765743099458137e3890L,
+ //
+ // 1902-2200: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1902%2C2200%2C2}]
+ 1.705787724951999960095629912416210969679e3895L, -1.565564556110550991891247404758895970376e3900L, 1.439889351869832939488618785632174464789e3905L, -1.327084102784257406218693901793045990520e3910L, 1.225682557296027075027021534960026145706e3915L, -1.134401635488994148555787301654561211982e3920L, 1.052116934052356802920509999705307165985e3925L, -9.778417073593082219082361206542342793584e3929L, 9.107088061888562704837019028349522303725e3934L, -8.499551364633102138471246155980056936129e3939L, 7.949082681085658044610890152056533167407e3944L, -7.449748809722797718736397140511396011691e3949L, 6.996307824769340144608141799981589288378e3954L, -6.584122718472954006131003060359621706243e3959L, 6.209086595833487707192492087176843233407e3964L, -5.867557793863165391821489909125720982339e3969L, 5.556303538475260373917478405626416604297e3974L, -5.272450955936249442242634142613834212778e3979L, 5.013444428433789818228792126117223030641e3984L, -4.777008429684552423800736200488532033034e3989L, 4.561115100786341787876705283291018781137e3994L, -4.363955932181992701667719449097126840439e3999L, 4.183917007557000586305945495258591147615e4004L, -4.019557342177353010692923286760895584096e4009L, 3.869589913635745758786275231296652917580e4014L, -3.732865038934070181861017140563175000872e4019L, 3.608355799736107390800162778737339576843e4024L, -3.495145258697474565347261083975193776541e4029L, 3.392415245050326563747729613872524362741e4034L, -3.299436517958948801426629481782413630714e4039L, 3.215560142306355508598119430378551642857e4044L, -3.140209934146377815556058799557727461298e4049L, 3.072875852591406752692761744649563131272e4054L, -3.013108231854799187724018548255922550991e4059L, 2.960512761914376268185064129600549308882e4064L, -2.914746139139036596123006476633770383901e4069L, 2.875512319506974985103149834921665445532e4074L, -2.842559316984704569380036093537576068104e4079L, 2.815676498441436148701483904115879856704e4084L, -2.794692334326268275058539147656334465534e4089L, 2.779472571396106785963004020814493340829e4094L, -2.769918800191406321625251621260024635680e4099L, 2.765967395840433013288935879837390099329e4104L, -2.767588816244119880300161388073836623878e4109L, 2.774787246856347651152278076466043136230e4114L, -2.787600586224957950622601135620189837948e4119L, 2.806100771288225169339048358106052817280e4124L, -2.830394446218080573456394167711739786431e4129L, 2.860623983452244712039094143642843717029e4134L, -2.896968870550611723525738907034588104300e4139L, 2.939647481737606306044335918078617963078e4144L, -2.988919258547518526076380181812161398808e4149L, 3.045087329976721023952450383837883029431e4154L, -3.108501609077197464748958150625867523408e4159L, 3.179562410123820875787052833975010965963e4164L, -3.258724638491880104953913719767939138170e4169L, 3.346502614347964869115073881474258766546e4174L, -3.443475601364631413158991572423086599816e4179L, 3.550294123121350747300886840907918182129e4184L, -3.667687162886053419715985091863398517145e4189L, 3.796470357354794420044278000297864085607e4194L, -3.937555311976846882455930574021795626971e4199L, 4.091960185075595842547638450930710467324e4204L, -4.260821710519620959138720129506770036460e4209L, 4.445408854703156440576808070360934740837e4214L, -4.647138333645908068599900650548418672065e4219L, 4.867592250805288922190809906525766574205e4224L, -5.108538156515551259475573296900660666192e4229L, 5.371951876776035157276013631113314852508e4234L, -5.660043513521220243900043448456234873940e4239L, 5.975287081834808618140945840817834710330e4244L, -6.320454323372684034118816565375206053746e4249L, 6.698653321371992324876559665938996023646e4254L, -7.113372643219128807424340495235606473967e4259L, 7.568531854202750881338746432078817214052e4264L, -8.068539383842553693076672384509126681464e4269L, 8.618358887685935324188596304168259394311e4274L, -9.223585437012291673660319256730398171887e4279L, 9.890533091606747031464718533600572123091e4284L, -1.062633567277107015128545384570274268438e4290L, 1.143906286231591191271274413511275981288e4295L, -1.233785411712565904499340744089870916842e4300L, 1.333307331840530219050170916015276125870e4305L, -1.443648758235403286296065629219598769529e4310L, 1.566147425967471851736562867318748510088e4315L, -1.702326086290842780634120184324081017286e4320L, 1.853920350455786350409148418966087344063e4325L, -2.022911043115598592197907512410632615740e4330L, 2.211561842992792253055716743938240466613e4335L, -2.422463130294011318178080247305407476096e4340L, 2.658583129381772791030436640519847627789e4345L, -2.923327636881988941081365085520742216540e4350L, 3.220609866329557159104267531058019683271e4355L, -3.554932228621330128152149026066400241546e4360L, 3.931482212643167323798366327390058684499e4365L, -4.356244944221399578650235478583297389113e4370L, 4.836135498303121165971331625888490168138e4375L, -5.379154636371461359750682662639062606297e4380L, 5.994572359716861309678596804350346692501e4385L, -6.693144535124290060793936095397161934045e4390L, 7.487368894313509797084395689517008597061e4395L, -8.391787970609807810531578161564037339793e4400L, 9.423348062978921203475110312003096820035e4405L, -1.060182516651648405903017734022504884319e4411L, 1.195033105063952979885086754342706651656e4416L, -1.349591538868673992167798923586925758429e4421L, 1.527028315253291113905307092657539132480e4426L, -1.731065051510920640409442255224015234974e4431L, 1.966076741510092840076264635935585216200e4436L, -2.237214093245750681191361238831105906202e4441L, 2.550550094903891445719729187215253324232e4446L, -2.913255853313667303707651906277658164129e4451L, 3.333811847072394764285817140850092324169e4456L, -3.822262084288044913490118858492563410392e4461L, 4.390520310533864198186202368026630430120e4466L, -5.052739449335052080092114976206610871466e4471L, 5.825757966350870043117899492954521458799e4476L, -6.729639942938203582008846884575881320532e4481L, 7.788329466816396015493306357116312471970e4486L, -9.030444674469025073047417528762134025409e4491L, 1.049024263381993629167658236142000524752e4497L, -1.220879351508964912255081664072251573277e4502L, 1.423541151220109512749655991050110438471e4507L, -1.662940118618541616964708044356967429362e4512L, 1.946219185900482116137855064775635250366e4517L, -2.281995008842006909631764011781911322493e4522L, 2.680678198213108543648324254258111216040e4527L, -3.154866427472784086389609599207759103500e4532L, 3.719827710160801797530420206201570269720e4537L, -4.394095404360277919140027580071549980218e4542L, 5.200201854779615608741690339830306148442e4547L, -6.165584312943608652377791415603277251516e4552L, 7.323705248531382981433751104158852636445e4557L, -8.715439846124090647163930834760361817820e4562L, 1.039079696609215651011736087603304766850e4568L, -1.241105689556982425619608247473478857800e4573L, 1.485143079696380339521658550262280772546e4578L, -1.780437412164973637340821168154300094802e4583L, 2.138372099157518882088209435171770222745e4588L, -2.572985071149069551034276570909360759588e4593L, 3.101615379617643734762997559011097203354e4598L, -3.745713657616368229906151946770042703357e4603L, 4.531859496161940719835150033082561700677e4608L, -5.493040495326927998321538336584233566465e4613L, 6.670262730603009306595018122252730741798e4618L, -8.114581584793494903775255213273982440688e4623L, 9.889666561810883044159054730371102725871e4628L, -1.207504541653929734716275932570097623330e4634L, 1.477021377885843688233899471354959308782e4639L, -1.809984912147908767583043524070645821179e4644L,
+ //
+ // 2202-2320: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C2202%2C2320%2C2}]
+ 2.222043594325228980916360265527780300093e4649L, -2.732869701246338361699515268224049951411e4654L, 3.367233945421922463553518272642397177145e4659L, -4.156377225041273602431272489314020150392e4664L, 5.139764368092890466235162431795350591151e4669L, -6.367329693760865476879589228002216011370e4674L, 7.902356742934106007362514378717026407839e4679L, -9.825176966314431712897976595483070301406e4684L, 1.223792760178593282435724837135946867088e4690L, -1.527068151452750404853140815207477555192e4695L, 1.908935682572268829496101580401263597905e4700L, -2.390593888616966248780378941331847473699e4705L, 2.999171106576893833644521002894489856321e4710L, -3.769440655453736670024798444784356437578e4715L, 4.746047769851891438576002047529258107351e4720L, -5.986405469241447720766576164546767533359e4725L, 7.564466155536872051712519119999711534616e4730L, -9.575641408047918720040356745796976488951e4735L, 1.214322951835035451699619713803395497423e4741L, -1.542682591979864353012093794301924196234e4746L, 1.963334539793192183270983986567556358603e4751L, -2.503148969013901182572118121398034622584e4756L, 3.197076711250102964526567664729089847162e4761L, -4.090653552025822488578293526174572934858e4766L, 5.243302769651520536759521264615159906699e4771L, -6.732697170903775309261288127044088674182e4776L, 8.660529543801770516930589210020128142543e4781L, -1.116015823611149634592870112730519454113e4787L, 1.440675306432920129218036927923030695520e4792L, -1.863078034853256227415397798026969938881e4797L, 2.413595413458810442409656314019115041699e4802L, -3.132317029597258599678590012779717945144e4807L, 4.072246763371584312534474102756137619716e4812L, -5.303577511521827157146305369181950467569e4817L, 6.919417518688636032335131253584331645491e4822L, -9.043473312934241153732087612484569398979e4827L, 1.184037400265044213826044590639924237359e4833L, -1.552956685415800894409743993367334099777e4838L, 2.040404893052952221581694807126473204625e4843L, -2.685565763841580219033402331219206776210e4848L, 3.540927057361929050327811875290025248120e4853L, -4.676912607538885419407656762767991163574e4858L, 6.188165903566760647569323704623433330229e4863L, -8.202087471895029964699042637255411806373e4868L, 1.089045274355389654614196651761310970580e4874L, -1.448524684976553869119447042300206226148e4879L, 1.930028100376784839502387280956424581974e4884L, -2.576074799096023589462128312524664980682e4889L, 3.444369635011990347297134928452972402038e4894L, -4.613354441299253694113609154769978684993e4899L, 6.189834306866879018555349507257537840922e4904L, -8.319470760665157534580593571258276368233e4909L, 1.120124240070996761986102680587384813245e4915L, -1.510740451399746828351090108638980398124e4920L, 2.041108231091323198877509959371257503819e4925L, -2.762447751447012472733302936575873838539e4930L,
+#endif
+ }};
+
+ return bernoulli_data[n];
+}
+
+template <class T>
+inline T unchecked_bernoulli_imp(std::size_t n, const mpl::int_<4>& )
+{
+ //
+ // Special case added for multiprecision types that have no conversion from long long,
+ // there are very few such types, but mpfr_class is one.
+ //
+ static const boost::array<boost::int32_t, 1 + max_bernoulli_b2n<T>::value> numerators =
+ {{
+ boost::int32_t( +1LL),
+ boost::int32_t( +1LL),
+ boost::int32_t( -1LL),
+ boost::int32_t( +1LL),
+ boost::int32_t( -1LL),
+ boost::int32_t( +5LL),
+ boost::int32_t( -691LL),
+ boost::int32_t( +7LL),
+ boost::int32_t( -3617LL),
+ boost::int32_t( +43867LL),
+ boost::int32_t( -174611LL),
+ boost::int32_t( +854513LL),
+ }};
+
+ static const boost::array<boost::int32_t, 1 + max_bernoulli_b2n<T>::value> denominators =
+ {{
+ boost::int32_t( 1LL),
+ boost::int32_t( 6LL),
+ boost::int32_t( 30LL),
+ boost::int32_t( 42LL),
+ boost::int32_t( 30LL),
+ boost::int32_t( 66LL),
+ boost::int32_t( 2730LL),
+ boost::int32_t( 6LL),
+ boost::int32_t( 510LL),
+ boost::int32_t( 798LL),
+ boost::int32_t( 330LL),
+ boost::int32_t( 138LL),
+ }};
+ return T(numerators[n]) / T(denominators[n]);
+}
+
+} // namespace detail
+
+template<class T>
+inline T unchecked_bernoulli_b2n(const std::size_t n)
+{
+ typedef mpl::int_<detail::bernoulli_imp_variant<T>::value> tag_type;
+
+ return detail::unchecked_bernoulli_imp<T>(n, tag_type());
+}
+
+}} // namespaces
+
+#endif // BOOST_MATH_UNCHECKED_BERNOULLI_HPP
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_factorial.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_factorial.hpp
new file mode 100644
index 00000000000..3c23d6e15a9
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/detail/unchecked_factorial.hpp
@@ -0,0 +1,625 @@
+// Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SP_UC_FACTORIALS_HPP
+#define BOOST_MATH_SP_UC_FACTORIALS_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/array.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push) // Temporary until lexical cast fixed.
+#pragma warning(disable: 4127 4701)
+#endif
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+#include <boost/lexical_cast.hpp>
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+
+namespace boost { namespace math
+{
+// Forward declarations:
+template <class T>
+struct max_factorial;
+
+// Definitions:
+template <>
+inline float unchecked_factorial<float>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
+{
+ static const boost::array<float, 35> factorials = {{
+ 1.0F,
+ 1.0F,
+ 2.0F,
+ 6.0F,
+ 24.0F,
+ 120.0F,
+ 720.0F,
+ 5040.0F,
+ 40320.0F,
+ 362880.0F,
+ 3628800.0F,
+ 39916800.0F,
+ 479001600.0F,
+ 6227020800.0F,
+ 87178291200.0F,
+ 1307674368000.0F,
+ 20922789888000.0F,
+ 355687428096000.0F,
+ 6402373705728000.0F,
+ 121645100408832000.0F,
+ 0.243290200817664e19F,
+ 0.5109094217170944e20F,
+ 0.112400072777760768e22F,
+ 0.2585201673888497664e23F,
+ 0.62044840173323943936e24F,
+ 0.15511210043330985984e26F,
+ 0.403291461126605635584e27F,
+ 0.10888869450418352160768e29F,
+ 0.304888344611713860501504e30F,
+ 0.8841761993739701954543616e31F,
+ 0.26525285981219105863630848e33F,
+ 0.822283865417792281772556288e34F,
+ 0.26313083693369353016721801216e36F,
+ 0.868331761881188649551819440128e37F,
+ 0.29523279903960414084761860964352e39F,
+ }};
+
+ return factorials[i];
+}
+
+template <>
+struct max_factorial<float>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 34);
+};
+
+
+template <>
+inline long double unchecked_factorial<long double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
+{
+ static const boost::array<long double, 171> factorials = {{
+ 1L,
+ 1L,
+ 2L,
+ 6L,
+ 24L,
+ 120L,
+ 720L,
+ 5040L,
+ 40320L,
+ 362880.0L,
+ 3628800.0L,
+ 39916800.0L,
+ 479001600.0L,
+ 6227020800.0L,
+ 87178291200.0L,
+ 1307674368000.0L,
+ 20922789888000.0L,
+ 355687428096000.0L,
+ 6402373705728000.0L,
+ 121645100408832000.0L,
+ 0.243290200817664e19L,
+ 0.5109094217170944e20L,
+ 0.112400072777760768e22L,
+ 0.2585201673888497664e23L,
+ 0.62044840173323943936e24L,
+ 0.15511210043330985984e26L,
+ 0.403291461126605635584e27L,
+ 0.10888869450418352160768e29L,
+ 0.304888344611713860501504e30L,
+ 0.8841761993739701954543616e31L,
+ 0.26525285981219105863630848e33L,
+ 0.822283865417792281772556288e34L,
+ 0.26313083693369353016721801216e36L,
+ 0.868331761881188649551819440128e37L,
+ 0.29523279903960414084761860964352e39L,
+ 0.103331479663861449296666513375232e41L,
+ 0.3719933267899012174679994481508352e42L,
+ 0.137637530912263450463159795815809024e44L,
+ 0.5230226174666011117600072241000742912e45L,
+ 0.203978820811974433586402817399028973568e47L,
+ 0.815915283247897734345611269596115894272e48L,
+ 0.3345252661316380710817006205344075166515e50L,
+ 0.1405006117752879898543142606244511569936e52L,
+ 0.6041526306337383563735513206851399750726e53L,
+ 0.265827157478844876804362581101461589032e55L,
+ 0.1196222208654801945619631614956577150644e57L,
+ 0.5502622159812088949850305428800254892962e58L,
+ 0.2586232415111681806429643551536119799692e60L,
+ 0.1241391559253607267086228904737337503852e62L,
+ 0.6082818640342675608722521633212953768876e63L,
+ 0.3041409320171337804361260816606476884438e65L,
+ 0.1551118753287382280224243016469303211063e67L,
+ 0.8065817517094387857166063685640376697529e68L,
+ 0.427488328406002556429801375338939964969e70L,
+ 0.2308436973392413804720927426830275810833e72L,
+ 0.1269640335365827592596510084756651695958e74L,
+ 0.7109985878048634518540456474637249497365e75L,
+ 0.4052691950487721675568060190543232213498e77L,
+ 0.2350561331282878571829474910515074683829e79L,
+ 0.1386831185456898357379390197203894063459e81L,
+ 0.8320987112741390144276341183223364380754e82L,
+ 0.507580213877224798800856812176625227226e84L,
+ 0.3146997326038793752565312235495076408801e86L,
+ 0.1982608315404440064116146708361898137545e88L,
+ 0.1268869321858841641034333893351614808029e90L,
+ 0.8247650592082470666723170306785496252186e91L,
+ 0.5443449390774430640037292402478427526443e93L,
+ 0.3647111091818868528824985909660546442717e95L,
+ 0.2480035542436830599600990418569171581047e97L,
+ 0.1711224524281413113724683388812728390923e99L,
+ 0.1197857166996989179607278372168909873646e101L,
+ 0.8504785885678623175211676442399260102886e102L,
+ 0.6123445837688608686152407038527467274078e104L,
+ 0.4470115461512684340891257138125051110077e106L,
+ 0.3307885441519386412259530282212537821457e108L,
+ 0.2480914081139539809194647711659403366093e110L,
+ 0.188549470166605025498793226086114655823e112L,
+ 0.1451830920282858696340707840863082849837e114L,
+ 0.1132428117820629783145752115873204622873e116L,
+ 0.8946182130782975286851441715398316520698e117L,
+ 0.7156945704626380229481153372318653216558e119L,
+ 0.5797126020747367985879734231578109105412e121L,
+ 0.4753643337012841748421382069894049466438e123L,
+ 0.3945523969720658651189747118012061057144e125L,
+ 0.3314240134565353266999387579130131288001e127L,
+ 0.2817104114380550276949479442260611594801e129L,
+ 0.2422709538367273238176552320344125971528e131L,
+ 0.210775729837952771721360051869938959523e133L,
+ 0.1854826422573984391147968456455462843802e135L,
+ 0.1650795516090846108121691926245361930984e137L,
+ 0.1485715964481761497309522733620825737886e139L,
+ 0.1352001527678402962551665687594951421476e141L,
+ 0.1243841405464130725547532432587355307758e143L,
+ 0.1156772507081641574759205162306240436215e145L,
+ 0.1087366156656743080273652852567866010042e147L,
+ 0.103299784882390592625997020993947270954e149L,
+ 0.9916779348709496892095714015418938011582e150L,
+ 0.9619275968248211985332842594956369871234e152L,
+ 0.942689044888324774562618574305724247381e154L,
+ 0.9332621544394415268169923885626670049072e156L,
+ 0.9332621544394415268169923885626670049072e158L,
+ 0.9425947759838359420851623124482936749562e160L,
+ 0.9614466715035126609268655586972595484554e162L,
+ 0.990290071648618040754671525458177334909e164L,
+ 0.1029901674514562762384858386476504428305e167L,
+ 0.1081396758240290900504101305800329649721e169L,
+ 0.1146280563734708354534347384148349428704e171L,
+ 0.1226520203196137939351751701038733888713e173L,
+ 0.132464181945182897449989183712183259981e175L,
+ 0.1443859583202493582204882102462797533793e177L,
+ 0.1588245541522742940425370312709077287172e179L,
+ 0.1762952551090244663872161047107075788761e181L,
+ 0.1974506857221074023536820372759924883413e183L,
+ 0.2231192748659813646596607021218715118256e185L,
+ 0.2543559733472187557120132004189335234812e187L,
+ 0.2925093693493015690688151804817735520034e189L,
+ 0.339310868445189820119825609358857320324e191L,
+ 0.396993716080872089540195962949863064779e193L,
+ 0.4684525849754290656574312362808384164393e195L,
+ 0.5574585761207605881323431711741977155627e197L,
+ 0.6689502913449127057588118054090372586753e199L,
+ 0.8094298525273443739681622845449350829971e201L,
+ 0.9875044200833601362411579871448208012564e203L,
+ 0.1214630436702532967576624324188129585545e206L,
+ 0.1506141741511140879795014161993280686076e208L,
+ 0.1882677176888926099743767702491600857595e210L,
+ 0.237217324288004688567714730513941708057e212L,
+ 0.3012660018457659544809977077527059692324e214L,
+ 0.3856204823625804217356770659234636406175e216L,
+ 0.4974504222477287440390234150412680963966e218L,
+ 0.6466855489220473672507304395536485253155e220L,
+ 0.8471580690878820510984568758152795681634e222L,
+ 0.1118248651196004307449963076076169029976e225L,
+ 0.1487270706090685728908450891181304809868e227L,
+ 0.1992942746161518876737324194182948445223e229L,
+ 0.269047270731805048359538766214698040105e231L,
+ 0.3659042881952548657689727220519893345429e233L,
+ 0.5012888748274991661034926292112253883237e235L,
+ 0.6917786472619488492228198283114910358867e237L,
+ 0.9615723196941089004197195613529725398826e239L,
+ 0.1346201247571752460587607385894161555836e242L,
+ 0.1898143759076170969428526414110767793728e244L,
+ 0.2695364137888162776588507508037290267094e246L,
+ 0.3854370717180072770521565736493325081944e248L,
+ 0.5550293832739304789551054660550388118e250L,
+ 0.80479260574719919448490292577980627711e252L,
+ 0.1174997204390910823947958271638517164581e255L,
+ 0.1727245890454638911203498659308620231933e257L,
+ 0.2556323917872865588581178015776757943262e259L,
+ 0.380892263763056972698595524350736933546e261L,
+ 0.571338395644585459047893286526105400319e263L,
+ 0.8627209774233240431623188626544191544816e265L,
+ 0.1311335885683452545606724671234717114812e268L,
+ 0.2006343905095682394778288746989117185662e270L,
+ 0.308976961384735088795856467036324046592e272L,
+ 0.4789142901463393876335775239063022722176e274L,
+ 0.7471062926282894447083809372938315446595e276L,
+ 0.1172956879426414428192158071551315525115e279L,
+ 0.1853271869493734796543609753051078529682e281L,
+ 0.2946702272495038326504339507351214862195e283L,
+ 0.4714723635992061322406943211761943779512e285L,
+ 0.7590705053947218729075178570936729485014e287L,
+ 0.1229694218739449434110178928491750176572e290L,
+ 0.2004401576545302577599591653441552787813e292L,
+ 0.3287218585534296227263330311644146572013e294L,
+ 0.5423910666131588774984495014212841843822e296L,
+ 0.9003691705778437366474261723593317460744e298L,
+ 0.1503616514864999040201201707840084015944e301L,
+ 0.2526075744973198387538018869171341146786e303L,
+ 0.4269068009004705274939251888899566538069e305L,
+ 0.7257415615307998967396728211129263114717e307L,
+ }};
+
+ return factorials[i];
+}
+
+template <>
+struct max_factorial<long double>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 170);
+};
+
+#ifdef BOOST_MATH_USE_FLOAT128
+
+template <>
+inline BOOST_MATH_FLOAT128_TYPE unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(unsigned i)
+{
+ static const boost::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials = { {
+ 1,
+ 1,
+ 2,
+ 6,
+ 24,
+ 120,
+ 720,
+ 5040,
+ 40320,
+ 362880.0Q,
+ 3628800.0Q,
+ 39916800.0Q,
+ 479001600.0Q,
+ 6227020800.0Q,
+ 87178291200.0Q,
+ 1307674368000.0Q,
+ 20922789888000.0Q,
+ 355687428096000.0Q,
+ 6402373705728000.0Q,
+ 121645100408832000.0Q,
+ 0.243290200817664e19Q,
+ 0.5109094217170944e20Q,
+ 0.112400072777760768e22Q,
+ 0.2585201673888497664e23Q,
+ 0.62044840173323943936e24Q,
+ 0.15511210043330985984e26Q,
+ 0.403291461126605635584e27Q,
+ 0.10888869450418352160768e29Q,
+ 0.304888344611713860501504e30Q,
+ 0.8841761993739701954543616e31Q,
+ 0.26525285981219105863630848e33Q,
+ 0.822283865417792281772556288e34Q,
+ 0.26313083693369353016721801216e36Q,
+ 0.868331761881188649551819440128e37Q,
+ 0.29523279903960414084761860964352e39Q,
+ 0.103331479663861449296666513375232e41Q,
+ 0.3719933267899012174679994481508352e42Q,
+ 0.137637530912263450463159795815809024e44Q,
+ 0.5230226174666011117600072241000742912e45Q,
+ 0.203978820811974433586402817399028973568e47Q,
+ 0.815915283247897734345611269596115894272e48Q,
+ 0.3345252661316380710817006205344075166515e50Q,
+ 0.1405006117752879898543142606244511569936e52Q,
+ 0.6041526306337383563735513206851399750726e53Q,
+ 0.265827157478844876804362581101461589032e55Q,
+ 0.1196222208654801945619631614956577150644e57Q,
+ 0.5502622159812088949850305428800254892962e58Q,
+ 0.2586232415111681806429643551536119799692e60Q,
+ 0.1241391559253607267086228904737337503852e62Q,
+ 0.6082818640342675608722521633212953768876e63Q,
+ 0.3041409320171337804361260816606476884438e65Q,
+ 0.1551118753287382280224243016469303211063e67Q,
+ 0.8065817517094387857166063685640376697529e68Q,
+ 0.427488328406002556429801375338939964969e70Q,
+ 0.2308436973392413804720927426830275810833e72Q,
+ 0.1269640335365827592596510084756651695958e74Q,
+ 0.7109985878048634518540456474637249497365e75Q,
+ 0.4052691950487721675568060190543232213498e77Q,
+ 0.2350561331282878571829474910515074683829e79Q,
+ 0.1386831185456898357379390197203894063459e81Q,
+ 0.8320987112741390144276341183223364380754e82Q,
+ 0.507580213877224798800856812176625227226e84Q,
+ 0.3146997326038793752565312235495076408801e86Q,
+ 0.1982608315404440064116146708361898137545e88Q,
+ 0.1268869321858841641034333893351614808029e90Q,
+ 0.8247650592082470666723170306785496252186e91Q,
+ 0.5443449390774430640037292402478427526443e93Q,
+ 0.3647111091818868528824985909660546442717e95Q,
+ 0.2480035542436830599600990418569171581047e97Q,
+ 0.1711224524281413113724683388812728390923e99Q,
+ 0.1197857166996989179607278372168909873646e101Q,
+ 0.8504785885678623175211676442399260102886e102Q,
+ 0.6123445837688608686152407038527467274078e104Q,
+ 0.4470115461512684340891257138125051110077e106Q,
+ 0.3307885441519386412259530282212537821457e108Q,
+ 0.2480914081139539809194647711659403366093e110Q,
+ 0.188549470166605025498793226086114655823e112Q,
+ 0.1451830920282858696340707840863082849837e114Q,
+ 0.1132428117820629783145752115873204622873e116Q,
+ 0.8946182130782975286851441715398316520698e117Q,
+ 0.7156945704626380229481153372318653216558e119Q,
+ 0.5797126020747367985879734231578109105412e121Q,
+ 0.4753643337012841748421382069894049466438e123Q,
+ 0.3945523969720658651189747118012061057144e125Q,
+ 0.3314240134565353266999387579130131288001e127Q,
+ 0.2817104114380550276949479442260611594801e129Q,
+ 0.2422709538367273238176552320344125971528e131Q,
+ 0.210775729837952771721360051869938959523e133Q,
+ 0.1854826422573984391147968456455462843802e135Q,
+ 0.1650795516090846108121691926245361930984e137Q,
+ 0.1485715964481761497309522733620825737886e139Q,
+ 0.1352001527678402962551665687594951421476e141Q,
+ 0.1243841405464130725547532432587355307758e143Q,
+ 0.1156772507081641574759205162306240436215e145Q,
+ 0.1087366156656743080273652852567866010042e147Q,
+ 0.103299784882390592625997020993947270954e149Q,
+ 0.9916779348709496892095714015418938011582e150Q,
+ 0.9619275968248211985332842594956369871234e152Q,
+ 0.942689044888324774562618574305724247381e154Q,
+ 0.9332621544394415268169923885626670049072e156Q,
+ 0.9332621544394415268169923885626670049072e158Q,
+ 0.9425947759838359420851623124482936749562e160Q,
+ 0.9614466715035126609268655586972595484554e162Q,
+ 0.990290071648618040754671525458177334909e164Q,
+ 0.1029901674514562762384858386476504428305e167Q,
+ 0.1081396758240290900504101305800329649721e169Q,
+ 0.1146280563734708354534347384148349428704e171Q,
+ 0.1226520203196137939351751701038733888713e173Q,
+ 0.132464181945182897449989183712183259981e175Q,
+ 0.1443859583202493582204882102462797533793e177Q,
+ 0.1588245541522742940425370312709077287172e179Q,
+ 0.1762952551090244663872161047107075788761e181Q,
+ 0.1974506857221074023536820372759924883413e183Q,
+ 0.2231192748659813646596607021218715118256e185Q,
+ 0.2543559733472187557120132004189335234812e187Q,
+ 0.2925093693493015690688151804817735520034e189Q,
+ 0.339310868445189820119825609358857320324e191Q,
+ 0.396993716080872089540195962949863064779e193Q,
+ 0.4684525849754290656574312362808384164393e195Q,
+ 0.5574585761207605881323431711741977155627e197Q,
+ 0.6689502913449127057588118054090372586753e199Q,
+ 0.8094298525273443739681622845449350829971e201Q,
+ 0.9875044200833601362411579871448208012564e203Q,
+ 0.1214630436702532967576624324188129585545e206Q,
+ 0.1506141741511140879795014161993280686076e208Q,
+ 0.1882677176888926099743767702491600857595e210Q,
+ 0.237217324288004688567714730513941708057e212Q,
+ 0.3012660018457659544809977077527059692324e214Q,
+ 0.3856204823625804217356770659234636406175e216Q,
+ 0.4974504222477287440390234150412680963966e218Q,
+ 0.6466855489220473672507304395536485253155e220Q,
+ 0.8471580690878820510984568758152795681634e222Q,
+ 0.1118248651196004307449963076076169029976e225Q,
+ 0.1487270706090685728908450891181304809868e227Q,
+ 0.1992942746161518876737324194182948445223e229Q,
+ 0.269047270731805048359538766214698040105e231Q,
+ 0.3659042881952548657689727220519893345429e233Q,
+ 0.5012888748274991661034926292112253883237e235Q,
+ 0.6917786472619488492228198283114910358867e237Q,
+ 0.9615723196941089004197195613529725398826e239Q,
+ 0.1346201247571752460587607385894161555836e242Q,
+ 0.1898143759076170969428526414110767793728e244Q,
+ 0.2695364137888162776588507508037290267094e246Q,
+ 0.3854370717180072770521565736493325081944e248Q,
+ 0.5550293832739304789551054660550388118e250Q,
+ 0.80479260574719919448490292577980627711e252Q,
+ 0.1174997204390910823947958271638517164581e255Q,
+ 0.1727245890454638911203498659308620231933e257Q,
+ 0.2556323917872865588581178015776757943262e259Q,
+ 0.380892263763056972698595524350736933546e261Q,
+ 0.571338395644585459047893286526105400319e263Q,
+ 0.8627209774233240431623188626544191544816e265Q,
+ 0.1311335885683452545606724671234717114812e268Q,
+ 0.2006343905095682394778288746989117185662e270Q,
+ 0.308976961384735088795856467036324046592e272Q,
+ 0.4789142901463393876335775239063022722176e274Q,
+ 0.7471062926282894447083809372938315446595e276Q,
+ 0.1172956879426414428192158071551315525115e279Q,
+ 0.1853271869493734796543609753051078529682e281Q,
+ 0.2946702272495038326504339507351214862195e283Q,
+ 0.4714723635992061322406943211761943779512e285Q,
+ 0.7590705053947218729075178570936729485014e287Q,
+ 0.1229694218739449434110178928491750176572e290Q,
+ 0.2004401576545302577599591653441552787813e292Q,
+ 0.3287218585534296227263330311644146572013e294Q,
+ 0.5423910666131588774984495014212841843822e296Q,
+ 0.9003691705778437366474261723593317460744e298Q,
+ 0.1503616514864999040201201707840084015944e301Q,
+ 0.2526075744973198387538018869171341146786e303Q,
+ 0.4269068009004705274939251888899566538069e305Q,
+ 0.7257415615307998967396728211129263114717e307Q,
+ } };
+
+ return factorials[i];
+}
+
+template <>
+struct max_factorial<BOOST_MATH_FLOAT128_TYPE>
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 170);
+};
+
+#endif
+
+template <>
+inline double unchecked_factorial<double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
+{
+ return static_cast<double>(boost::math::unchecked_factorial<long double>(i));
+}
+
+template <>
+struct max_factorial<double>
+{
+ BOOST_STATIC_CONSTANT(unsigned,
+ value = ::boost::math::max_factorial<long double>::value);
+};
+
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+
+template <class T>
+inline T unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
+{
+ BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+ // factorial<unsigned int>(n) is not implemented
+ // because it would overflow integral type T for too small n
+ // to be useful. Use instead a floating-point type,
+ // and convert to an unsigned type if essential, for example:
+ // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
+ // See factorial documentation for more detail.
+
+ static const boost::array<T, 101> factorials = {{
+ boost::lexical_cast<T>("1"),
+ boost::lexical_cast<T>("1"),
+ boost::lexical_cast<T>("2"),
+ boost::lexical_cast<T>("6"),
+ boost::lexical_cast<T>("24"),
+ boost::lexical_cast<T>("120"),
+ boost::lexical_cast<T>("720"),
+ boost::lexical_cast<T>("5040"),
+ boost::lexical_cast<T>("40320"),
+ boost::lexical_cast<T>("362880"),
+ boost::lexical_cast<T>("3628800"),
+ boost::lexical_cast<T>("39916800"),
+ boost::lexical_cast<T>("479001600"),
+ boost::lexical_cast<T>("6227020800"),
+ boost::lexical_cast<T>("87178291200"),
+ boost::lexical_cast<T>("1307674368000"),
+ boost::lexical_cast<T>("20922789888000"),
+ boost::lexical_cast<T>("355687428096000"),
+ boost::lexical_cast<T>("6402373705728000"),
+ boost::lexical_cast<T>("121645100408832000"),
+ boost::lexical_cast<T>("2432902008176640000"),
+ boost::lexical_cast<T>("51090942171709440000"),
+ boost::lexical_cast<T>("1124000727777607680000"),
+ boost::lexical_cast<T>("25852016738884976640000"),
+ boost::lexical_cast<T>("620448401733239439360000"),
+ boost::lexical_cast<T>("15511210043330985984000000"),
+ boost::lexical_cast<T>("403291461126605635584000000"),
+ boost::lexical_cast<T>("10888869450418352160768000000"),
+ boost::lexical_cast<T>("304888344611713860501504000000"),
+ boost::lexical_cast<T>("8841761993739701954543616000000"),
+ boost::lexical_cast<T>("265252859812191058636308480000000"),
+ boost::lexical_cast<T>("8222838654177922817725562880000000"),
+ boost::lexical_cast<T>("263130836933693530167218012160000000"),
+ boost::lexical_cast<T>("8683317618811886495518194401280000000"),
+ boost::lexical_cast<T>("295232799039604140847618609643520000000"),
+ boost::lexical_cast<T>("10333147966386144929666651337523200000000"),
+ boost::lexical_cast<T>("371993326789901217467999448150835200000000"),
+ boost::lexical_cast<T>("13763753091226345046315979581580902400000000"),
+ boost::lexical_cast<T>("523022617466601111760007224100074291200000000"),
+ boost::lexical_cast<T>("20397882081197443358640281739902897356800000000"),
+ boost::lexical_cast<T>("815915283247897734345611269596115894272000000000"),
+ boost::lexical_cast<T>("33452526613163807108170062053440751665152000000000"),
+ boost::lexical_cast<T>("1405006117752879898543142606244511569936384000000000"),
+ boost::lexical_cast<T>("60415263063373835637355132068513997507264512000000000"),
+ boost::lexical_cast<T>("2658271574788448768043625811014615890319638528000000000"),
+ boost::lexical_cast<T>("119622220865480194561963161495657715064383733760000000000"),
+ boost::lexical_cast<T>("5502622159812088949850305428800254892961651752960000000000"),
+ boost::lexical_cast<T>("258623241511168180642964355153611979969197632389120000000000"),
+ boost::lexical_cast<T>("12413915592536072670862289047373375038521486354677760000000000"),
+ boost::lexical_cast<T>("608281864034267560872252163321295376887552831379210240000000000"),
+ boost::lexical_cast<T>("30414093201713378043612608166064768844377641568960512000000000000"),
+ boost::lexical_cast<T>("1551118753287382280224243016469303211063259720016986112000000000000"),
+ boost::lexical_cast<T>("80658175170943878571660636856403766975289505440883277824000000000000"),
+ boost::lexical_cast<T>("4274883284060025564298013753389399649690343788366813724672000000000000"),
+ boost::lexical_cast<T>("230843697339241380472092742683027581083278564571807941132288000000000000"),
+ boost::lexical_cast<T>("12696403353658275925965100847566516959580321051449436762275840000000000000"),
+ boost::lexical_cast<T>("710998587804863451854045647463724949736497978881168458687447040000000000000"),
+ boost::lexical_cast<T>("40526919504877216755680601905432322134980384796226602145184481280000000000000"),
+ boost::lexical_cast<T>("2350561331282878571829474910515074683828862318181142924420699914240000000000000"),
+ boost::lexical_cast<T>("138683118545689835737939019720389406345902876772687432540821294940160000000000000"),
+ boost::lexical_cast<T>("8320987112741390144276341183223364380754172606361245952449277696409600000000000000"),
+ boost::lexical_cast<T>("507580213877224798800856812176625227226004528988036003099405939480985600000000000000"),
+ boost::lexical_cast<T>("31469973260387937525653122354950764088012280797258232192163168247821107200000000000000"),
+ boost::lexical_cast<T>("1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000"),
+ boost::lexical_cast<T>("126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000"),
+ boost::lexical_cast<T>("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000"),
+ boost::lexical_cast<T>("544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000"),
+ boost::lexical_cast<T>("36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000"),
+ boost::lexical_cast<T>("2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000"),
+ boost::lexical_cast<T>("171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000"),
+ boost::lexical_cast<T>("11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000"),
+ boost::lexical_cast<T>("850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000"),
+ boost::lexical_cast<T>("61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000"),
+ boost::lexical_cast<T>("4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000"),
+ boost::lexical_cast<T>("330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000"),
+ boost::lexical_cast<T>("24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000"),
+ boost::lexical_cast<T>("1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000"),
+ boost::lexical_cast<T>("145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000"),
+ boost::lexical_cast<T>("11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000"),
+ boost::lexical_cast<T>("894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000"),
+ boost::lexical_cast<T>("71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000"),
+ boost::lexical_cast<T>("5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000"),
+ boost::lexical_cast<T>("475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000"),
+ boost::lexical_cast<T>("39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000"),
+ boost::lexical_cast<T>("3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000"),
+ boost::lexical_cast<T>("281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000"),
+ boost::lexical_cast<T>("24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000"),
+ boost::lexical_cast<T>("2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000"),
+ boost::lexical_cast<T>("185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000"),
+ boost::lexical_cast<T>("16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000"),
+ boost::lexical_cast<T>("1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000"),
+ boost::lexical_cast<T>("135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000"),
+ boost::lexical_cast<T>("12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000"),
+ boost::lexical_cast<T>("1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000"),
+ boost::lexical_cast<T>("108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000"),
+ boost::lexical_cast<T>("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000"),
+ boost::lexical_cast<T>("991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000"),
+ boost::lexical_cast<T>("96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000"),
+ boost::lexical_cast<T>("9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000"),
+ boost::lexical_cast<T>("933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000"),
+ boost::lexical_cast<T>("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"),
+ }};
+
+ return factorials[i];
+}
+
+template <class T>
+struct max_factorial
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 100);
+};
+
+#else // BOOST_MATH_NO_LEXICAL_CAST
+
+template <class T>
+inline T unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
+{
+ return 1;
+}
+
+template <class T>
+struct max_factorial
+{
+ BOOST_STATIC_CONSTANT(unsigned, value = 0);
+};
+
+#endif
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+template <class T>
+const unsigned max_factorial<T>::value;
+#endif
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_UC_FACTORIALS_HPP
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/erf.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/erf.hpp
new file mode 100644
index 00000000000..f7f75b0bc7a
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/erf.hpp
@@ -0,0 +1,1155 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_ERF_HPP
+#define BOOST_MATH_SPECIAL_ERF_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/big_constant.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+
+//
+// Asymptotic series for large z:
+//
+template <class T>
+struct erf_asympt_series_t
+{
+ erf_asympt_series_t(T z) : xx(2 * -z * z), tk(1)
+ {
+ BOOST_MATH_STD_USING
+ result = -exp(-z * z) / sqrt(boost::math::constants::pi<T>());
+ result /= z;
+ }
+
+ typedef T result_type;
+
+ T operator()()
+ {
+ BOOST_MATH_STD_USING
+ T r = result;
+ result *= tk / xx;
+ tk += 2;
+ if( fabs(r) < fabs(result))
+ result = 0;
+ return r;
+ }
+private:
+ T result;
+ T xx;
+ int tk;
+};
+//
+// How large z has to be in order to ensure that the series converges:
+//
+template <class T>
+inline float erf_asymptotic_limit_N(const T&)
+{
+ return (std::numeric_limits<float>::max)();
+}
+inline float erf_asymptotic_limit_N(const mpl::int_<24>&)
+{
+ return 2.8F;
+}
+inline float erf_asymptotic_limit_N(const mpl::int_<53>&)
+{
+ return 4.3F;
+}
+inline float erf_asymptotic_limit_N(const mpl::int_<64>&)
+{
+ return 4.8F;
+}
+inline float erf_asymptotic_limit_N(const mpl::int_<106>&)
+{
+ return 6.5F;
+}
+inline float erf_asymptotic_limit_N(const mpl::int_<113>&)
+{
+ return 6.8F;
+}
+
+template <class T, class Policy>
+inline T erf_asymptotic_limit()
+{
+ typedef typename policies::precision<T, Policy>::type precision_type;
+ typedef typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<24> >,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<0> >,
+ mpl::int_<0>,
+ mpl::int_<24>
+ >::type,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<53> >,
+ mpl::int_<53>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<106> >,
+ mpl::int_<106>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<113> >,
+ mpl::int_<113>,
+ mpl::int_<0>
+ >::type
+ >::type
+ >::type
+ >::type
+ >::type tag_type;
+ return erf_asymptotic_limit_N(tag_type());
+}
+
+template <class T, class Policy, class Tag>
+T erf_imp(T z, bool invert, const Policy& pol, const Tag& t)
+{
+ BOOST_MATH_STD_USING
+
+ BOOST_MATH_INSTRUMENT_CODE("Generic erf_imp called");
+
+ if(z < 0)
+ {
+ if(!invert)
+ return -erf_imp(T(-z), invert, pol, t);
+ else
+ return 1 + erf_imp(T(-z), false, pol, t);
+ }
+
+ T result;
+
+ if(!invert && (z > detail::erf_asymptotic_limit<T, Policy>()))
+ {
+ detail::erf_asympt_series_t<T> s(z);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+ result = boost::math::tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, 1);
+ policies::check_series_iterations<T>("boost::math::erf<%1%>(%1%, %1%)", max_iter, pol);
+ }
+ else
+ {
+ T x = z * z;
+ if(x < 0.6)
+ {
+ // Compute P:
+ result = z * exp(-x);
+ result /= sqrt(boost::math::constants::pi<T>());
+ if(result != 0)
+ result *= 2 * detail::lower_gamma_series(T(0.5f), x, pol);
+ }
+ else if(x < 1.1f)
+ {
+ // Compute Q:
+ invert = !invert;
+ result = tgamma_small_upper_part(T(0.5f), x, pol);
+ result /= sqrt(boost::math::constants::pi<T>());
+ }
+ else
+ {
+ // Compute Q:
+ invert = !invert;
+ result = z * exp(-x);
+ result /= sqrt(boost::math::constants::pi<T>());
+ result *= upper_gamma_fraction(T(0.5f), x, policies::get_epsilon<T, Policy>());
+ }
+ }
+ if(invert)
+ result = 1 - result;
+ return result;
+}
+
+template <class T, class Policy>
+T erf_imp(T z, bool invert, const Policy& pol, const mpl::int_<53>& t)
+{
+ BOOST_MATH_STD_USING
+
+ BOOST_MATH_INSTRUMENT_CODE("53-bit precision erf_imp called");
+
+ if(z < 0)
+ {
+ if(!invert)
+ return -erf_imp(T(-z), invert, pol, t);
+ else if(z < -0.5)
+ return 2 - erf_imp(T(-z), invert, pol, t);
+ else
+ return 1 + erf_imp(T(-z), false, pol, t);
+ }
+
+ T result;
+
+ //
+ // Big bunch of selection statements now to pick
+ // which implementation to use,
+ // try to put most likely options first:
+ //
+ if(z < 0.5)
+ {
+ //
+ // We're going to calculate erf:
+ //
+ if(z < 1e-10)
+ {
+ if(z == 0)
+ {
+ result = T(0);
+ }
+ else
+ {
+ static const T c = BOOST_MATH_BIG_CONSTANT(T, 53, 0.003379167095512573896158903121545171688);
+ result = static_cast<T>(z * 1.125f + z * c);
+ }
+ }
+ else
+ {
+ // Maximum Deviation Found: 1.561e-17
+ // Expected Error Term: 1.561e-17
+ // Maximum Relative Change in Control Points: 1.155e-04
+ // Max Error found at double precision = 2.961182e-17
+
+ static const T Y = 1.044948577880859375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0834305892146531832907),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.338165134459360935041),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.0509990735146777432841),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.00772758345802133288487),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.000322780120964605683831),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.455004033050794024546),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0875222600142252549554),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00858571925074406212772),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.000370900071787748000569),
+ };
+ T zz = z * z;
+ result = z * (Y + tools::evaluate_polynomial(P, zz) / tools::evaluate_polynomial(Q, zz));
+ }
+ }
+ else if(invert ? (z < 28) : (z < 5.8f))
+ {
+ //
+ // We'll be calculating erfc:
+ //
+ invert = !invert;
+ if(z < 1.5f)
+ {
+ // Maximum Deviation Found: 3.702e-17
+ // Expected Error Term: 3.702e-17
+ // Maximum Relative Change in Control Points: 2.845e-04
+ // Max Error found at double precision = 4.841816e-17
+ static const T Y = 0.405935764312744140625f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.098090592216281240205),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.178114665841120341155),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.191003695796775433986),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0888900368967884466578),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0195049001251218801359),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00180424538297014223957),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.84759070983002217845),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.42628004845511324508),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.578052804889902404909),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.12385097467900864233),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0113385233577001411017),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.337511472483094676155e-5),
+ };
+ BOOST_MATH_INSTRUMENT_VARIABLE(Y);
+ BOOST_MATH_INSTRUMENT_VARIABLE(P[0]);
+ BOOST_MATH_INSTRUMENT_VARIABLE(Q[0]);
+ BOOST_MATH_INSTRUMENT_VARIABLE(z);
+ result = Y + tools::evaluate_polynomial(P, T(z - 0.5)) / tools::evaluate_polynomial(Q, T(z - 0.5));
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ result *= exp(-z * z) / z;
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if(z < 2.5f)
+ {
+ // Max Error found at double precision = 6.599585e-18
+ // Maximum Deviation Found: 3.909e-18
+ // Expected Error Term: 3.909e-18
+ // Maximum Relative Change in Control Points: 9.886e-05
+ static const T Y = 0.50672817230224609375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.0243500476207698441272),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0386540375035707201728),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.04394818964209516296),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175679436311802092299),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00323962406290842133584),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.000235839115596880717416),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.53991494948552447182),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.982403709157920235114),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.325732924782444448493),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0563921837420478160373),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00410369723978904575884),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 1.5)) / tools::evaluate_polynomial(Q, T(z - 1.5));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 4.5f)
+ {
+ // Maximum Deviation Found: 1.512e-17
+ // Expected Error Term: 1.512e-17
+ // Maximum Relative Change in Control Points: 2.222e-04
+ // Max Error found at double precision = 2.062515e-17
+ static const T Y = 0.5405750274658203125f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00295276716530971662634),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0137384425896355332126),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00840807615555585383007),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00212825620914618649141),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.000250269961544794627958),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.113212406648847561139e-4),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.04217814166938418171),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.442597659481563127003),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0958492726301061423444),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0105982906484876531489),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.000479411269521714493907),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 3.5)) / tools::evaluate_polynomial(Q, T(z - 3.5));
+ result *= exp(-z * z) / z;
+ }
+ else
+ {
+ // Max Error found at double precision = 2.997958e-17
+ // Maximum Deviation Found: 2.860e-17
+ // Expected Error Term: 2.859e-17
+ // Maximum Relative Change in Control Points: 1.357e-05
+ static const T Y = 0.5579090118408203125f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.00628057170626964891937),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175389834052493308818),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.212652252872804219852),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -0.687717681153649930619),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -2.5518551727311523996),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -3.22729451764143718517),
+ BOOST_MATH_BIG_CONSTANT(T, 53, -2.8175401114513378771),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 2.79257750980575282228),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 11.0567237927800161565),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 15.930646027911794143),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 22.9367376522880577224),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 13.5064170191802889145),
+ BOOST_MATH_BIG_CONSTANT(T, 53, 5.48409182238641741584),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z));
+ result *= exp(-z * z) / z;
+ }
+ }
+ else
+ {
+ //
+ // Any value of z larger than 28 will underflow to zero:
+ //
+ result = 0;
+ invert = !invert;
+ }
+
+ if(invert)
+ {
+ result = 1 - result;
+ }
+
+ return result;
+} // template <class T, class Lanczos>T erf_imp(T z, bool invert, const Lanczos& l, const mpl::int_<53>& t)
+
+
+template <class T, class Policy>
+T erf_imp(T z, bool invert, const Policy& pol, const mpl::int_<64>& t)
+{
+ BOOST_MATH_STD_USING
+
+ BOOST_MATH_INSTRUMENT_CODE("64-bit precision erf_imp called");
+
+ if(z < 0)
+ {
+ if(!invert)
+ return -erf_imp(T(-z), invert, pol, t);
+ else if(z < -0.5)
+ return 2 - erf_imp(T(-z), invert, pol, t);
+ else
+ return 1 + erf_imp(T(-z), false, pol, t);
+ }
+
+ T result;
+
+ //
+ // Big bunch of selection statements now to pick which
+ // implementation to use, try to put most likely options
+ // first:
+ //
+ if(z < 0.5)
+ {
+ //
+ // We're going to calculate erf:
+ //
+ if(z == 0)
+ {
+ result = 0;
+ }
+ else if(z < 1e-10)
+ {
+ static const T c = BOOST_MATH_BIG_CONSTANT(T, 64, 0.003379167095512573896158903121545171688);
+ result = z * 1.125 + z * c;
+ }
+ else
+ {
+ // Max Error found at long double precision = 1.623299e-20
+ // Maximum Deviation Found: 4.326e-22
+ // Expected Error Term: -4.326e-22
+ // Maximum Relative Change in Control Points: 1.474e-04
+ static const T Y = 1.044948577880859375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0834305892146531988966),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.338097283075565413695),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0509602734406067204596),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.00904906346158537794396),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.000489468651464798669181),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.200305626366151877759e-4),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.455817300515875172439),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0916537354356241792007),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0102722652675910031202),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000650511752687851548735),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.189532519105655496778e-4),
+ };
+ result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z)));
+ }
+ }
+ else if(invert ? (z < 110) : (z < 6.4f))
+ {
+ //
+ // We'll be calculating erfc:
+ //
+ invert = !invert;
+ if(z < 1.5)
+ {
+ // Max Error found at long double precision = 3.239590e-20
+ // Maximum Deviation Found: 2.241e-20
+ // Expected Error Term: -2.241e-20
+ // Maximum Relative Change in Control Points: 5.110e-03
+ static const T Y = 0.405935764312744140625f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.0980905922162812031672),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.159989089922969141329),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.222359821619935712378),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.127303921703577362312),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0384057530342762400273),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00628431160851156719325),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000441266654514391746428),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.266689068336295642561e-7),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 2.03237474985469469291),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.78355454954969405222),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.867940326293760578231),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.248025606990021698392),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0396649631833002269861),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00279220237309449026796),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 2.5)
+ {
+ // Max Error found at long double precision = 3.686211e-21
+ // Maximum Deviation Found: 1.495e-21
+ // Expected Error Term: -1.494e-21
+ // Maximum Relative Change in Control Points: 1.793e-04
+ static const T Y = 0.50672817230224609375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.024350047620769840217),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0343522687935671451309),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0505420824305544949541),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0257479325917757388209),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00669349844190354356118),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00090807914416099524444),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.515917266698050027934e-4),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.71657861671930336344),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.26409634824280366218),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.512371437838969015941),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.120902623051120950935),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0158027197831887485261),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.000897871370778031611439),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 4.5)
+ {
+ // Maximum Deviation Found: 1.107e-20
+ // Expected Error Term: -1.106e-20
+ // Maximum Relative Change in Control Points: 1.709e-04
+ // Max Error found at long double precision = 1.446908e-20
+ static const T Y = 0.5405750274658203125f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0029527671653097284033),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0141853245895495604051),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0104959584626432293901),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00343963795976100077626),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00059065441194877637899),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.523435380636174008685e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.189896043050331257262e-5),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.19352160185285642574),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.603256964363454392857),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.165411142458540585835),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0259729870946203166468),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00221657568292893699158),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.804149464190309799804e-4),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 3.5f)) / tools::evaluate_polynomial(Q, T(z - 3.5f));
+ result *= exp(-z * z) / z;
+ }
+ else
+ {
+ // Max Error found at long double precision = 7.961166e-21
+ // Maximum Deviation Found: 6.677e-21
+ // Expected Error Term: 6.676e-21
+ // Maximum Relative Change in Control Points: 2.319e-05
+ static const T Y = 0.55825519561767578125f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00593438793008050214106),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0280666231009089713937),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.141597835204583050043),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.978088201154300548842),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -5.47351527796012049443),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -13.8677304660245326627),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -27.1274948720539821722),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -29.2545152747009461519),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -16.8865774499799676937),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 4.72948911186645394541),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 23.6750543147695749212),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 60.0021517335693186785),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 131.766251645149522868),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 178.167924971283482513),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 182.499390505915222699),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 104.365251479578577989),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 30.8365511891224291717),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z));
+ result *= exp(-z * z) / z;
+ }
+ }
+ else
+ {
+ //
+ // Any value of z larger than 110 will underflow to zero:
+ //
+ result = 0;
+ invert = !invert;
+ }
+
+ if(invert)
+ {
+ result = 1 - result;
+ }
+
+ return result;
+} // template <class T, class Lanczos>T erf_imp(T z, bool invert, const Lanczos& l, const mpl::int_<64>& t)
+
+
+template <class T, class Policy>
+T erf_imp(T z, bool invert, const Policy& pol, const mpl::int_<113>& t)
+{
+ BOOST_MATH_STD_USING
+
+ BOOST_MATH_INSTRUMENT_CODE("113-bit precision erf_imp called");
+
+ if(z < 0)
+ {
+ if(!invert)
+ return -erf_imp(T(-z), invert, pol, t);
+ else if(z < -0.5)
+ return 2 - erf_imp(T(-z), invert, pol, t);
+ else
+ return 1 + erf_imp(T(-z), false, pol, t);
+ }
+
+ T result;
+
+ //
+ // Big bunch of selection statements now to pick which
+ // implementation to use, try to put most likely options
+ // first:
+ //
+ if(z < 0.5)
+ {
+ //
+ // We're going to calculate erf:
+ //
+ if(z == 0)
+ {
+ result = 0;
+ }
+ else if(z < 1e-20)
+ {
+ static const T c = BOOST_MATH_BIG_CONSTANT(T, 113, 0.003379167095512573896158903121545171688);
+ result = z * 1.125 + z * c;
+ }
+ else
+ {
+ // Max Error found at long double precision = 2.342380e-35
+ // Maximum Deviation Found: 6.124e-36
+ // Expected Error Term: -6.124e-36
+ // Maximum Relative Change in Control Points: 3.492e-10
+ static const T Y = 1.0841522216796875f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0442269454158250738961589031215451778),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.35549265736002144875335323556961233),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0582179564566667896225454670863270393),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0112694696904802304229950538453123925),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.000805730648981801146251825329609079099),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.566304966591936566229702842075966273e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.169655010425186987820201021510002265e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.344448249920445916714548295433198544e-7),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.466542092785657604666906909196052522),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.100005087012526447295176964142107611),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0128341535890117646540050072234142603),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00107150448466867929159660677016658186),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.586168368028999183607733369248338474e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.196230608502104324965623171516808796e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.313388521582925207734229967907890146e-7),
+ };
+ result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z)));
+ }
+ }
+ else if(invert ? (z < 110) : (z < 8.65f))
+ {
+ //
+ // We'll be calculating erfc:
+ //
+ invert = !invert;
+ if(z < 1)
+ {
+ // Max Error found at long double precision = 3.246278e-35
+ // Maximum Deviation Found: 1.388e-35
+ // Expected Error Term: 1.387e-35
+ // Maximum Relative Change in Control Points: 6.127e-05
+ static const T Y = 0.371877193450927734375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0640320213544647969396032886581290455),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.200769874440155895637857443946706731),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.378447199873537170666487408805779826),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.30521399466465939450398642044975127),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.146890026406815277906781824723458196),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0464837937749539978247589252732769567),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00987895759019540115099100165904822903),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00137507575429025512038051025154301132),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0001144764551085935580772512359680516),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.436544865032836914773944382339900079e-5),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.47651182872457465043733800302427977),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.78706486002517996428836400245547955),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.87295924621659627926365005293130693),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.829375825174365625428280908787261065),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.251334771307848291593780143950311514),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0522110268876176186719436765734722473),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00718332151250963182233267040106902368),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000595279058621482041084986219276392459),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.226988669466501655990637599399326874e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.270666232259029102353426738909226413e-10),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 1.5)
+ {
+ // Max Error found at long double precision = 2.215785e-35
+ // Maximum Deviation Found: 1.539e-35
+ // Expected Error Term: 1.538e-35
+ // Maximum Relative Change in Control Points: 6.104e-05
+ static const T Y = 0.45658016204833984375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0289965858925328393392496555094848345),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0868181194868601184627743162571779226),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.169373435121178901746317404936356745),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.13350446515949251201104889028133486),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0617447837290183627136837688446313313),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0185618495228251406703152962489700468),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00371949406491883508764162050169531013),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000485121708792921297742105775823900772),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.376494706741453489892108068231400061e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.133166058052466262415271732172490045e-5),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.32970330146503867261275580968135126),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.46325715420422771961250513514928746),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.55307882560757679068505047390857842),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.644274289865972449441174485441409076),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.182609091063258208068606847453955649),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0354171651271241474946129665801606795),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00454060370165285246451879969534083997),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000349871943711566546821198612518656486),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.123749319840299552925421880481085392e-4),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 1.0f)) / tools::evaluate_polynomial(Q, T(z - 1.0f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 2.25)
+ {
+ // Maximum Deviation Found: 1.418e-35
+ // Expected Error Term: 1.418e-35
+ // Maximum Relative Change in Control Points: 1.316e-04
+ // Max Error found at long double precision = 1.998462e-35
+ static const T Y = 0.50250148773193359375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0201233630504573402185161184151016606),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0331864357574860196516686996302305002),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0716562720864787193337475444413405461),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0545835322082103985114927569724880658),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0236692635189696678976549720784989593),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00656970902163248872837262539337601845),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00120282643299089441390490459256235021),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000142123229065182650020762792081622986),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.991531438367015135346716277792989347e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.312857043762117596999398067153076051e-6),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.13506082409097783827103424943508554),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2.06399257267556230937723190496806215),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.18678481279932541314830499880691109),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.447733186643051752513538142316799562),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.11505680005657879437196953047542148),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.020163993632192726170219663831914034),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00232708971840141388847728782209730585),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000160733201627963528519726484608224112),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.507158721790721802724402992033269266e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.18647774409821470950544212696270639e-12),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f));
+ result *= exp(-z * z) / z;
+ }
+ else if (z < 3)
+ {
+ // Maximum Deviation Found: 3.575e-36
+ // Expected Error Term: 3.575e-36
+ // Maximum Relative Change in Control Points: 7.103e-05
+ // Max Error found at long double precision = 5.794737e-36
+ static const T Y = 0.52896785736083984375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.00902152521745813634562524098263360074),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0145207142776691539346923710537580927),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0301681239582193983824211995978678571),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0215548540823305814379020678660434461),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00864683476267958365678294164340749949),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00219693096885585491739823283511049902),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000364961639163319762492184502159894371),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.388174251026723752769264051548703059e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.241918026931789436000532513553594321e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.676586625472423508158937481943649258e-7),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.93669171363907292305550231764920001),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.69468476144051356810672506101377494),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.880023580986436640372794392579985511),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.299099106711315090710836273697708402),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0690593962363545715997445583603382337),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0108427016361318921960863149875360222),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00111747247208044534520499324234317695),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.686843205749767250666787987163701209e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.192093541425429248675532015101904262e-5),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 2.25f)) / tools::evaluate_polynomial(Q, T(z - 2.25f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 3.5)
+ {
+ // Maximum Deviation Found: 8.126e-37
+ // Expected Error Term: -8.126e-37
+ // Maximum Relative Change in Control Points: 1.363e-04
+ // Max Error found at long double precision = 1.747062e-36
+ static const T Y = 0.54037380218505859375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033703486408887424921155540591370375),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0104948043110005245215286678898115811),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0148530118504000311502310457390417795),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00816693029245443090102738825536188916),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00249716579989140882491939681805594585),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0004655591010047353023978045800916647),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.531129557920045295895085236636025323e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.343526765122727069515775194111741049e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.971120407556888763695313774578711839e-7),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.59911256167540354915906501335919317),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.136006830764025173864831382946934),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.468565867990030871678574840738423023),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.122821824954470343413956476900662236),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0209670914950115943338996513330141633),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00227845718243186165620199012883547257),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000144243326443913171313947613547085553),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.407763415954267700941230249989140046e-5),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 3.0f)) / tools::evaluate_polynomial(Q, T(z - 3.0f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 5.5)
+ {
+ // Maximum Deviation Found: 5.804e-36
+ // Expected Error Term: -5.803e-36
+ // Maximum Relative Change in Control Points: 2.475e-05
+ // Max Error found at long double precision = 1.349545e-35
+ static const T Y = 0.55000019073486328125f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00118142849742309772151454518093813615),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0072201822885703318172366893469382745),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0078782276276860110721875733778481505),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00418229166204362376187593976656261146),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00134198400587769200074194304298642705),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000283210387078004063264777611497435572),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.405687064094911866569295610914844928e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.39348283801568113807887364414008292e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.248798540917787001526976889284624449e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.929502490223452372919607105387474751e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.156161469668275442569286723236274457e-9),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.52955245103668419479878456656709381),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.06263944820093830054635017117417064),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.441684612681607364321013134378316463),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.121665258426166960049773715928906382),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0232134512374747691424978642874321434),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00310778180686296328582860464875562636),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000288361770756174705123674838640161693),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.177529187194133944622193191942300132e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.655068544833064069223029299070876623e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.11005507545746069573608988651927452e-7),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 4.5f)) / tools::evaluate_polynomial(Q, T(z - 4.5f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 7.5)
+ {
+ // Maximum Deviation Found: 1.007e-36
+ // Expected Error Term: 1.007e-36
+ // Maximum Relative Change in Control Points: 1.027e-03
+ // Max Error found at long double precision = 2.646420e-36
+ static const T Y = 0.5574436187744140625f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000293236907400849056269309713064107674),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00225110719535060642692275221961480162),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190984458121502831421717207849429799),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000747757733460111743833929141001680706),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000170663175280949889583158597373928096),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.246441188958013822253071608197514058e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.229818000860544644974205957895688106e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.134886977703388748488480980637704864e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.454764611880548962757125070106650958e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.673002744115866600294723141176820155e-10),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.12843690320861239631195353379313367),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.569900657061622955362493442186537259),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.169094404206844928112348730277514273),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0324887449084220415058158657252147063),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00419252877436825753042680842608219552),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00036344133176118603523976748563178578),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.204123895931375107397698245752850347e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.674128352521481412232785122943508729e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.997637501418963696542159244436245077e-8),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z - 6.5f)) / tools::evaluate_polynomial(Q, T(z - 6.5f));
+ result *= exp(-z * z) / z;
+ }
+ else if(z < 11.5)
+ {
+ // Maximum Deviation Found: 8.380e-36
+ // Expected Error Term: 8.380e-36
+ // Maximum Relative Change in Control Points: 2.632e-06
+ // Max Error found at long double precision = 9.849522e-36
+ static const T Y = 0.56083202362060546875f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000282420728751494363613829834891390121),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00175387065018002823433704079355125161),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0021344978564889819420775336322920375),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00124151356560137532655039683963075661),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000423600733566948018555157026862139644),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.914030340865175237133613697319509698e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.126999927156823363353809747017945494e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.110610959842869849776179749369376402e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.55075079477173482096725348704634529e-7),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.119735694018906705225870691331543806e-8),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.69889613396167354566098060039549882),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.28824647372749624464956031163282674),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.572297795434934493541628008224078717),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.164157697425571712377043857240773164),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.0315311145224594430281219516531649562),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00405588922155632380812945849777127458),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000336929033691445666232029762868642417),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.164033049810404773469413526427932109e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.356615210500531410114914617294694857e-6),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(z / 2 - 4.75f)) / tools::evaluate_polynomial(Q, T(z / 2 - 4.75f));
+ result *= exp(-z * z) / z;
+ }
+ else
+ {
+ // Maximum Deviation Found: 1.132e-35
+ // Expected Error Term: -1.132e-35
+ // Maximum Relative Change in Control Points: 4.674e-04
+ // Max Error found at long double precision = 1.162590e-35
+ static const T Y = 0.5632686614990234375f;
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.000920922048732849448079451574171836943),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.00321439044532288750501700028748922439),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.250455263029390118657884864261823431),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.906807635364090342031792404764598142),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -8.92233572835991735876688745989985565),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -21.7797433494422564811782116907878495),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -91.1451915251976354349734589601171659),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -144.1279109655993927069052125017673),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -313.845076581796338665519022313775589),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -273.11378811923343424081101235736475),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -271.651566205951067025696102600443452),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -60.0530577077238079968843307523245547),
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 3.49040448075464744191022350947892036),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 34.3563592467165971295915749548313227),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 84.4993232033879023178285731843850461),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 376.005865281206894120659401340373818),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 629.95369438888946233003926191755125),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1568.35771983533158591604513304269098),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1646.02452040831961063640827116581021),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 2299.96860633240298708910425594484895),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1222.73204392037452750381340219906374),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 799.359797306084372350264298361110448),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 72.7415265778588087243442792401576737),
+ };
+ result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z));
+ result *= exp(-z * z) / z;
+ }
+ }
+ else
+ {
+ //
+ // Any value of z larger than 110 will underflow to zero:
+ //
+ result = 0;
+ invert = !invert;
+ }
+
+ if(invert)
+ {
+ result = 1 - result;
+ }
+
+ return result;
+} // template <class T, class Lanczos>T erf_imp(T z, bool invert, const Lanczos& l, const mpl::int_<113>& t)
+
+template <class T, class Policy, class tag>
+struct erf_initializer
+{
+ struct init
+ {
+ init()
+ {
+ do_init(tag());
+ }
+ static void do_init(const mpl::int_<0>&){}
+ static void do_init(const mpl::int_<53>&)
+ {
+ boost::math::erf(static_cast<T>(1e-12), Policy());
+ boost::math::erf(static_cast<T>(0.25), Policy());
+ boost::math::erf(static_cast<T>(1.25), Policy());
+ boost::math::erf(static_cast<T>(2.25), Policy());
+ boost::math::erf(static_cast<T>(4.25), Policy());
+ boost::math::erf(static_cast<T>(5.25), Policy());
+ }
+ static void do_init(const mpl::int_<64>&)
+ {
+ boost::math::erf(static_cast<T>(1e-12), Policy());
+ boost::math::erf(static_cast<T>(0.25), Policy());
+ boost::math::erf(static_cast<T>(1.25), Policy());
+ boost::math::erf(static_cast<T>(2.25), Policy());
+ boost::math::erf(static_cast<T>(4.25), Policy());
+ boost::math::erf(static_cast<T>(5.25), Policy());
+ }
+ static void do_init(const mpl::int_<113>&)
+ {
+ boost::math::erf(static_cast<T>(1e-22), Policy());
+ boost::math::erf(static_cast<T>(0.25), Policy());
+ boost::math::erf(static_cast<T>(1.25), Policy());
+ boost::math::erf(static_cast<T>(2.125), Policy());
+ boost::math::erf(static_cast<T>(2.75), Policy());
+ boost::math::erf(static_cast<T>(3.25), Policy());
+ boost::math::erf(static_cast<T>(5.25), Policy());
+ boost::math::erf(static_cast<T>(7.25), Policy());
+ boost::math::erf(static_cast<T>(11.25), Policy());
+ boost::math::erf(static_cast<T>(12.5), Policy());
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy, class tag>
+const typename erf_initializer<T, Policy, tag>::init erf_initializer<T, Policy, tag>::initializer;
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type erf(T z, const Policy& /* pol */)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name());
+ BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name());
+ BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name());
+
+ typedef typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<0> >,
+ mpl::int_<0>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<53> >,
+ mpl::int_<53>, // double
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>, // 80-bit long double
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<113> >,
+ mpl::int_<113>, // 128-bit long double
+ mpl::int_<0> // too many bits, use generic version.
+ >::type
+ >::type
+ >::type
+ >::type tag_type;
+
+ BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name());
+
+ detail::erf_initializer<value_type, forwarding_policy, tag_type>::force_instantiate(); // Force constants to be initialized before main
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::erf_imp(
+ static_cast<value_type>(z),
+ false,
+ forwarding_policy(),
+ tag_type()), "boost::math::erf<%1%>(%1%, %1%)");
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type erfc(T z, const Policy& /* pol */)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name());
+ BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name());
+ BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name());
+
+ typedef typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<0> >,
+ mpl::int_<0>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<53> >,
+ mpl::int_<53>, // double
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>, // 80-bit long double
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<113> >,
+ mpl::int_<113>, // 128-bit long double
+ mpl::int_<0> // too many bits, use generic version.
+ >::type
+ >::type
+ >::type
+ >::type tag_type;
+
+ BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name());
+
+ detail::erf_initializer<value_type, forwarding_policy, tag_type>::force_instantiate(); // Force constants to be initialized before main
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::erf_imp(
+ static_cast<value_type>(z),
+ true,
+ forwarding_policy(),
+ tag_type()), "boost::math::erfc<%1%>(%1%, %1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erf(T z)
+{
+ return boost::math::erf(z, policies::policy<>());
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erfc(T z)
+{
+ return boost::math::erfc(z, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#include <boost/math/special_functions/detail/erf_inv.hpp>
+
+#endif // BOOST_MATH_SPECIAL_ERF_HPP
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/expm1.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/expm1.hpp
new file mode 100644
index 00000000000..7423dc5c811
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/expm1.hpp
@@ -0,0 +1,343 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_EXPM1_INCLUDED
+#define BOOST_MATH_EXPM1_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <math.h> // platform's ::expm1
+#include <boost/limits.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/mpl/less_equal.hpp>
+
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+# include <boost/static_assert.hpp>
+#else
+# include <boost/assert.hpp>
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+ // Functor expm1_series returns the next term in the Taylor series
+ // x^k / k!
+ // each time that operator() is invoked.
+ //
+ template <class T>
+ struct expm1_series
+ {
+ typedef T result_type;
+
+ expm1_series(T x)
+ : k(0), m_x(x), m_term(1) {}
+
+ T operator()()
+ {
+ ++k;
+ m_term *= m_x;
+ m_term /= k;
+ return m_term;
+ }
+
+ int count()const
+ {
+ return k;
+ }
+
+ private:
+ int k;
+ const T m_x;
+ T m_term;
+ expm1_series(const expm1_series&);
+ expm1_series& operator=(const expm1_series&);
+ };
+
+template <class T, class Policy, class tag>
+struct expm1_initializer
+{
+ struct init
+ {
+ init()
+ {
+ do_init(tag());
+ }
+ template <int N>
+ static void do_init(const mpl::int_<N>&){}
+ static void do_init(const mpl::int_<64>&)
+ {
+ expm1(T(0.5));
+ }
+ static void do_init(const mpl::int_<113>&)
+ {
+ expm1(T(0.5));
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy, class tag>
+const typename expm1_initializer<T, Policy, tag>::init expm1_initializer<T, Policy, tag>::initializer;
+
+//
+// Algorithm expm1 is part of C99, but is not yet provided by many compilers.
+//
+// This version uses a Taylor series expansion for 0.5 > |x| > epsilon.
+//
+template <class T, class Policy>
+T expm1_imp(T x, const mpl::int_<0>&, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T a = fabs(x);
+ if(a > T(0.5f))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
+ return exp(x) - T(1);
+ }
+ if(a < tools::epsilon<T>())
+ return x;
+ detail::expm1_series<T> s(x);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) && !BOOST_WORKAROUND(__EDG_VERSION__, <= 245)
+ T result = tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter);
+#else
+ T zero = 0;
+ T result = tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, zero);
+#endif
+ policies::check_series_iterations<T>("boost::math::expm1<%1%>(%1%)", max_iter, pol);
+ return result;
+}
+
+template <class T, class P>
+T expm1_imp(T x, const mpl::int_<53>&, const P& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T a = fabs(x);
+ if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
+ return exp(x) - T(1);
+ }
+ if(a < tools::epsilon<T>())
+ return x;
+
+ static const float Y = 0.10281276702880859e1f;
+ static const T n[] = { static_cast<T>(-0.28127670288085937e-1), static_cast<T>(0.51278186299064534e0), static_cast<T>(-0.6310029069350198e-1), static_cast<T>(0.11638457975729296e-1), static_cast<T>(-0.52143390687521003e-3), static_cast<T>(0.21491399776965688e-4) };
+ static const T d[] = { 1, static_cast<T>(-0.45442309511354755e0), static_cast<T>(0.90850389570911714e-1), static_cast<T>(-0.10088963629815502e-1), static_cast<T>(0.63003407478692265e-3), static_cast<T>(-0.17976570003654402e-4) };
+
+ T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x);
+ return result;
+}
+
+template <class T, class P>
+T expm1_imp(T x, const mpl::int_<64>&, const P& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T a = fabs(x);
+ if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
+ return exp(x) - T(1);
+ }
+ if(a < tools::epsilon<T>())
+ return x;
+
+ static const float Y = 0.10281276702880859375e1f;
+ static const T n[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.281276702880859375e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.512980290285154286358e0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.667758794592881019644e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.131432469658444745835e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.72303795326880286965e-3),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.447441185192951335042e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.714539134024984593011e-6)
+ };
+ static const T d[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.461477618025562520389e0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.961237488025708540713e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.116483957658204450739e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.873308008461557544458e-3),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.387922804997682392562e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.807473180049193557294e-6)
+ };
+
+ T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x);
+ return result;
+}
+
+template <class T, class P>
+T expm1_imp(T x, const mpl::int_<113>&, const P& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T a = fabs(x);
+ if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
+ return exp(x) - T(1);
+ }
+ if(a < tools::epsilon<T>())
+ return x;
+
+ static const float Y = 0.10281276702880859375e1f;
+ static const T n[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.28127670288085937499999999999999999854e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.51278156911210477556524452177540792214e0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.63263178520747096729500254678819588223e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.14703285606874250425508446801230572252e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.8675686051689527802425310407898459386e-3),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.88126359618291165384647080266133492399e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.25963087867706310844432390015463138953e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.14226691087800461778631773363204081194e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.15995603306536496772374181066765665596e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.45261820069007790520447958280473183582e-10)
+ };
+ static const T d[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.45441264709074310514348137469214538853e0),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.96827131936192217313133611655555298106e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.12745248725908178612540554584374876219e-1),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.11473613871583259821612766907781095472e-2),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.73704168477258911962046591907690764416e-4),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.34087499397791555759285503797256103259e-5),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.11114024704296196166272091230695179724e-6),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.23987051614110848595909588343223896577e-8),
+ BOOST_MATH_BIG_CONSTANT(T, 113, -0.29477341859111589208776402638429026517e-10),
+ BOOST_MATH_BIG_CONSTANT(T, 113, 0.13222065991022301420255904060628100924e-12)
+ };
+
+ T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x);
+ return result;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type expm1(T x, const Policy& /* pol */)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ typedef typename mpl::if_c<
+ ::std::numeric_limits<result_type>::is_specialized == 0,
+ mpl::int_<0>, // no numeric_limits, use generic solution
+ typename mpl::if_<
+ typename mpl::less_equal<precision_type, mpl::int_<53> >::type,
+ mpl::int_<53>, // double
+ typename mpl::if_<
+ typename mpl::less_equal<precision_type, mpl::int_<64> >::type,
+ mpl::int_<64>, // 80-bit long double
+ typename mpl::if_<
+ typename mpl::less_equal<precision_type, mpl::int_<113> >::type,
+ mpl::int_<113>, // 128-bit long double
+ mpl::int_<0> // too many bits, use generic version.
+ >::type
+ >::type
+ >::type
+ >::type tag_type;
+
+ detail::expm1_initializer<value_type, forwarding_policy, tag_type>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::expm1_imp(
+ static_cast<value_type>(x),
+ tag_type(), forwarding_policy()), "boost::math::expm1<%1%>(%1%)");
+}
+
+#ifdef expm1
+# ifndef BOOST_HAS_expm1
+# define BOOST_HAS_expm1
+# endif
+# undef expm1
+#endif
+
+#if defined(BOOST_HAS_EXPM1) && !(defined(__osf__) && defined(__DECCXX_VER))
+# ifdef BOOST_MATH_USE_C99
+inline float expm1(float x, const policies::policy<>&){ return ::expm1f(x); }
+# ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double expm1(long double x, const policies::policy<>&){ return ::expm1l(x); }
+# endif
+# else
+inline float expm1(float x, const policies::policy<>&){ return static_cast<float>(::expm1(x)); }
+# endif
+inline double expm1(double x, const policies::policy<>&){ return ::expm1(x); }
+#endif
+
+template <class T>
+inline typename tools::promote_args<T>::type expm1(T x)
+{
+ return expm1(x, policies::policy<>());
+}
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+inline float expm1(float z)
+{
+ return expm1<float>(z);
+}
+inline double expm1(double z)
+{
+ return expm1<double>(z);
+}
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double expm1(long double z)
+{
+ return expm1<long double>(z);
+}
+#endif
+#endif
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_HYPOT_INCLUDED
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/factorials.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/factorials.hpp
new file mode 100644
index 00000000000..de24642ac41
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/factorials.hpp
@@ -0,0 +1,268 @@
+// Copyright John Maddock 2006, 2010.
+// 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)
+
+#ifndef BOOST_MATH_SP_FACTORIALS_HPP
+#define BOOST_MATH_SP_FACTORIALS_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/special_functions/detail/unchecked_factorial.hpp>
+#include <boost/array.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push) // Temporary until lexical cast fixed.
+#pragma warning(disable: 4127 4701)
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#include <boost/config/no_tr1/cmath.hpp>
+
+namespace boost { namespace math
+{
+
+template <class T, class Policy>
+inline T factorial(unsigned i, const Policy& pol)
+{
+ BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+ // factorial<unsigned int>(n) is not implemented
+ // because it would overflow integral type T for too small n
+ // to be useful. Use instead a floating-point type,
+ // and convert to an unsigned type if essential, for example:
+ // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
+ // See factorial documentation for more detail.
+
+ BOOST_MATH_STD_USING // Aid ADL for floor.
+
+ if(i <= max_factorial<T>::value)
+ return unchecked_factorial<T>(i);
+ T result = boost::math::tgamma(static_cast<T>(i+1), pol);
+ if(result > tools::max_value<T>())
+ return result; // Overflowed value! (But tgamma will have signalled the error already).
+ return floor(result + 0.5f);
+}
+
+template <class T>
+inline T factorial(unsigned i)
+{
+ return factorial<T>(i, policies::policy<>());
+}
+/*
+// Can't have these in a policy enabled world?
+template<>
+inline float factorial<float>(unsigned i)
+{
+ if(i <= max_factorial<float>::value)
+ return unchecked_factorial<float>(i);
+ return tools::overflow_error<float>(BOOST_CURRENT_FUNCTION);
+}
+
+template<>
+inline double factorial<double>(unsigned i)
+{
+ if(i <= max_factorial<double>::value)
+ return unchecked_factorial<double>(i);
+ return tools::overflow_error<double>(BOOST_CURRENT_FUNCTION);
+}
+*/
+template <class T, class Policy>
+T double_factorial(unsigned i, const Policy& pol)
+{
+ BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+ BOOST_MATH_STD_USING // ADL lookup of std names
+ if(i & 1)
+ {
+ // odd i:
+ if(i < max_factorial<T>::value)
+ {
+ unsigned n = (i - 1) / 2;
+ return ceil(unchecked_factorial<T>(i) / (ldexp(T(1), (int)n) * unchecked_factorial<T>(n)) - 0.5f);
+ }
+ //
+ // Fallthrough: i is too large to use table lookup, try the
+ // gamma function instead.
+ //
+ T result = boost::math::tgamma(static_cast<T>(i) / 2 + 1, pol) / sqrt(constants::pi<T>());
+ if(ldexp(tools::max_value<T>(), -static_cast<int>(i+1) / 2) > result)
+ return ceil(result * ldexp(T(1), static_cast<int>(i+1) / 2) - 0.5f);
+ }
+ else
+ {
+ // even i:
+ unsigned n = i / 2;
+ T result = factorial<T>(n, pol);
+ if(ldexp(tools::max_value<T>(), -(int)n) > result)
+ return result * ldexp(T(1), (int)n);
+ }
+ //
+ // If we fall through to here then the result is infinite:
+ //
+ return policies::raise_overflow_error<T>("boost::math::double_factorial<%1%>(unsigned)", 0, pol);
+}
+
+template <class T>
+inline T double_factorial(unsigned i)
+{
+ return double_factorial<T>(i, policies::policy<>());
+}
+
+namespace detail{
+
+template <class T, class Policy>
+T rising_factorial_imp(T x, int n, const Policy& pol)
+{
+ BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+ if(x < 0)
+ {
+ //
+ // For x less than zero, we really have a falling
+ // factorial, modulo a possible change of sign.
+ //
+ // Note that the falling factorial isn't defined
+ // for negative n, so we'll get rid of that case
+ // first:
+ //
+ bool inv = false;
+ if(n < 0)
+ {
+ x += n;
+ n = -n;
+ inv = true;
+ }
+ T result = ((n&1) ? -1 : 1) * falling_factorial(-x, n, pol);
+ if(inv)
+ result = 1 / result;
+ return result;
+ }
+ if(n == 0)
+ return 1;
+ if(x == 0)
+ {
+ if(n < 0)
+ return -boost::math::tgamma_delta_ratio(x + 1, static_cast<T>(-n), pol);
+ else
+ return 0;
+ }
+ if((x < 1) && (x + n < 0))
+ {
+ T val = boost::math::tgamma_delta_ratio(1 - x, static_cast<T>(-n), pol);
+ return (n & 1) ? -val : val;
+ }
+ //
+ // We don't optimise this for small n, because
+ // tgamma_delta_ratio is alreay optimised for that
+ // use case:
+ //
+ return 1 / boost::math::tgamma_delta_ratio(x, static_cast<T>(n), pol);
+}
+
+template <class T, class Policy>
+inline T falling_factorial_imp(T x, unsigned n, const Policy& pol)
+{
+ BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+ BOOST_MATH_STD_USING // ADL of std names
+ if((x == 0) && (n >= 0))
+ return 0;
+ if(x < 0)
+ {
+ //
+ // For x < 0 we really have a rising factorial
+ // modulo a possible change of sign:
+ //
+ return (n&1 ? -1 : 1) * rising_factorial(-x, n, pol);
+ }
+ if(n == 0)
+ return 1;
+ if(x < 0.5f)
+ {
+ //
+ // 1 + x below will throw away digits, so split up calculation:
+ //
+ if(n > max_factorial<T>::value - 2)
+ {
+ // If the two end of the range are far apart we have a ratio of two very large
+ // numbers, split the calculation up into two blocks:
+ T t1 = x * boost::math::falling_factorial(x - 1, max_factorial<T>::value - 2);
+ T t2 = boost::math::falling_factorial(x - max_factorial<T>::value + 1, n - max_factorial<T>::value + 1);
+ if(tools::max_value<T>() / fabs(t1) < fabs(t2))
+ return boost::math::sign(t1) * boost::math::sign(t2) * policies::raise_overflow_error<T>("boost::math::falling_factorial<%1%>", 0, pol);
+ return t1 * t2;
+ }
+ return x * boost::math::falling_factorial(x - 1, n - 1);
+ }
+ if(x <= n - 1)
+ {
+ //
+ // x+1-n will be negative and tgamma_delta_ratio won't
+ // handle it, split the product up into three parts:
+ //
+ T xp1 = x + 1;
+ unsigned n2 = itrunc((T)floor(xp1), pol);
+ if(n2 == xp1)
+ return 0;
+ T result = boost::math::tgamma_delta_ratio(xp1, -static_cast<T>(n2), pol);
+ x -= n2;
+ result *= x;
+ ++n2;
+ if(n2 < n)
+ result *= falling_factorial(x - 1, n - n2, pol);
+ return result;
+ }
+ //
+ // Simple case: just the ratio of two
+ // (positive argument) gamma functions.
+ // Note that we don't optimise this for small n,
+ // because tgamma_delta_ratio is alreay optimised
+ // for that use case:
+ //
+ return boost::math::tgamma_delta_ratio(x + 1, -static_cast<T>(n), pol);
+}
+
+} // namespace detail
+
+template <class RT>
+inline typename tools::promote_args<RT>::type
+ falling_factorial(RT x, unsigned n)
+{
+ typedef typename tools::promote_args<RT>::type result_type;
+ return detail::falling_factorial_imp(
+ static_cast<result_type>(x), n, policies::policy<>());
+}
+
+template <class RT, class Policy>
+inline typename tools::promote_args<RT>::type
+ falling_factorial(RT x, unsigned n, const Policy& pol)
+{
+ typedef typename tools::promote_args<RT>::type result_type;
+ return detail::falling_factorial_imp(
+ static_cast<result_type>(x), n, pol);
+}
+
+template <class RT>
+inline typename tools::promote_args<RT>::type
+ rising_factorial(RT x, int n)
+{
+ typedef typename tools::promote_args<RT>::type result_type;
+ return detail::rising_factorial_imp(
+ static_cast<result_type>(x), n, policies::policy<>());
+}
+
+template <class RT, class Policy>
+inline typename tools::promote_args<RT>::type
+ rising_factorial(RT x, int n, const Policy& pol)
+{
+ typedef typename tools::promote_args<RT>::type result_type;
+ return detail::rising_factorial_imp(
+ static_cast<result_type>(x), n, pol);
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_FACTORIALS_HPP
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/fpclassify.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/fpclassify.hpp
new file mode 100644
index 00000000000..40f6e14ba5e
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/fpclassify.hpp
@@ -0,0 +1,606 @@
+// Copyright John Maddock 2005-2008.
+// Copyright (c) 2006-2008 Johan Rade
+// 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)
+
+#ifndef BOOST_MATH_FPCLASSIFY_HPP
+#define BOOST_MATH_FPCLASSIFY_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <math.h>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/limits.hpp>
+#include <boost/math/tools/real_cast.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/detail/fp_traits.hpp>
+/*!
+ \file fpclassify.hpp
+ \brief Classify floating-point value as normal, subnormal, zero, infinite, or NaN.
+ \version 1.0
+ \author John Maddock
+ */
+
+/*
+
+1. If the platform is C99 compliant, then the native floating point
+classification functions are used. However, note that we must only
+define the functions which call std::fpclassify etc if that function
+really does exist: otherwise a compiler may reject the code even though
+the template is never instantiated.
+
+2. If the platform is not C99 compliant, and the binary format for
+a floating point type (float, double or long double) can be determined
+at compile time, then the following algorithm is used:
+
+ If all exponent bits, the flag bit (if there is one),
+ and all significand bits are 0, then the number is zero.
+
+ If all exponent bits and the flag bit (if there is one) are 0,
+ and at least one significand bit is 1, then the number is subnormal.
+
+ If all exponent bits are 1 and all significand bits are 0,
+ then the number is infinity.
+
+ If all exponent bits are 1 and at least one significand bit is 1,
+ then the number is a not-a-number.
+
+ Otherwise the number is normal.
+
+ This algorithm works for the IEEE 754 representation,
+ and also for several non IEEE 754 formats.
+
+ Most formats have the structure
+ sign bit + exponent bits + significand bits.
+
+ A few have the structure
+ sign bit + exponent bits + flag bit + significand bits.
+ The flag bit is 0 for zero and subnormal numbers,
+ and 1 for normal numbers and NaN.
+ It is 0 (Motorola 68K) or 1 (Intel) for infinity.
+
+ To get the bits, the four or eight most significant bytes are copied
+ into an uint32_t or uint64_t and bit masks are applied.
+ This covers all the exponent bits and the flag bit (if there is one),
+ but not always all the significand bits.
+ Some of the functions below have two implementations,
+ depending on whether all the significand bits are copied or not.
+
+3. If the platform is not C99 compliant, and the binary format for
+a floating point type (float, double or long double) can not be determined
+at compile time, then comparison with std::numeric_limits values
+is used.
+
+*/
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#include <float.h>
+#endif
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std{ using ::abs; using ::fabs; }
+#endif
+
+namespace boost{
+
+//
+// This must not be located in any namespace under boost::math
+// otherwise we can get into an infinite loop if isnan is
+// a #define for "isnan" !
+//
+namespace math_detail{
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4800)
+#endif
+
+template <class T>
+inline bool is_nan_helper(T t, const boost::true_type&)
+{
+#ifdef isnan
+ return isnan(t);
+#elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY)
+ (void)t;
+ return false;
+#else // BOOST_HAS_FPCLASSIFY
+ return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN);
+#endif
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class T>
+inline bool is_nan_helper(T, const boost::false_type&)
+{
+ return false;
+}
+
+}
+
+namespace math{
+
+namespace detail{
+
+#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
+template <class T>
+inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&)
+{
+ return (std::fpclassify)(t);
+}
+#endif
+
+template <class T>
+inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<true>&)
+{
+ BOOST_MATH_INSTRUMENT_VARIABLE(t);
+
+ // whenever possible check for Nan's first:
+#if defined(BOOST_HAS_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
+ if(::boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
+ return FP_NAN;
+#elif defined(isnan)
+ if(boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
+ return FP_NAN;
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+ if(::_isnan(boost::math::tools::real_cast<double>(t)))
+ return FP_NAN;
+#endif
+ // std::fabs broken on a few systems especially for long long!!!!
+ T at = (t < T(0)) ? -t : t;
+
+ // Use a process of exclusion to figure out
+ // what kind of type we have, this relies on
+ // IEEE conforming reals that will treat
+ // Nan's as unordered. Some compilers
+ // don't do this once optimisations are
+ // turned on, hence the check for nan's above.
+ if(at <= (std::numeric_limits<T>::max)())
+ {
+ if(at >= (std::numeric_limits<T>::min)())
+ return FP_NORMAL;
+ return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
+ }
+ else if(at > (std::numeric_limits<T>::max)())
+ return FP_INFINITE;
+ return FP_NAN;
+}
+
+template <class T>
+inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
+{
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<T>::is_specialized)
+ return fpclassify_imp(t, generic_tag<true>());
+#endif
+ //
+ // An unknown type with no numeric_limits support,
+ // so what are we supposed to do we do here?
+ //
+ BOOST_MATH_INSTRUMENT_VARIABLE(t);
+
+ return t == 0 ? FP_ZERO : FP_NORMAL;
+}
+
+template<class T>
+int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
+{
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(x);
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ BOOST_MATH_INSTRUMENT_VARIABLE(a);
+ a &= traits::exponent | traits::flag | traits::significand;
+ BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand));
+ BOOST_MATH_INSTRUMENT_VARIABLE(a);
+
+ if(a <= traits::significand) {
+ if(a == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if(a < traits::exponent) return FP_NORMAL;
+
+ a &= traits::significand;
+ if(a == 0) return FP_INFINITE;
+
+ return FP_NAN;
+}
+
+template<class T>
+int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
+{
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(x);
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::flag | traits::significand;
+
+ if(a <= traits::significand) {
+ if(x == 0)
+ return FP_ZERO;
+ else
+ return FP_SUBNORMAL;
+ }
+
+ if(a < traits::exponent) return FP_NORMAL;
+
+ a &= traits::significand;
+ traits::set_bits(x,a);
+ if(x == 0) return FP_INFINITE;
+
+ return FP_NAN;
+}
+
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS))
+inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+{
+ return boost::math::detail::fpclassify_imp(t, generic_tag<true>());
+}
+#endif
+
+} // namespace detail
+
+template <class T>
+inline int fpclassify BOOST_NO_MACRO_EXPAND(T t)
+{
+ typedef typename detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+ typedef typename tools::promote_args_permissive<T>::type value_type;
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
+ return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
+ return detail::fpclassify_imp(static_cast<value_type>(t), method());
+#else
+ return detail::fpclassify_imp(static_cast<value_type>(t), method());
+#endif
+}
+
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template <>
+inline int fpclassify<long double> BOOST_NO_MACRO_EXPAND(long double t)
+{
+ typedef detail::fp_traits<long double>::type traits;
+ typedef traits::method method;
+ typedef long double value_type;
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<long double>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
+ return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
+ return detail::fpclassify_imp(static_cast<value_type>(t), method());
+#else
+ return detail::fpclassify_imp(static_cast<value_type>(t), method());
+#endif
+}
+#endif
+
+namespace detail {
+
+#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
+ template<class T>
+ inline bool isfinite_impl(T x, native_tag const&)
+ {
+ return (std::isfinite)(x);
+ }
+#endif
+
+ template<class T>
+ inline bool isfinite_impl(T x, generic_tag<true> const&)
+ {
+ return x >= -(std::numeric_limits<T>::max)()
+ && x <= (std::numeric_limits<T>::max)();
+ }
+
+ template<class T>
+ inline bool isfinite_impl(T x, generic_tag<false> const&)
+ {
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<T>::is_specialized)
+ return isfinite_impl(x, generic_tag<true>());
+#endif
+ (void)x; // warning supression.
+ return true;
+ }
+
+ template<class T>
+ inline bool isfinite_impl(T x, ieee_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent;
+ return a != traits::exponent;
+ }
+
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
+inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+{
+ return boost::math::detail::isfinite_impl(t, generic_tag<true>());
+}
+#endif
+
+}
+
+template<class T>
+inline bool (isfinite)(T x)
+{ //!< \brief return true if floating-point type t is finite.
+ typedef typename detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+ // typedef typename boost::is_floating_point<T>::type fp_tag;
+ typedef typename tools::promote_args_permissive<T>::type value_type;
+ return detail::isfinite_impl(static_cast<value_type>(x), method());
+}
+
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template<>
+inline bool (isfinite)(long double x)
+{ //!< \brief return true if floating-point type t is finite.
+ typedef detail::fp_traits<long double>::type traits;
+ typedef traits::method method;
+ //typedef boost::is_floating_point<long double>::type fp_tag;
+ typedef long double value_type;
+ return detail::isfinite_impl(static_cast<value_type>(x), method());
+}
+#endif
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
+ template<class T>
+ inline bool isnormal_impl(T x, native_tag const&)
+ {
+ return (std::isnormal)(x);
+ }
+#endif
+
+ template<class T>
+ inline bool isnormal_impl(T x, generic_tag<true> const&)
+ {
+ if(x < 0) x = -x;
+ return x >= (std::numeric_limits<T>::min)()
+ && x <= (std::numeric_limits<T>::max)();
+ }
+
+ template<class T>
+ inline bool isnormal_impl(T x, generic_tag<false> const&)
+ {
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<T>::is_specialized)
+ return isnormal_impl(x, generic_tag<true>());
+#endif
+ return !(x == 0);
+ }
+
+ template<class T>
+ inline bool isnormal_impl(T x, ieee_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::flag;
+ return (a != 0) && (a < traits::exponent);
+ }
+
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
+inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+{
+ return boost::math::detail::isnormal_impl(t, generic_tag<true>());
+}
+#endif
+
+}
+
+template<class T>
+inline bool (isnormal)(T x)
+{
+ typedef typename detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+ //typedef typename boost::is_floating_point<T>::type fp_tag;
+ typedef typename tools::promote_args_permissive<T>::type value_type;
+ return detail::isnormal_impl(static_cast<value_type>(x), method());
+}
+
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template<>
+inline bool (isnormal)(long double x)
+{
+ typedef detail::fp_traits<long double>::type traits;
+ typedef traits::method method;
+ //typedef boost::is_floating_point<long double>::type fp_tag;
+ typedef long double value_type;
+ return detail::isnormal_impl(static_cast<value_type>(x), method());
+}
+#endif
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
+ template<class T>
+ inline bool isinf_impl(T x, native_tag const&)
+ {
+ return (std::isinf)(x);
+ }
+#endif
+
+ template<class T>
+ inline bool isinf_impl(T x, generic_tag<true> const&)
+ {
+ (void)x; // in case the compiler thinks that x is unused because std::numeric_limits<T>::has_infinity is false
+ return std::numeric_limits<T>::has_infinity
+ && ( x == std::numeric_limits<T>::infinity()
+ || x == -std::numeric_limits<T>::infinity());
+ }
+
+ template<class T>
+ inline bool isinf_impl(T x, generic_tag<false> const&)
+ {
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<T>::is_specialized)
+ return isinf_impl(x, generic_tag<true>());
+#endif
+ (void)x; // warning supression.
+ return false;
+ }
+
+ template<class T>
+ inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::significand;
+ return a == traits::exponent;
+ }
+
+ template<class T>
+ inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::significand;
+ if(a != traits::exponent)
+ return false;
+
+ traits::set_bits(x,0);
+ return x == 0;
+ }
+
+#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
+inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
+{
+ return boost::math::detail::isinf_impl(t, generic_tag<true>());
+}
+#endif
+
+} // namespace detail
+
+template<class T>
+inline bool (isinf)(T x)
+{
+ typedef typename detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+ // typedef typename boost::is_floating_point<T>::type fp_tag;
+ typedef typename tools::promote_args_permissive<T>::type value_type;
+ return detail::isinf_impl(static_cast<value_type>(x), method());
+}
+
+#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template<>
+inline bool (isinf)(long double x)
+{
+ typedef detail::fp_traits<long double>::type traits;
+ typedef traits::method method;
+ //typedef boost::is_floating_point<long double>::type fp_tag;
+ typedef long double value_type;
+ return detail::isinf_impl(static_cast<value_type>(x), method());
+}
+#endif
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
+ template<class T>
+ inline bool isnan_impl(T x, native_tag const&)
+ {
+ return (std::isnan)(x);
+ }
+#endif
+
+ template<class T>
+ inline bool isnan_impl(T x, generic_tag<true> const&)
+ {
+ return std::numeric_limits<T>::has_infinity
+ ? !(x <= std::numeric_limits<T>::infinity())
+ : x != x;
+ }
+
+ template<class T>
+ inline bool isnan_impl(T x, generic_tag<false> const&)
+ {
+#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ if(std::numeric_limits<T>::is_specialized)
+ return isnan_impl(x, generic_tag<true>());
+#endif
+ (void)x; // warning supression
+ return false;
+ }
+
+ template<class T>
+ inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a &= traits::exponent | traits::significand;
+ return a > traits::exponent;
+ }
+
+ template<class T>
+ inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+
+ a &= traits::exponent | traits::significand;
+ if(a < traits::exponent)
+ return false;
+
+ a &= traits::significand;
+ traits::set_bits(x,a);
+ return x != 0;
+ }
+
+} // namespace detail
+
+template<class T>
+inline bool (isnan)(T x)
+{ //!< \brief return true if floating-point type t is NaN (Not A Number).
+ typedef typename detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+ // typedef typename boost::is_floating_point<T>::type fp_tag;
+ return detail::isnan_impl(x, method());
+}
+
+#ifdef isnan
+template <> inline bool isnan BOOST_NO_MACRO_EXPAND<float>(float t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
+template <> inline bool isnan BOOST_NO_MACRO_EXPAND<double>(double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
+template <> inline bool isnan BOOST_NO_MACRO_EXPAND<long double>(long double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
+#elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
+template<>
+inline bool (isnan)(long double x)
+{ //!< \brief return true if floating-point type t is NaN (Not A Number).
+ typedef detail::fp_traits<long double>::type traits;
+ typedef traits::method method;
+ //typedef boost::is_floating_point<long double>::type fp_tag;
+ return detail::isnan_impl(x, method());
+}
+#endif
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_FPCLASSIFY_HPP
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/gamma.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/gamma.hpp
new file mode 100644
index 00000000000..07a0ba4f774
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/gamma.hpp
@@ -0,0 +1,1931 @@
+
+// Copyright John Maddock 2006-7, 2013-14.
+// Copyright Paul A. Bristow 2007, 2013-14.
+// Copyright Nikhar Agrawal 2013-14
+// Copyright Christopher Kormanyos 2013-14
+
+// 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)
+
+#ifndef BOOST_MATH_SF_GAMMA_HPP
+#define BOOST_MATH_SF_GAMMA_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/fraction.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+#include <boost/math/special_functions/powm1.hpp>
+#include <boost/math/special_functions/sqrt1pm1.hpp>
+#include <boost/math/special_functions/lanczos.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/detail/igamma_large.hpp>
+#include <boost/math/special_functions/detail/unchecked_factorial.hpp>
+#include <boost/math/special_functions/detail/lgamma_small.hpp>
+#include <boost/math/special_functions/bernoulli.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/greater.hpp>
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <algorithm>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
+# pragma warning(disable: 4127) // conditional expression is constant.
+# pragma warning(disable: 4100) // unreferenced formal parameter.
+// Several variables made comments,
+// but some difficulty as whether referenced on not may depend on macro values.
+// So to be safe, 4100 warnings suppressed.
+// TODO - revisit this?
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail{
+
+template <class T>
+inline bool is_odd(T v, const boost::true_type&)
+{
+ int i = static_cast<int>(v);
+ return i&1;
+}
+template <class T>
+inline bool is_odd(T v, const boost::false_type&)
+{
+ // Oh dear can't cast T to int!
+ BOOST_MATH_STD_USING
+ T modulus = v - 2 * floor(v/2);
+ return static_cast<bool>(modulus != 0);
+}
+template <class T>
+inline bool is_odd(T v)
+{
+ return is_odd(v, ::boost::is_convertible<T, int>());
+}
+
+template <class T>
+T sinpx(T z)
+{
+ // Ad hoc function calculates x * sin(pi * x),
+ // taking extra care near when x is near a whole number.
+ BOOST_MATH_STD_USING
+ int sign = 1;
+ if(z < 0)
+ {
+ z = -z;
+ }
+ else
+ {
+ sign = -sign;
+ }
+ T fl = floor(z);
+ T dist;
+ if(is_odd(fl))
+ {
+ fl += 1;
+ dist = fl - z;
+ sign = -sign;
+ }
+ else
+ {
+ dist = z - fl;
+ }
+ BOOST_ASSERT(fl >= 0);
+ if(dist > 0.5)
+ dist = 1 - dist;
+ T result = sin(dist*boost::math::constants::pi<T>());
+ return sign*z*result;
+} // template <class T> T sinpx(T z)
+//
+// tgamma(z), with Lanczos support:
+//
+template <class T, class Policy, class Lanczos>
+T gamma_imp(T z, const Policy& pol, const Lanczos& l)
+{
+ BOOST_MATH_STD_USING
+
+ T result = 1;
+
+#ifdef BOOST_MATH_INSTRUMENT
+ static bool b = false;
+ if(!b)
+ {
+ std::cout << "tgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl;
+ b = true;
+ }
+#endif
+ static const char* function = "boost::math::tgamma<%1%>(%1%)";
+
+ if(z <= 0)
+ {
+ if(floor(z) == z)
+ return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
+ if(z <= -20)
+ {
+ result = gamma_imp(T(-z), pol, l) * sinpx(z);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ if((fabs(result) < 1) && (tools::max_value<T>() * fabs(result) < boost::math::constants::pi<T>()))
+ return -boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+ result = -boost::math::constants::pi<T>() / result;
+ if(result == 0)
+ return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
+ if((boost::math::fpclassify)(result) == (int)FP_SUBNORMAL)
+ return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", result, pol);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ return result;
+ }
+
+ // shift z to > 1:
+ while(z < 0)
+ {
+ result /= z;
+ z += 1;
+ }
+ }
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ if((floor(z) == z) && (z < max_factorial<T>::value))
+ {
+ result *= unchecked_factorial<T>(itrunc(z, pol) - 1);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else if (z < tools::root_epsilon<T>())
+ {
+ if (z < 1 / tools::max_value<T>())
+ result = policies::raise_overflow_error<T>(function, 0, pol);
+ result *= 1 / z - constants::euler<T>();
+ }
+ else
+ {
+ result *= Lanczos::lanczos_sum(z);
+ T zgh = (z + static_cast<T>(Lanczos::g()) - boost::math::constants::half<T>());
+ T lzgh = log(zgh);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ BOOST_MATH_INSTRUMENT_VARIABLE(tools::log_max_value<T>());
+ if(z * lzgh > tools::log_max_value<T>())
+ {
+ // we're going to overflow unless this is done with care:
+ BOOST_MATH_INSTRUMENT_VARIABLE(zgh);
+ if(lzgh * z / 2 > tools::log_max_value<T>())
+ return boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+ T hp = pow(zgh, (z / 2) - T(0.25));
+ BOOST_MATH_INSTRUMENT_VARIABLE(hp);
+ result *= hp / exp(zgh);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ if(tools::max_value<T>() / hp < result)
+ return boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+ result *= hp;
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ else
+ {
+ BOOST_MATH_INSTRUMENT_VARIABLE(zgh);
+ BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, z - boost::math::constants::half<T>()));
+ BOOST_MATH_INSTRUMENT_VARIABLE(exp(zgh));
+ result *= pow(zgh, z - boost::math::constants::half<T>()) / exp(zgh);
+ BOOST_MATH_INSTRUMENT_VARIABLE(result);
+ }
+ }
+ return result;
+}
+//
+// lgamma(z) with Lanczos support:
+//
+template <class T, class Policy, class Lanczos>
+T lgamma_imp(T z, const Policy& pol, const Lanczos& l, int* sign = 0)
+{
+#ifdef BOOST_MATH_INSTRUMENT
+ static bool b = false;
+ if(!b)
+ {
+ std::cout << "lgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl;
+ b = true;
+ }
+#endif
+
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::lgamma<%1%>(%1%)";
+
+ T result = 0;
+ int sresult = 1;
+ if(z <= -tools::root_epsilon<T>())
+ {
+ // reflection formula:
+ if(floor(z) == z)
+ return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
+
+ T t = sinpx(z);
+ z = -z;
+ if(t < 0)
+ {
+ t = -t;
+ }
+ else
+ {
+ sresult = -sresult;
+ }
+ result = log(boost::math::constants::pi<T>()) - lgamma_imp(z, pol, l) - log(t);
+ }
+ else if (z < tools::root_epsilon<T>())
+ {
+ if (0 == z)
+ return policies::raise_pole_error<T>(function, "Evaluation of lgamma at %1%.", z, pol);
+ if (fabs(z) < 1 / tools::max_value<T>())
+ result = -log(fabs(z));
+ else
+ result = log(fabs(1 / z - constants::euler<T>()));
+ if (z < 0)
+ sresult = -1;
+ }
+ else if(z < 15)
+ {
+ typedef typename policies::precision<T, Policy>::type precision_type;
+ typedef typename mpl::if_<
+ mpl::and_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::greater<precision_type, mpl::int_<0> >
+ >,
+ mpl::int_<64>,
+ typename mpl::if_<
+ mpl::and_<
+ mpl::less_equal<precision_type, mpl::int_<113> >,
+ mpl::greater<precision_type, mpl::int_<0> >
+ >,
+ mpl::int_<113>, mpl::int_<0> >::type
+ >::type tag_type;
+ result = lgamma_small_imp<T>(z, T(z - 1), T(z - 2), tag_type(), pol, l);
+ }
+ else if((z >= 3) && (z < 100) && (std::numeric_limits<T>::max_exponent >= 1024))
+ {
+ // taking the log of tgamma reduces the error, no danger of overflow here:
+ result = log(gamma_imp(z, pol, l));
+ }
+ else
+ {
+ // regular evaluation:
+ T zgh = static_cast<T>(z + Lanczos::g() - boost::math::constants::half<T>());
+ result = log(zgh) - 1;
+ result *= z - 0.5f;
+ result += log(Lanczos::lanczos_sum_expG_scaled(z));
+ }
+
+ if(sign)
+ *sign = sresult;
+ return result;
+}
+
+//
+// Incomplete gamma functions follow:
+//
+template <class T>
+struct upper_incomplete_gamma_fract
+{
+private:
+ T z, a;
+ int k;
+public:
+ typedef std::pair<T,T> result_type;
+
+ upper_incomplete_gamma_fract(T a1, T z1)
+ : z(z1-a1+1), a(a1), k(0)
+ {
+ }
+
+ result_type operator()()
+ {
+ ++k;
+ z += 2;
+ return result_type(k * (a - k), z);
+ }
+};
+
+template <class T>
+inline T upper_gamma_fraction(T a, T z, T eps)
+{
+ // Multiply result by z^a * e^-z to get the full
+ // upper incomplete integral. Divide by tgamma(z)
+ // to normalise.
+ upper_incomplete_gamma_fract<T> f(a, z);
+ return 1 / (z - a + 1 + boost::math::tools::continued_fraction_a(f, eps));
+}
+
+template <class T>
+struct lower_incomplete_gamma_series
+{
+private:
+ T a, z, result;
+public:
+ typedef T result_type;
+ lower_incomplete_gamma_series(T a1, T z1) : a(a1), z(z1), result(1){}
+
+ T operator()()
+ {
+ T r = result;
+ a += 1;
+ result *= z/a;
+ return r;
+ }
+};
+
+template <class T, class Policy>
+inline T lower_gamma_series(T a, T z, const Policy& pol, T init_value = 0)
+{
+ // Multiply result by ((z^a) * (e^-z) / a) to get the full
+ // lower incomplete integral. Then divide by tgamma(a)
+ // to get the normalised value.
+ lower_incomplete_gamma_series<T> s(a, z);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+ T factor = policies::get_epsilon<T, Policy>();
+ T result = boost::math::tools::sum_series(s, factor, max_iter, init_value);
+ policies::check_series_iterations<T>("boost::math::detail::lower_gamma_series<%1%>(%1%)", max_iter, pol);
+ return result;
+}
+
+//
+// Fully generic tgamma and lgamma use Stirling's approximation
+// with Bernoulli numbers.
+//
+template<class T>
+std::size_t highest_bernoulli_index()
+{
+ const float digits10_of_type = (std::numeric_limits<T>::is_specialized
+ ? static_cast<float>(std::numeric_limits<T>::digits10)
+ : static_cast<float>(boost::math::tools::digits<T>() * 0.301F));
+
+ // Find the high index n for Bn to produce the desired precision in Stirling's calculation.
+ return static_cast<std::size_t>(18.0F + (0.6F * digits10_of_type));
+}
+
+template<class T>
+T minimum_argument_for_bernoulli_recursion()
+{
+ const float digits10_of_type = (std::numeric_limits<T>::is_specialized
+ ? static_cast<float>(std::numeric_limits<T>::digits10)
+ : static_cast<float>(boost::math::tools::digits<T>() * 0.301F));
+
+ return T(digits10_of_type * 1.7F);
+}
+
+// Forward declaration of the lgamma_imp template specialization.
+template <class T, class Policy>
+T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign = 0);
+
+template <class T, class Policy>
+T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&)
+{
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::tgamma<%1%>(%1%)";
+
+ // Check if the argument of tgamma is identically zero.
+ const bool is_at_zero = (z == 0);
+
+ if(is_at_zero)
+ return policies::raise_domain_error<T>(function, "Evaluation of tgamma at zero %1%.", z, pol);
+
+ const bool b_neg = (z < 0);
+
+ const bool floor_of_z_is_equal_to_z = (floor(z) == z);
+
+ // Special case handling of small factorials:
+ if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial<T>::value))
+ {
+ return boost::math::unchecked_factorial<T>(itrunc(z) - 1);
+ }
+
+ // Make a local, unsigned copy of the input argument.
+ T zz((!b_neg) ? z : -z);
+
+ // Special case for ultra-small z:
+ if(zz < tools::cbrt_epsilon<T>())
+ {
+ const T a0(1);
+ const T a1(boost::math::constants::euler<T>());
+ const T six_euler_squared((boost::math::constants::euler<T>() * boost::math::constants::euler<T>()) * 6);
+ const T a2((six_euler_squared - boost::math::constants::pi_sqr<T>()) / 12);
+
+ const T inverse_tgamma_series = z * ((a2 * z + a1) * z + a0);
+
+ return 1 / inverse_tgamma_series;
+ }
+
+ // Scale the argument up for the calculation of lgamma,
+ // and use downward recursion later for the final result.
+ const T min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
+
+ int n_recur;
+
+ if(zz < min_arg_for_recursion)
+ {
+ n_recur = boost::math::itrunc(min_arg_for_recursion - zz) + 1;
+
+ zz += n_recur;
+ }
+ else
+ {
+ n_recur = 0;
+ }
+
+ const T log_gamma_value = lgamma_imp(zz, pol, lanczos::undefined_lanczos());
+
+ if(log_gamma_value > tools::log_max_value<T>())
+ return policies::raise_overflow_error<T>(function, 0, pol);
+
+ T gamma_value = exp(log_gamma_value);
+
+ // Rescale the result using downward recursion if necessary.
+ if(n_recur)
+ {
+ // The order of divides is important, if we keep subtracting 1 from zz
+ // we DO NOT get back to z (cancellation error). Further if z < epsilon
+ // we would end up dividing by zero. Also in order to prevent spurious
+ // overflow with the first division, we must save dividing by |z| till last,
+ // so the optimal order of divides is z+1, z+2, z+3...z+n_recur-1,z.
+ zz = fabs(z) + 1;
+ for(int k = 1; k < n_recur; ++k)
+ {
+ gamma_value /= zz;
+ zz += 1;
+ }
+ gamma_value /= fabs(z);
+ }
+
+ // Return the result, accounting for possible negative arguments.
+ if(b_neg)
+ {
+ // Provide special error analysis for:
+ // * arguments in the neighborhood of a negative integer
+ // * arguments exactly equal to a negative integer.
+
+ // Check if the argument of tgamma is exactly equal to a negative integer.
+ if(floor_of_z_is_equal_to_z)
+ return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
+
+ gamma_value *= sinpx(z);
+
+ BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value);
+
+ const bool result_is_too_large_to_represent = ( (abs(gamma_value) < 1)
+ && ((tools::max_value<T>() * abs(gamma_value)) < boost::math::constants::pi<T>()));
+
+ if(result_is_too_large_to_represent)
+ return policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+
+ gamma_value = -boost::math::constants::pi<T>() / gamma_value;
+ BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value);
+
+ if(gamma_value == 0)
+ return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
+
+ if((boost::math::fpclassify)(gamma_value) == static_cast<int>(FP_SUBNORMAL))
+ return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", gamma_value, pol);
+ }
+
+ return gamma_value;
+}
+
+template <class T, class Policy>
+T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign)
+{
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::lgamma<%1%>(%1%)";
+
+ // Check if the argument of lgamma is identically zero.
+ const bool is_at_zero = (z == 0);
+
+ if(is_at_zero)
+ return policies::raise_domain_error<T>(function, "Evaluation of lgamma at zero %1%.", z, pol);
+
+ const bool b_neg = (z < 0);
+
+ const bool floor_of_z_is_equal_to_z = (floor(z) == z);
+
+ // Special case handling of small factorials:
+ if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial<T>::value))
+ {
+ return log(boost::math::unchecked_factorial<T>(itrunc(z) - 1));
+ }
+
+ // Make a local, unsigned copy of the input argument.
+ T zz((!b_neg) ? z : -z);
+
+ const T min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
+
+ T log_gamma_value;
+
+ if (zz < min_arg_for_recursion)
+ {
+ // Here we simply take the logarithm of tgamma(). This is somewhat
+ // inefficient, but simple. The rationale is that the argument here
+ // is relatively small and overflow is not expected to be likely.
+ if (z > -tools::root_epsilon<T>())
+ {
+ // Reflection formula may fail if z is very close to zero, let the series
+ // expansion for tgamma close to zero do the work:
+ log_gamma_value = log(abs(gamma_imp(z, pol, lanczos::undefined_lanczos())));
+ if (sign)
+ {
+ *sign = z < 0 ? -1 : 1;
+ }
+ return log_gamma_value;
+ }
+ else
+ {
+ // No issue with spurious overflow in reflection formula,
+ // just fall through to regular code:
+ log_gamma_value = log(abs(gamma_imp(zz, pol, lanczos::undefined_lanczos())));
+ }
+ }
+ else
+ {
+ // Perform the Bernoulli series expansion of Stirling's approximation.
+
+ const std::size_t number_of_bernoullis_b2n = highest_bernoulli_index<T>();
+
+ T one_over_x_pow_two_n_minus_one = 1 / zz;
+ const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one;
+ T sum = (boost::math::bernoulli_b2n<T>(1) / 2) * one_over_x_pow_two_n_minus_one;
+ const T target_epsilon_to_break_loop = (sum * boost::math::tools::epsilon<T>()) * T(1.0E-10F);
+
+ for(std::size_t n = 2U; n < number_of_bernoullis_b2n; ++n)
+ {
+ one_over_x_pow_two_n_minus_one *= one_over_x2;
+
+ const std::size_t n2 = static_cast<std::size_t>(n * 2U);
+
+ const T term = (boost::math::bernoulli_b2n<T>(static_cast<int>(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U));
+
+ if((n >= 8U) && (abs(term) < target_epsilon_to_break_loop))
+ {
+ // We have reached the desired precision in Stirling's expansion.
+ // Adding additional terms to the sum of this divergent asymptotic
+ // expansion will not improve the result.
+
+ // Break from the loop.
+ break;
+ }
+
+ sum += term;
+ }
+
+ // Complete Stirling's approximation.
+ const T half_ln_two_pi = log(boost::math::constants::two_pi<T>()) / 2;
+
+ log_gamma_value = ((((zz - boost::math::constants::half<T>()) * log(zz)) - zz) + half_ln_two_pi) + sum;
+ }
+
+ int sign_of_result = 1;
+
+ if(b_neg)
+ {
+ // Provide special error analysis if the argument is exactly
+ // equal to a negative integer.
+
+ // Check if the argument of lgamma is exactly equal to a negative integer.
+ if(floor_of_z_is_equal_to_z)
+ return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
+
+ T t = sinpx(z);
+
+ if(t < 0)
+ {
+ t = -t;
+ }
+ else
+ {
+ sign_of_result = -sign_of_result;
+ }
+
+ log_gamma_value = - log_gamma_value
+ + log(boost::math::constants::pi<T>())
+ - log(t);
+ }
+
+ if(sign != static_cast<int*>(0U)) { *sign = sign_of_result; }
+
+ return log_gamma_value;
+}
+
+//
+// This helper calculates tgamma(dz+1)-1 without cancellation errors,
+// used by the upper incomplete gamma with z < 1:
+//
+template <class T, class Policy, class Lanczos>
+T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l)
+{
+ BOOST_MATH_STD_USING
+
+ typedef typename policies::precision<T,Policy>::type precision_type;
+
+ typedef typename mpl::if_<
+ mpl::or_<
+ mpl::less_equal<precision_type, mpl::int_<0> >,
+ mpl::greater<precision_type, mpl::int_<113> >
+ >,
+ typename mpl::if_<
+ is_same<Lanczos, lanczos::lanczos24m113>,
+ mpl::int_<113>,
+ mpl::int_<0>
+ >::type,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>, mpl::int_<113> >::type
+ >::type tag_type;
+
+ T result;
+ if(dz < 0)
+ {
+ if(dz < -0.5)
+ {
+ // Best method is simply to subtract 1 from tgamma:
+ result = boost::math::tgamma(1+dz, pol) - 1;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ else
+ {
+ // Use expm1 on lgamma:
+ result = boost::math::expm1(-boost::math::log1p(dz, pol)
+ + lgamma_small_imp<T>(dz+2, dz + 1, dz, tag_type(), pol, l));
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ }
+ else
+ {
+ if(dz < 2)
+ {
+ // Use expm1 on lgamma:
+ result = boost::math::expm1(lgamma_small_imp<T>(dz+1, dz, dz-1, tag_type(), pol, l), pol);
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ else
+ {
+ // Best method is simply to subtract 1 from tgamma:
+ result = boost::math::tgamma(1+dz, pol) - 1;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ }
+
+ return result;
+}
+
+template <class T, class Policy>
+inline T tgammap1m1_imp(T dz, Policy const& pol,
+ const ::boost::math::lanczos::undefined_lanczos& l)
+{
+ BOOST_MATH_STD_USING // ADL of std names
+ //
+ // There should be a better solution than this, but the
+ // algebra isn't easy for the general case....
+ // Start by subracting 1 from tgamma:
+ //
+ T result = gamma_imp(T(1 + dz), pol, l) - 1;
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ //
+ // Test the level of cancellation error observed: we loose one bit
+ // for each power of 2 the result is less than 1. If we would get
+ // more bits from our most precise lgamma rational approximation,
+ // then use that instead:
+ //
+ BOOST_MATH_INSTRUMENT_CODE((dz > -0.5));
+ BOOST_MATH_INSTRUMENT_CODE((dz < 2));
+ BOOST_MATH_INSTRUMENT_CODE((ldexp(1.0, boost::math::policies::digits<T, Policy>()) * fabs(result) < 1e34));
+ if((dz > -0.5) && (dz < 2) && (ldexp(1.0, boost::math::policies::digits<T, Policy>()) * fabs(result) < 1e34))
+ {
+ result = tgammap1m1_imp(dz, pol, boost::math::lanczos::lanczos24m113());
+ BOOST_MATH_INSTRUMENT_CODE(result);
+ }
+ return result;
+}
+
+//
+// Series representation for upper fraction when z is small:
+//
+template <class T>
+struct small_gamma2_series
+{
+ typedef T result_type;
+
+ small_gamma2_series(T a_, T x_) : result(-x_), x(-x_), apn(a_+1), n(1){}
+
+ T operator()()
+ {
+ T r = result / (apn);
+ result *= x;
+ result /= ++n;
+ apn += 1;
+ return r;
+ }
+
+private:
+ T result, x, apn;
+ int n;
+};
+//
+// calculate power term prefix (z^a)(e^-z) used in the non-normalised
+// incomplete gammas:
+//
+template <class T, class Policy>
+T full_igamma_prefix(T a, T z, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ T prefix;
+ T alz = a * log(z);
+
+ if(z >= 1)
+ {
+ if((alz < tools::log_max_value<T>()) && (-z > tools::log_min_value<T>()))
+ {
+ prefix = pow(z, a) * exp(-z);
+ }
+ else if(a >= 1)
+ {
+ prefix = pow(z / exp(z/a), a);
+ }
+ else
+ {
+ prefix = exp(alz - z);
+ }
+ }
+ else
+ {
+ if(alz > tools::log_min_value<T>())
+ {
+ prefix = pow(z, a) * exp(-z);
+ }
+ else if(z/a < tools::log_max_value<T>())
+ {
+ prefix = pow(z / exp(z/a), a);
+ }
+ else
+ {
+ prefix = exp(alz - z);
+ }
+ }
+ //
+ // This error handling isn't very good: it happens after the fact
+ // rather than before it...
+ //
+ if((boost::math::fpclassify)(prefix) == (int)FP_INFINITE)
+ return policies::raise_overflow_error<T>("boost::math::detail::full_igamma_prefix<%1%>(%1%, %1%)", "Result of incomplete gamma function is too large to represent.", pol);
+
+ return prefix;
+}
+//
+// Compute (z^a)(e^-z)/tgamma(a)
+// most if the error occurs in this function:
+//
+template <class T, class Policy, class Lanczos>
+T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l)
+{
+ BOOST_MATH_STD_USING
+ T agh = a + static_cast<T>(Lanczos::g()) - T(0.5);
+ T prefix;
+ T d = ((z - a) - static_cast<T>(Lanczos::g()) + T(0.5)) / agh;
+
+ if(a < 1)
+ {
+ //
+ // We have to treat a < 1 as a special case because our Lanczos
+ // approximations are optimised against the factorials with a > 1,
+ // and for high precision types especially (128-bit reals for example)
+ // very small values of a can give rather eroneous results for gamma
+ // unless we do this:
+ //
+ // TODO: is this still required? Lanczos approx should be better now?
+ //
+ if(z <= tools::log_min_value<T>())
+ {
+ // Oh dear, have to use logs, should be free of cancellation errors though:
+ return exp(a * log(z) - z - lgamma_imp(a, pol, l));
+ }
+ else
+ {
+ // direct calculation, no danger of overflow as gamma(a) < 1/a
+ // for small a.
+ return pow(z, a) * exp(-z) / gamma_imp(a, pol, l);
+ }
+ }
+ else if((fabs(d*d*a) <= 100) && (a > 150))
+ {
+ // special case for large a and a ~ z.
+ prefix = a * boost::math::log1pmx(d, pol) + z * static_cast<T>(0.5 - Lanczos::g()) / agh;
+ prefix = exp(prefix);
+ }
+ else
+ {
+ //
+ // general case.
+ // direct computation is most accurate, but use various fallbacks
+ // for different parts of the problem domain:
+ //
+ T alz = a * log(z / agh);
+ T amz = a - z;
+ if(((std::min)(alz, amz) <= tools::log_min_value<T>()) || ((std::max)(alz, amz) >= tools::log_max_value<T>()))
+ {
+ T amza = amz / a;
+ if(((std::min)(alz, amz)/2 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/2 < tools::log_max_value<T>()))
+ {
+ // compute square root of the result and then square it:
+ T sq = pow(z / agh, a / 2) * exp(amz / 2);
+ prefix = sq * sq;
+ }
+ else if(((std::min)(alz, amz)/4 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/4 < tools::log_max_value<T>()) && (z > a))
+ {
+ // compute the 4th root of the result then square it twice:
+ T sq = pow(z / agh, a / 4) * exp(amz / 4);
+ prefix = sq * sq;
+ prefix *= prefix;
+ }
+ else if((amza > tools::log_min_value<T>()) && (amza < tools::log_max_value<T>()))
+ {
+ prefix = pow((z * exp(amza)) / agh, a);
+ }
+ else
+ {
+ prefix = exp(alz + amz);
+ }
+ }
+ else
+ {
+ prefix = pow(z / agh, a) * exp(amz);
+ }
+ }
+ prefix *= sqrt(agh / boost::math::constants::e<T>()) / Lanczos::lanczos_sum_expG_scaled(a);
+ return prefix;
+}
+//
+// And again, without Lanczos support:
+//
+template <class T, class Policy>
+T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined_lanczos&)
+{
+ BOOST_MATH_STD_USING
+
+ T limit = (std::max)(T(10), a);
+ T sum = detail::lower_gamma_series(a, limit, pol) / a;
+ sum += detail::upper_gamma_fraction(a, limit, ::boost::math::policies::get_epsilon<T, Policy>());
+
+ if(a < 10)
+ {
+ // special case for small a:
+ T prefix = pow(z / 10, a);
+ prefix *= exp(10-z);
+ if(0 == prefix)
+ {
+ prefix = pow((z * exp((10-z)/a)) / 10, a);
+ }
+ prefix /= sum;
+ return prefix;
+ }
+
+ T zoa = z / a;
+ T amz = a - z;
+ T alzoa = a * log(zoa);
+ T prefix;
+ if(((std::min)(alzoa, amz) <= tools::log_min_value<T>()) || ((std::max)(alzoa, amz) >= tools::log_max_value<T>()))
+ {
+ T amza = amz / a;
+ if((amza <= tools::log_min_value<T>()) || (amza >= tools::log_max_value<T>()))
+ {
+ prefix = exp(alzoa + amz);
+ }
+ else
+ {
+ prefix = pow(zoa * exp(amza), a);
+ }
+ }
+ else
+ {
+ prefix = pow(zoa, a) * exp(amz);
+ }
+ prefix /= sum;
+ return prefix;
+}
+//
+// Upper gamma fraction for very small a:
+//
+template <class T, class Policy>
+inline T tgamma_small_upper_part(T a, T x, const Policy& pol, T* pgam = 0, bool invert = false, T* pderivative = 0)
+{
+ BOOST_MATH_STD_USING // ADL of std functions.
+ //
+ // Compute the full upper fraction (Q) when a is very small:
+ //
+ T result;
+ result = boost::math::tgamma1pm1(a, pol);
+ if(pgam)
+ *pgam = (result + 1) / a;
+ T p = boost::math::powm1(x, a, pol);
+ result -= p;
+ result /= a;
+ detail::small_gamma2_series<T> s(a, x);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>() - 10;
+ p += 1;
+ if(pderivative)
+ *pderivative = p / (*pgam * exp(x));
+ T init_value = invert ? *pgam : 0;
+ result = -p * tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, (init_value - result) / p);
+ policies::check_series_iterations<T>("boost::math::tgamma_small_upper_part<%1%>(%1%, %1%)", max_iter, pol);
+ if(invert)
+ result = -result;
+ return result;
+}
+//
+// Upper gamma fraction for integer a:
+//
+template <class T, class Policy>
+inline T finite_gamma_q(T a, T x, Policy const& pol, T* pderivative = 0)
+{
+ //
+ // Calculates normalised Q when a is an integer:
+ //
+ BOOST_MATH_STD_USING
+ T e = exp(-x);
+ T sum = e;
+ if(sum != 0)
+ {
+ T term = sum;
+ for(unsigned n = 1; n < a; ++n)
+ {
+ term /= n;
+ term *= x;
+ sum += term;
+ }
+ }
+ if(pderivative)
+ {
+ *pderivative = e * pow(x, a) / boost::math::unchecked_factorial<T>(itrunc(T(a - 1), pol));
+ }
+ return sum;
+}
+//
+// Upper gamma fraction for half integer a:
+//
+template <class T, class Policy>
+T finite_half_gamma_q(T a, T x, T* p_derivative, const Policy& pol)
+{
+ //
+ // Calculates normalised Q when a is a half-integer:
+ //
+ BOOST_MATH_STD_USING
+ T e = boost::math::erfc(sqrt(x), pol);
+ if((e != 0) && (a > 1))
+ {
+ T term = exp(-x) / sqrt(constants::pi<T>() * x);
+ term *= x;
+ static const T half = T(1) / 2;
+ term /= half;
+ T sum = term;
+ for(unsigned n = 2; n < a; ++n)
+ {
+ term /= n - half;
+ term *= x;
+ sum += term;
+ }
+ e += sum;
+ if(p_derivative)
+ {
+ *p_derivative = 0;
+ }
+ }
+ else if(p_derivative)
+ {
+ // We'll be dividing by x later, so calculate derivative * x:
+ *p_derivative = sqrt(x) * exp(-x) / constants::root_pi<T>();
+ }
+ return e;
+}
+//
+// Main incomplete gamma entry point, handles all four incomplete gamma's:
+//
+template <class T, class Policy>
+T gamma_incomplete_imp(T a, T x, bool normalised, bool invert,
+ const Policy& pol, T* p_derivative)
+{
+ static const char* function = "boost::math::gamma_p<%1%>(%1%, %1%)";
+ if(a <= 0)
+ return policies::raise_domain_error<T>(function, "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
+ if(x < 0)
+ return policies::raise_domain_error<T>(function, "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
+
+ BOOST_MATH_STD_USING
+
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+
+ T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used
+
+ BOOST_ASSERT((p_derivative == 0) || (normalised == true));
+
+ bool is_int, is_half_int;
+ bool is_small_a = (a < 30) && (a <= x + 1) && (x < tools::log_max_value<T>());
+ if(is_small_a)
+ {
+ T fa = floor(a);
+ is_int = (fa == a);
+ is_half_int = is_int ? false : (fabs(fa - a) == 0.5f);
+ }
+ else
+ {
+ is_int = is_half_int = false;
+ }
+
+ int eval_method;
+
+ if(is_int && (x > 0.6))
+ {
+ // calculate Q via finite sum:
+ invert = !invert;
+ eval_method = 0;
+ }
+ else if(is_half_int && (x > 0.2))
+ {
+ // calculate Q via finite sum for half integer a:
+ invert = !invert;
+ eval_method = 1;
+ }
+ else if(x < 0.5)
+ {
+ //
+ // Changeover criterion chosen to give a changeover at Q ~ 0.33
+ //
+ if(-0.4 / log(x) < a)
+ {
+ eval_method = 2;
+ }
+ else
+ {
+ eval_method = 3;
+ }
+ }
+ else if(x < 1.1)
+ {
+ //
+ // Changover here occurs when P ~ 0.75 or Q ~ 0.25:
+ //
+ if(x * 0.75f < a)
+ {
+ eval_method = 2;
+ }
+ else
+ {
+ eval_method = 3;
+ }
+ }
+ else
+ {
+ //
+ // Begin by testing whether we're in the "bad" zone
+ // where the result will be near 0.5 and the usual
+ // series and continued fractions are slow to converge:
+ //
+ bool use_temme = false;
+ if(normalised && std::numeric_limits<T>::is_specialized && (a > 20))
+ {
+ T sigma = fabs((x-a)/a);
+ if((a > 200) && (policies::digits<T, Policy>() <= 113))
+ {
+ //
+ // This limit is chosen so that we use Temme's expansion
+ // only if the result would be larger than about 10^-6.
+ // Below that the regular series and continued fractions
+ // converge OK, and if we use Temme's method we get increasing
+ // errors from the dominant erfc term as it's (inexact) argument
+ // increases in magnitude.
+ //
+ if(20 / a > sigma * sigma)
+ use_temme = true;
+ }
+ else if(policies::digits<T, Policy>() <= 64)
+ {
+ // Note in this zone we can't use Temme's expansion for
+ // types longer than an 80-bit real:
+ // it would require too many terms in the polynomials.
+ if(sigma < 0.4)
+ use_temme = true;
+ }
+ }
+ if(use_temme)
+ {
+ eval_method = 5;
+ }
+ else
+ {
+ //
+ // Regular case where the result will not be too close to 0.5.
+ //
+ // Changeover here occurs at P ~ Q ~ 0.5
+ // Note that series computation of P is about x2 faster than continued fraction
+ // calculation of Q, so try and use the CF only when really necessary, especially
+ // for small x.
+ //
+ if(x - (1 / (3 * x)) < a)
+ {
+ eval_method = 2;
+ }
+ else
+ {
+ eval_method = 4;
+ invert = !invert;
+ }
+ }
+ }
+
+ switch(eval_method)
+ {
+ case 0:
+ {
+ result = finite_gamma_q(a, x, pol, p_derivative);
+ if(normalised == false)
+ result *= boost::math::tgamma(a, pol);
+ break;
+ }
+ case 1:
+ {
+ result = finite_half_gamma_q(a, x, p_derivative, pol);
+ if(normalised == false)
+ result *= boost::math::tgamma(a, pol);
+ if(p_derivative && (*p_derivative == 0))
+ *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
+ break;
+ }
+ case 2:
+ {
+ // Compute P:
+ result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
+ if(p_derivative)
+ *p_derivative = result;
+ if(result != 0)
+ {
+ T init_value = 0;
+ if(invert)
+ {
+ init_value = -a * (normalised ? 1 : boost::math::tgamma(a, pol)) / result;
+ }
+ result *= detail::lower_gamma_series(a, x, pol, init_value) / a;
+ if(invert)
+ {
+ invert = false;
+ result = -result;
+ }
+ }
+ break;
+ }
+ case 3:
+ {
+ // Compute Q:
+ invert = !invert;
+ T g;
+ result = tgamma_small_upper_part(a, x, pol, &g, invert, p_derivative);
+ invert = false;
+ if(normalised)
+ result /= g;
+ break;
+ }
+ case 4:
+ {
+ // Compute Q:
+ result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
+ if(p_derivative)
+ *p_derivative = result;
+ if(result != 0)
+ result *= upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>());
+ break;
+ }
+ case 5:
+ {
+ //
+ // Use compile time dispatch to the appropriate
+ // Temme asymptotic expansion. This may be dead code
+ // if T does not have numeric limits support, or has
+ // too many digits for the most precise version of
+ // these expansions, in that case we'll be calling
+ // an empty function.
+ //
+ typedef typename policies::precision<T, Policy>::type precision_type;
+
+ typedef typename mpl::if_<
+ mpl::or_<mpl::equal_to<precision_type, mpl::int_<0> >,
+ mpl::greater<precision_type, mpl::int_<113> > >,
+ mpl::int_<0>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<53> >,
+ mpl::int_<53>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>,
+ mpl::int_<113>
+ >::type
+ >::type
+ >::type tag_type;
+
+ result = igamma_temme_large(a, x, pol, static_cast<tag_type const*>(0));
+ if(x >= a)
+ invert = !invert;
+ if(p_derivative)
+ *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
+ break;
+ }
+ }
+
+ if(normalised && (result > 1))
+ result = 1;
+ if(invert)
+ {
+ T gam = normalised ? 1 : boost::math::tgamma(a, pol);
+ result = gam - result;
+ }
+ if(p_derivative)
+ {
+ //
+ // Need to convert prefix term to derivative:
+ //
+ if((x < 1) && (tools::max_value<T>() * x < *p_derivative))
+ {
+ // overflow, just return an arbitrarily large value:
+ *p_derivative = tools::max_value<T>() / 2;
+ }
+
+ *p_derivative /= x;
+ }
+
+ return result;
+}
+
+//
+// Ratios of two gamma functions:
+//
+template <class T, class Policy, class Lanczos>
+T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& l)
+{
+ BOOST_MATH_STD_USING
+ if(z < tools::epsilon<T>())
+ {
+ //
+ // We get spurious numeric overflow unless we're very careful, this
+ // can occur either inside Lanczos::lanczos_sum(z) or in the
+ // final combination of terms, to avoid this, split the product up
+ // into 2 (or 3) parts:
+ //
+ // G(z) / G(L) = 1 / (z * G(L)) ; z < eps, L = z + delta = delta
+ // z * G(L) = z * G(lim) * (G(L)/G(lim)) ; lim = largest factorial
+ //
+ if(boost::math::max_factorial<T>::value < delta)
+ {
+ T ratio = tgamma_delta_ratio_imp_lanczos(delta, T(boost::math::max_factorial<T>::value - delta), pol, l);
+ ratio *= z;
+ ratio *= boost::math::unchecked_factorial<T>(boost::math::max_factorial<T>::value - 1);
+ return 1 / ratio;
+ }
+ else
+ {
+ return 1 / (z * boost::math::tgamma(z + delta, pol));
+ }
+ }
+ T zgh = z + Lanczos::g() - constants::half<T>();
+ T result;
+ if(fabs(delta) < 10)
+ {
+ result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
+ }
+ else
+ {
+ result = pow(zgh / (zgh + delta), z - constants::half<T>());
+ }
+ // Split the calculation up to avoid spurious overflow:
+ result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta));
+ result *= pow(constants::e<T>() / (zgh + delta), delta);
+ return result;
+}
+//
+// And again without Lanczos support this time:
+//
+template <class T, class Policy>
+T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos::undefined_lanczos&)
+{
+ BOOST_MATH_STD_USING
+ //
+ // The upper gamma fraction is *very* slow for z < 6, actually it's very
+ // slow to converge everywhere but recursing until z > 6 gets rid of the
+ // worst of it's behaviour.
+ //
+ T prefix = 1;
+ T zd = z + delta;
+ while((zd < 6) && (z < 6))
+ {
+ prefix /= z;
+ prefix *= zd;
+ z += 1;
+ zd += 1;
+ }
+ if(delta < 10)
+ {
+ prefix *= exp(-z * boost::math::log1p(delta / z, pol));
+ }
+ else
+ {
+ prefix *= pow(z / zd, z);
+ }
+ prefix *= pow(constants::e<T>() / zd, delta);
+ T sum = detail::lower_gamma_series(z, z, pol) / z;
+ sum += detail::upper_gamma_fraction(z, z, ::boost::math::policies::get_epsilon<T, Policy>());
+ T sumd = detail::lower_gamma_series(zd, zd, pol) / zd;
+ sumd += detail::upper_gamma_fraction(zd, zd, ::boost::math::policies::get_epsilon<T, Policy>());
+ sum /= sumd;
+ if(fabs(tools::max_value<T>() / prefix) < fabs(sum))
+ return policies::raise_overflow_error<T>("boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)", "Result of tgamma is too large to represent.", pol);
+ return sum * prefix;
+}
+
+template <class T, class Policy>
+T tgamma_delta_ratio_imp(T z, T delta, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ if((z <= 0) || (z + delta <= 0))
+ {
+ // This isn't very sofisticated, or accurate, but it does work:
+ return boost::math::tgamma(z, pol) / boost::math::tgamma(z + delta, pol);
+ }
+
+ if(floor(delta) == delta)
+ {
+ if(floor(z) == z)
+ {
+ //
+ // Both z and delta are integers, see if we can just use table lookup
+ // of the factorials to get the result:
+ //
+ if((z <= max_factorial<T>::value) && (z + delta <= max_factorial<T>::value))
+ {
+ return unchecked_factorial<T>((unsigned)itrunc(z, pol) - 1) / unchecked_factorial<T>((unsigned)itrunc(T(z + delta), pol) - 1);
+ }
+ }
+ if(fabs(delta) < 20)
+ {
+ //
+ // delta is a small integer, we can use a finite product:
+ //
+ if(delta == 0)
+ return 1;
+ if(delta < 0)
+ {
+ z -= 1;
+ T result = z;
+ while(0 != (delta += 1))
+ {
+ z -= 1;
+ result *= z;
+ }
+ return result;
+ }
+ else
+ {
+ T result = 1 / z;
+ while(0 != (delta -= 1))
+ {
+ z += 1;
+ result /= z;
+ }
+ return result;
+ }
+ }
+ }
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+ return tgamma_delta_ratio_imp_lanczos(z, delta, pol, lanczos_type());
+}
+
+template <class T, class Policy>
+T tgamma_ratio_imp(T x, T y, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ if((x <= 0) || (boost::math::isinf)(x))
+ return policies::raise_domain_error<T>("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got a=%1%).", x, pol);
+ if((y <= 0) || (boost::math::isinf)(y))
+ return policies::raise_domain_error<T>("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got b=%1%).", y, pol);
+
+ if(x <= tools::min_value<T>())
+ {
+ // Special case for denorms...Ugh.
+ T shift = ldexp(T(1), tools::digits<T>());
+ return shift * tgamma_ratio_imp(T(x * shift), y, pol);
+ }
+
+ if((x < max_factorial<T>::value) && (y < max_factorial<T>::value))
+ {
+ // Rather than subtracting values, lets just call the gamma functions directly:
+ return boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
+ }
+ T prefix = 1;
+ if(x < 1)
+ {
+ if(y < 2 * max_factorial<T>::value)
+ {
+ // We need to sidestep on x as well, otherwise we'll underflow
+ // before we get to factor in the prefix term:
+ prefix /= x;
+ x += 1;
+ while(y >= max_factorial<T>::value)
+ {
+ y -= 1;
+ prefix /= y;
+ }
+ return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
+ }
+ //
+ // result is almost certainly going to underflow to zero, try logs just in case:
+ //
+ return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
+ }
+ if(y < 1)
+ {
+ if(x < 2 * max_factorial<T>::value)
+ {
+ // We need to sidestep on y as well, otherwise we'll overflow
+ // before we get to factor in the prefix term:
+ prefix *= y;
+ y += 1;
+ while(x >= max_factorial<T>::value)
+ {
+ x -= 1;
+ prefix *= x;
+ }
+ return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
+ }
+ //
+ // Result will almost certainly overflow, try logs just in case:
+ //
+ return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
+ }
+ //
+ // Regular case, x and y both large and similar in magnitude:
+ //
+ return boost::math::tgamma_delta_ratio(x, y - x, pol);
+}
+
+template <class T, class Policy>
+T gamma_p_derivative_imp(T a, T x, const Policy& pol)
+{
+ //
+ // Usual error checks first:
+ //
+ if(a <= 0)
+ return policies::raise_domain_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
+ if(x < 0)
+ return policies::raise_domain_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
+ //
+ // Now special cases:
+ //
+ if(x == 0)
+ {
+ return (a > 1) ? 0 :
+ (a == 1) ? 1 : policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", 0, pol);
+ }
+ //
+ // Normal case:
+ //
+ typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+ T f1 = detail::regularised_gamma_prefix(a, x, pol, lanczos_type());
+ if((x < 1) && (tools::max_value<T>() * x < f1))
+ {
+ // overflow:
+ return policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", 0, pol);
+ }
+
+ f1 /= x;
+
+ return f1;
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type
+ tgamma(T z, const Policy& /* pol */, const mpl::true_)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::gamma_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma<%1%>(%1%)");
+}
+
+template <class T, class Policy>
+struct igamma_initializer
+{
+ struct init
+ {
+ init()
+ {
+ typedef typename policies::precision<T, Policy>::type precision_type;
+
+ typedef typename mpl::if_<
+ mpl::or_<mpl::equal_to<precision_type, mpl::int_<0> >,
+ mpl::greater<precision_type, mpl::int_<113> > >,
+ mpl::int_<0>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<53> >,
+ mpl::int_<53>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>,
+ mpl::int_<113>
+ >::type
+ >::type
+ >::type tag_type;
+
+ do_init(tag_type());
+ }
+ template <int N>
+ static void do_init(const mpl::int_<N>&)
+ {
+ boost::math::gamma_p(static_cast<T>(400), static_cast<T>(400), Policy());
+ }
+ static void do_init(const mpl::int_<53>&){}
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy>
+const typename igamma_initializer<T, Policy>::init igamma_initializer<T, Policy>::initializer;
+
+template <class T, class Policy>
+struct lgamma_initializer
+{
+ struct init
+ {
+ init()
+ {
+ typedef typename policies::precision<T, Policy>::type precision_type;
+ typedef typename mpl::if_<
+ mpl::and_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::greater<precision_type, mpl::int_<0> >
+ >,
+ mpl::int_<64>,
+ typename mpl::if_<
+ mpl::and_<
+ mpl::less_equal<precision_type, mpl::int_<113> >,
+ mpl::greater<precision_type, mpl::int_<0> >
+ >,
+ mpl::int_<113>, mpl::int_<0> >::type
+ >::type tag_type;
+ do_init(tag_type());
+ }
+ static void do_init(const mpl::int_<64>&)
+ {
+ boost::math::lgamma(static_cast<T>(2.5), Policy());
+ boost::math::lgamma(static_cast<T>(1.25), Policy());
+ boost::math::lgamma(static_cast<T>(1.75), Policy());
+ }
+ static void do_init(const mpl::int_<113>&)
+ {
+ boost::math::lgamma(static_cast<T>(2.5), Policy());
+ boost::math::lgamma(static_cast<T>(1.25), Policy());
+ boost::math::lgamma(static_cast<T>(1.5), Policy());
+ boost::math::lgamma(static_cast<T>(1.75), Policy());
+ }
+ static void do_init(const mpl::int_<0>&)
+ {
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy>
+const typename lgamma_initializer<T, Policy>::init lgamma_initializer<T, Policy>::initializer;
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma(T1 a, T2 z, const Policy&, const mpl::false_)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::gamma_incomplete_imp(static_cast<value_type>(a),
+ static_cast<value_type>(z), false, true,
+ forwarding_policy(), static_cast<value_type*>(0)), "boost::math::tgamma<%1%>(%1%, %1%)");
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma(T1 a, T2 z, const mpl::false_ tag)
+{
+ return tgamma(a, z, policies::policy<>(), tag);
+}
+
+
+} // namespace detail
+
+template <class T>
+inline typename tools::promote_args<T>::type
+ tgamma(T z)
+{
+ return tgamma(z, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type
+ lgamma(T z, int* sign, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ detail::lgamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::lgamma_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type(), sign), "boost::math::lgamma<%1%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+ lgamma(T z, int* sign)
+{
+ return lgamma(z, sign, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type
+ lgamma(T x, const Policy& pol)
+{
+ return ::boost::math::lgamma(x, 0, pol);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+ lgamma(T x)
+{
+ return ::boost::math::lgamma(x, 0, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type
+ tgamma1pm1(T z, const Policy& /* pol */)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<typename remove_cv<result_type>::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+ tgamma1pm1(T z)
+{
+ return tgamma1pm1(z, policies::policy<>());
+}
+
+//
+// Full upper incomplete gamma:
+//
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma(T1 a, T2 z)
+{
+ //
+ // Type T2 could be a policy object, or a value, select the
+ // right overload based on T2:
+ //
+ typedef typename policies::is_policy<T2>::type maybe_policy;
+ return detail::tgamma(a, z, maybe_policy());
+}
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma(T1 a, T2 z, const Policy& pol)
+{
+ return detail::tgamma(a, z, pol, mpl::false_());
+}
+//
+// Full lower incomplete gamma:
+//
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma_lower(T1 a, T2 z, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::gamma_incomplete_imp(static_cast<value_type>(a),
+ static_cast<value_type>(z), false, false,
+ forwarding_policy(), static_cast<value_type*>(0)), "tgamma_lower<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma_lower(T1 a, T2 z)
+{
+ return tgamma_lower(a, z, policies::policy<>());
+}
+//
+// Regularised upper incomplete gamma:
+//
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_q(T1 a, T2 z, const Policy& /* pol */)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::gamma_incomplete_imp(static_cast<value_type>(a),
+ static_cast<value_type>(z), true, true,
+ forwarding_policy(), static_cast<value_type*>(0)), "gamma_q<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_q(T1 a, T2 z)
+{
+ return gamma_q(a, z, policies::policy<>());
+}
+//
+// Regularised lower incomplete gamma:
+//
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p(T1 a, T2 z, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::gamma_incomplete_imp(static_cast<value_type>(a),
+ static_cast<value_type>(z), true, false,
+ forwarding_policy(), static_cast<value_type*>(0)), "gamma_p<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p(T1 a, T2 z)
+{
+ return gamma_p(a, z, policies::policy<>());
+}
+
+// ratios of gamma functions:
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::tgamma_delta_ratio_imp(static_cast<value_type>(z), static_cast<value_type>(delta), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma_delta_ratio(T1 z, T2 delta)
+{
+ return tgamma_delta_ratio(z, delta, policies::policy<>());
+}
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma_ratio(T1 a, T2 b, const Policy&)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::tgamma_ratio_imp(static_cast<value_type>(a), static_cast<value_type>(b), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ tgamma_ratio(T1 a, T2 b)
+{
+ return tgamma_ratio(a, b, policies::policy<>());
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p_derivative(T1 a, T2 x, const Policy&)
+{
+ BOOST_FPU_EXCEPTION_GUARD
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::gamma_p_derivative_imp(static_cast<value_type>(a), static_cast<value_type>(x), forwarding_policy()), "boost::math::gamma_p_derivative<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ gamma_p_derivative(T1 a, T2 x)
+{
+ return gamma_p_derivative(a, x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#include <boost/math/special_functions/detail/igamma_inverse.hpp>
+#include <boost/math/special_functions/detail/gamma_inva.hpp>
+#include <boost/math/special_functions/erf.hpp>
+
+#endif // BOOST_MATH_SF_GAMMA_HPP
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/lanczos.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/lanczos.hpp
new file mode 100644
index 00000000000..0db21d3d169
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/lanczos.hpp
@@ -0,0 +1,1296 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/limits.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/policies/policy.hpp>
+#include <boost/mpl/less_equal.hpp>
+
+#include <limits.h>
+
+namespace boost{ namespace math{ namespace lanczos{
+
+//
+// Individual lanczos approximations start here.
+//
+// Optimal values for G for each N are taken from
+// http://web.mala.bc.ca/pughg/phdThesis/phdThesis.pdf,
+// as are the theoretical error bounds.
+//
+// Constants calculated using the method described by Godfrey
+// http://my.fit.edu/~gabdo/gamma.txt and elaborated by Toth at
+// http://www.rskey.org/gamma.htm using NTL::RR at 1000 bit precision.
+//
+// Begin with a small helper to force initialization of constants prior
+// to main. This makes the constant initialization thread safe, even
+// when called with a user-defined number type.
+//
+template <class Lanczos, class T>
+struct lanczos_initializer
+{
+ struct init
+ {
+ init()
+ {
+ T t(1);
+ Lanczos::lanczos_sum(t);
+ Lanczos::lanczos_sum_expG_scaled(t);
+ Lanczos::lanczos_sum_near_1(t);
+ Lanczos::lanczos_sum_near_2(t);
+ Lanczos::g();
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+template <class Lanczos, class T>
+typename lanczos_initializer<Lanczos, T>::init const lanczos_initializer<Lanczos, T>::initializer;
+//
+// Lanczos Coefficients for N=6 G=5.581
+// Max experimental error (with arbitary precision arithmetic) 9.516e-12
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos6 : public mpl::int_<35>
+{
+ //
+ // Produces slightly better than float precision when evaluated at
+ // double precision:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[6] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 8706.349592549009182288174442774377925882)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 8523.650341121874633477483696775067709735)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 3338.029219476423550899999750161289306564)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 653.6424994294008795995653541449610986791)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 63.99951844938187085666201263218840287667)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.506628274631006311133031631822390264407))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+ static_cast<boost::uint16_t>(0u),
+ static_cast<boost::uint16_t>(24u),
+ static_cast<boost::uint16_t>(50u),
+ static_cast<boost::uint16_t>(35u),
+ static_cast<boost::uint16_t>(10u),
+ static_cast<boost::uint16_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[6] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 32.81244541029783471623665933780748627823)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 32.12388941444332003446077108933558534361)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 12.58034729455216106950851080138931470954)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.463444478353241423633780693218408889251)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.2412010548258800231126240760264822486599)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.009446967704539249494420221613134244048319))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+ static_cast<boost::uint16_t>(0u),
+ static_cast<boost::uint16_t>(24u),
+ static_cast<boost::uint16_t>(50u),
+ static_cast<boost::uint16_t>(35u),
+ static_cast<boost::uint16_t>(10u),
+ static_cast<boost::uint16_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[5] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.044879010930422922760429926121241330235)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -2.751366405578505366591317846728753993668)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 1.02282965224225004296750609604264824677)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -0.09786124911582813985028889636665335893627)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.0009829742267506615183144364420540766510112)),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[5] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 5.748142489536043490764289256167080091892)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -7.734074268282457156081021756682138251825)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.875167944990511006997713242805893543947)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -0.2750873773533504542306766137703788781776)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.002763134585812698552178368447708846850353)),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 5.581000000000000405009359383257105946541; }
+};
+
+//
+// Lanczos Coefficients for N=11 G=10.900511
+// Max experimental error (with arbitary precision arithmetic) 2.16676e-19
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos11 : public mpl::int_<60>
+{
+ //
+ // Produces slightly better than double precision when evaluated at
+ // extended-double precision:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[11] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 38474670393.31776828316099004518914832218)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 36857665043.51950660081971227404959150474)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 15889202453.72942008945006665994637853242)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 4059208354.298834770194507810788393801607)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 680547661.1834733286087695557084801366446)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 78239755.00312005289816041245285376206263)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 6246580.776401795264013335510453568106366)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 341986.3488721347032223777872763188768288)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 12287.19451182455120096222044424100527629)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 261.6140441641668190791708576058805625502)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 2.506628274631000502415573855452633787834))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[11] = {
+ static_cast<boost::uint32_t>(0u),
+ static_cast<boost::uint32_t>(362880u),
+ static_cast<boost::uint32_t>(1026576u),
+ static_cast<boost::uint32_t>(1172700u),
+ static_cast<boost::uint32_t>(723680u),
+ static_cast<boost::uint32_t>(269325u),
+ static_cast<boost::uint32_t>(63273u),
+ static_cast<boost::uint32_t>(9450u),
+ static_cast<boost::uint32_t>(870u),
+ static_cast<boost::uint32_t>(45u),
+ static_cast<boost::uint32_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[11] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 709811.662581657956893540610814842699825)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 679979.847415722640161734319823103390728)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 293136.785721159725251629480984140341656)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 74887.5403291467179935942448101441897121)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 12555.29058241386295096255111537516768137)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 1443.42992444170669746078056942194198252)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 115.2419459613734722083208906727972935065)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 6.30923920573262762719523981992008976989)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.2266840463022436475495508977579735223818)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.004826466289237661857584712046231435101741)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.4624429436045378766270459638520555557321e-4))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[11] = {
+ static_cast<boost::uint32_t>(0u),
+ static_cast<boost::uint32_t>(362880u),
+ static_cast<boost::uint32_t>(1026576u),
+ static_cast<boost::uint32_t>(1172700u),
+ static_cast<boost::uint32_t>(723680u),
+ static_cast<boost::uint32_t>(269325u),
+ static_cast<boost::uint32_t>(63273u),
+ static_cast<boost::uint32_t>(9450u),
+ static_cast<boost::uint32_t>(870u),
+ static_cast<boost::uint32_t>(45u),
+ static_cast<boost::uint32_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[10] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 4.005853070677940377969080796551266387954)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -13.17044315127646469834125159673527183164)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 17.19146865350790353683895137079288129318)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -11.36446409067666626185701599196274701126)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 4.024801119349323770107694133829772634737)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.7445703262078094128346501724255463005006)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.06513861351917497265045550019547857713172)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.00217899958561830354633560009312512312758)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.17655204574495137651670832229571934738e-4)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.1036282091079938047775645941885460820853e-7)),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[10] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 19.05889633808148715159575716844556056056)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -62.66183664701721716960978577959655644762)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 81.7929198065004751699057192860287512027)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -54.06941772964234828416072865069196553015)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 19.14904664790693019642068229478769661515)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -3.542488556926667589704590409095331790317)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.3099140334815639910894627700232804503017)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.01036716187296241640634252431913030440825)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.8399926504443119927673843789048514017761e-4)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.493038376656195010308610694048822561263e-7)),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 10.90051099999999983936049829935654997826; }
+};
+
+//
+// Lanczos Coefficients for N=13 G=13.144565
+// Max experimental error (with arbitary precision arithmetic) 9.2213e-23
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos13 : public mpl::int_<72>
+{
+ //
+ // Produces slightly better than extended-double precision when evaluated at
+ // higher precision:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[13] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 44012138428004.60895436261759919070125699)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 41590453358593.20051581730723108131357995)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 18013842787117.99677796276038389462742949)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 4728736263475.388896889723995205703970787)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 837910083628.4046470415724300225777912264)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 105583707273.4299344907359855510105321192)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 9701363618.494999493386608345339104922694)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 654914397.5482052641016767125048538245644)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 32238322.94213356530668889463945849409184)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1128514.219497091438040721811544858643121)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 26665.79378459858944762533958798805525125)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 381.8801248632926870394389468349331394196)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 2.506628274631000502415763426076722427007))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+ static_cast<boost::uint32_t>(0u),
+ static_cast<boost::uint32_t>(39916800u),
+ static_cast<boost::uint32_t>(120543840u),
+ static_cast<boost::uint32_t>(150917976u),
+ static_cast<boost::uint32_t>(105258076u),
+ static_cast<boost::uint32_t>(45995730u),
+ static_cast<boost::uint32_t>(13339535u),
+ static_cast<boost::uint32_t>(2637558u),
+ static_cast<boost::uint32_t>(357423u),
+ static_cast<boost::uint32_t>(32670u),
+ static_cast<boost::uint32_t>(1925u),
+ static_cast<boost::uint32_t>(66u),
+ static_cast<boost::uint32_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[13] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 86091529.53418537217994842267760536134841)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 81354505.17858011242874285785316135398567)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 35236626.38815461910817650960734605416521)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 9249814.988024471294683815872977672237195)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1639024.216687146960253839656643518985826)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 206530.8157641225032631778026076868855623)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 18976.70193530288915698282139308582105936)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1281.068909912559479885759622791374106059)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 63.06093343420234536146194868906771599354)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 2.207470909792527638222674678171050209691)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.05216058694613505427476207805814960742102)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.0007469903808915448316510079585999893674101)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.4903180573459871862552197089738373164184e-5))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+ static_cast<boost::uint32_t>(0u),
+ static_cast<boost::uint32_t>(39916800u),
+ static_cast<boost::uint32_t>(120543840u),
+ static_cast<boost::uint32_t>(150917976u),
+ static_cast<boost::uint32_t>(105258076u),
+ static_cast<boost::uint32_t>(45995730u),
+ static_cast<boost::uint32_t>(13339535u),
+ static_cast<boost::uint32_t>(2637558u),
+ static_cast<boost::uint32_t>(357423u),
+ static_cast<boost::uint32_t>(32670u),
+ static_cast<boost::uint32_t>(1925u),
+ static_cast<boost::uint32_t>(66u),
+ static_cast<boost::uint32_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[12] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 4.832115561461656947793029596285626840312)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -19.86441536140337740383120735104359034688)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 33.9927422807443239927197864963170585331)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -31.41520692249765980987427413991250886138)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 17.0270866009599345679868972409543597821)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -5.5077216950865501362506920516723682167)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1.037811741948214855286817963800439373362)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.106640468537356182313660880481398642811)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.005276450526660653288757565778182586742831)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0001000935625597121545867453746252064770029)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.462590910138598083940803704521211569234e-6)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.1735307814426389420248044907765671743012e-9)),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[12] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 26.96979819614830698367887026728396466395)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -110.8705424709385114023884328797900204863)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 189.7258846119231466417015694690434770085)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -175.3397202971107486383321670769397356553)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 95.03437648691551457087250340903980824948)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -30.7406022781665264273675797983497141978)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 5.792405601630517993355102578874590410552)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.5951993240669148697377539518639997795831)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.02944979359164017509944724739946255067671)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0005586586555377030921194246330399163602684)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.2581888478270733025288922038673392636029e-5)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.9685385411006641478305219367315965391289e-9)),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 13.1445650000000000545696821063756942749; }
+};
+
+//
+// Lanczos Coefficients for N=22 G=22.61891
+// Max experimental error (with arbitary precision arithmetic) 2.9524e-38
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos22 : public mpl::int_<120>
+{
+ //
+ // Produces slightly better than 128-bit long-double precision when
+ // evaluated at higher precision:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[22] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 46198410803245094237463011094.12173081986)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 43735859291852324413622037436.321513777)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 19716607234435171720534556386.97481377748)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5629401471315018442177955161.245623932129)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1142024910634417138386281569.245580222392)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 175048529315951173131586747.695329230778)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 21044290245653709191654675.41581372963167)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2033001410561031998451380.335553678782601)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 160394318862140953773928.8736211601848891)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 10444944438396359705707.48957290388740896)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 565075825801617290121.1466393747967538948)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 25475874292116227538.99448534450411942597)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 957135055846602154.6720835535232270205725)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 29874506304047462.23662392445173880821515)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 769651310384737.2749087590725764959689181)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 16193289100889.15989633624378404096011797)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 273781151680.6807433264462376754578933261)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3630485900.32917021712188739762161583295)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 36374352.05577334277856865691538582936484)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 258945.7742115532455441786924971194951043)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1167.501919472435718934219997431551246996)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2.50662827463100050241576528481104525333))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[22] = {
+ BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(2432902008176640000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(8752948036761600000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(13803759753640704000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(12870931245150988800, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(8037811822645051776, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(3599979517947607200, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1206647803780373360, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(311333643161390640, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(63030812099294896, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(10142299865511450, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1307535010540395, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(135585182899530, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(11310276995381, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(756111184500, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(40171771630, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1672280820, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(53327946, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1256850, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(20615, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(210, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[22] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 6939996264376682180.277485395074954356211)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 6570067992110214451.87201438870245659384)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2961859037444440551.986724631496417064121)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 845657339772791245.3541226499766163431651)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 171556737035449095.2475716923888737881837)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 26296059072490867.7822441885603400926007)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3161305619652108.433798300149816829198706)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 305400596026022.4774396904484542582526472)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 24094681058862.55120507202622377623528108)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1569055604375.919477574824168939428328839)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 84886558909.02047889339710230696942513159)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3827024985.166751989686050643579753162298)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 143782298.9273215199098728674282885500522)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 4487794.24541641841336786238909171265944)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 115618.2025760830513505888216285273541959)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2432.580773108508276957461757328744780439)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 41.12782532742893597168530008461874360191)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.5453771709477689805460179187388702295792)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.005464211062612080347167337964166505282809)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.388992321263586767037090706042788910953e-4)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.1753839324538447655939518484052327068859e-6)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.3765495513732730583386223384116545391759e-9))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[22] = {
+ BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(2432902008176640000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(8752948036761600000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(13803759753640704000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(12870931245150988800, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(8037811822645051776, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(3599979517947607200, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1206647803780373360, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(311333643161390640, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(63030812099294896, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(10142299865511450, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1307535010540395, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(135585182899530, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(11310276995381, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(756111184500, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(40171771630, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1672280820, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(53327946, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1256850, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(20615, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(210, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[21] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8.318998691953337183034781139546384476554)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -63.15415991415959158214140353299240638675)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 217.3108224383632868591462242669081540163)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -448.5134281386108366899784093610397354889)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 619.2903759363285456927248474593012711346)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -604.1630177420625418522025080080444177046)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 428.8166750424646119935047118287362193314)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -224.6988753721310913866347429589434550302)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 87.32181627555510833499451817622786940961)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -25.07866854821128965662498003029199058098)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5.264398125689025351448861011657789005392)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.792518936256495243383586076579921559914)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.08317448364744713773350272460937904691566)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.005845345166274053157781068150827567998882)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0002599412126352082483326238522490030412391)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6748102079670763884917431338234783496303e-5)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.908824383434109002762325095643458603605e-7)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.5299325929309389890892469299969669579725e-9)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.994306085859549890267983602248532869362e-12)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3499893692975262747371544905820891835298e-15)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7260746353663365145454867069182884694961e-20)),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[21] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 75.39272007105208086018421070699575462226)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -572.3481967049935412452681346759966390319)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1969.426202741555335078065370698955484358)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -4064.74968778032030891520063865996757519)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5612.452614138013929794736248384309574814)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -5475.357667500026172903620177988213902339)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3886.243614216111328329547926490398103492)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -2036.382026072125407192448069428134470564)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 791.3727954936062108045551843636692287652)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -227.2808432388436552794021219198885223122)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 47.70974355562144229897637024320739257284)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -7.182373807798293545187073539819697141572)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7537866989631514559601547530490976100468)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.05297470142240154822658739758236594717787)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.00235577330936380542539812701472320434133)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6115613067659273118098229498679502138802e-4)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.8236417010170941915758315020695551724181e-6)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.4802628430993048190311242611330072198089e-8)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.9011113376981524418952720279739624707342e-11)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3171854152689711198382455703658589996796e-14)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.6580207998808093935798753964580596673177e-19)),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 22.61890999999999962710717227309942245483; }
+};
+
+//
+// Lanczos Coefficients for N=6 G=1.428456135094165802001953125
+// Max experimental error (with arbitary precision arithmetic) 8.111667e-8
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos6m24 : public mpl::int_<24>
+{
+ //
+ // Use for float precision, when evaluated as a float:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ static const T num[6] = {
+ static_cast<T>(58.52061591769095910314047740215847630266L),
+ static_cast<T>(182.5248962595894264831189414768236280862L),
+ static_cast<T>(211.0971093028510041839168287718170827259L),
+ static_cast<T>(112.2526547883668146736465390902227161763L),
+ static_cast<T>(27.5192015197455403062503721613097825345L),
+ static_cast<T>(2.50662858515256974113978724717473206342L)
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+ static_cast<boost::uint16_t>(0u),
+ static_cast<boost::uint16_t>(24u),
+ static_cast<boost::uint16_t>(50u),
+ static_cast<boost::uint16_t>(35u),
+ static_cast<boost::uint16_t>(10u),
+ static_cast<boost::uint16_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ static const T num[6] = {
+ static_cast<T>(14.0261432874996476619570577285003839357L),
+ static_cast<T>(43.74732405540314316089531289293124360129L),
+ static_cast<T>(50.59547402616588964511581430025589038612L),
+ static_cast<T>(26.90456680562548195593733429204228910299L),
+ static_cast<T>(6.595765571169314946316366571954421695196L),
+ static_cast<T>(0.6007854010515290065101128585795542383721L)
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+ static_cast<boost::uint16_t>(0u),
+ static_cast<boost::uint16_t>(24u),
+ static_cast<boost::uint16_t>(50u),
+ static_cast<boost::uint16_t>(35u),
+ static_cast<boost::uint16_t>(10u),
+ static_cast<boost::uint16_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ static const T d[5] = {
+ static_cast<T>(0.4922488055204602807654354732674868442106L),
+ static_cast<T>(0.004954497451132152436631238060933905650346L),
+ static_cast<T>(-0.003374784572167105840686977985330859371848L),
+ static_cast<T>(0.001924276018962061937026396537786414831385L),
+ static_cast<T>(-0.00056533046336427583708166383712907694434L),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ static const T d[5] = {
+ static_cast<T>(0.6534966888520080645505805298901130485464L),
+ static_cast<T>(0.006577461728560758362509168026049182707101L),
+ static_cast<T>(-0.004480276069269967207178373559014835978161L),
+ static_cast<T>(0.00255461870648818292376982818026706528842L),
+ static_cast<T>(-0.000750517993690428370380996157470900204524L),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 1.428456135094165802001953125; }
+};
+
+//
+// Lanczos Coefficients for N=13 G=6.024680040776729583740234375
+// Max experimental error (with arbitary precision arithmetic) 1.196214e-17
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos13m53 : public mpl::int_<53>
+{
+ //
+ // Use for double precision, when evaluated as a double:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ static const T num[13] = {
+ static_cast<T>(23531376880.41075968857200767445163675473L),
+ static_cast<T>(42919803642.64909876895789904700198885093L),
+ static_cast<T>(35711959237.35566804944018545154716670596L),
+ static_cast<T>(17921034426.03720969991975575445893111267L),
+ static_cast<T>(6039542586.35202800506429164430729792107L),
+ static_cast<T>(1439720407.311721673663223072794912393972L),
+ static_cast<T>(248874557.8620541565114603864132294232163L),
+ static_cast<T>(31426415.58540019438061423162831820536287L),
+ static_cast<T>(2876370.628935372441225409051620849613599L),
+ static_cast<T>(186056.2653952234950402949897160456992822L),
+ static_cast<T>(8071.672002365816210638002902272250613822L),
+ static_cast<T>(210.8242777515793458725097339207133627117L),
+ static_cast<T>(2.506628274631000270164908177133837338626L)
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+ static_cast<boost::uint32_t>(0u),
+ static_cast<boost::uint32_t>(39916800u),
+ static_cast<boost::uint32_t>(120543840u),
+ static_cast<boost::uint32_t>(150917976u),
+ static_cast<boost::uint32_t>(105258076u),
+ static_cast<boost::uint32_t>(45995730u),
+ static_cast<boost::uint32_t>(13339535u),
+ static_cast<boost::uint32_t>(2637558u),
+ static_cast<boost::uint32_t>(357423u),
+ static_cast<boost::uint32_t>(32670u),
+ static_cast<boost::uint32_t>(1925u),
+ static_cast<boost::uint32_t>(66u),
+ static_cast<boost::uint32_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ static const T num[13] = {
+ static_cast<T>(56906521.91347156388090791033559122686859L),
+ static_cast<T>(103794043.1163445451906271053616070238554L),
+ static_cast<T>(86363131.28813859145546927288977868422342L),
+ static_cast<T>(43338889.32467613834773723740590533316085L),
+ static_cast<T>(14605578.08768506808414169982791359218571L),
+ static_cast<T>(3481712.15498064590882071018964774556468L),
+ static_cast<T>(601859.6171681098786670226533699352302507L),
+ static_cast<T>(75999.29304014542649875303443598909137092L),
+ static_cast<T>(6955.999602515376140356310115515198987526L),
+ static_cast<T>(449.9445569063168119446858607650988409623L),
+ static_cast<T>(19.51992788247617482847860966235652136208L),
+ static_cast<T>(0.5098416655656676188125178644804694509993L),
+ static_cast<T>(0.006061842346248906525783753964555936883222L)
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+ static_cast<boost::uint32_t>(0u),
+ static_cast<boost::uint32_t>(39916800u),
+ static_cast<boost::uint32_t>(120543840u),
+ static_cast<boost::uint32_t>(150917976u),
+ static_cast<boost::uint32_t>(105258076u),
+ static_cast<boost::uint32_t>(45995730u),
+ static_cast<boost::uint32_t>(13339535u),
+ static_cast<boost::uint32_t>(2637558u),
+ static_cast<boost::uint32_t>(357423u),
+ static_cast<boost::uint32_t>(32670u),
+ static_cast<boost::uint32_t>(1925u),
+ static_cast<boost::uint32_t>(66u),
+ static_cast<boost::uint32_t>(1u)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ static const T d[12] = {
+ static_cast<T>(2.208709979316623790862569924861841433016L),
+ static_cast<T>(-3.327150580651624233553677113928873034916L),
+ static_cast<T>(1.483082862367253753040442933770164111678L),
+ static_cast<T>(-0.1993758927614728757314233026257810172008L),
+ static_cast<T>(0.004785200610085071473880915854204301886437L),
+ static_cast<T>(-0.1515973019871092388943437623825208095123e-5L),
+ static_cast<T>(-0.2752907702903126466004207345038327818713e-7L),
+ static_cast<T>(0.3075580174791348492737947340039992829546e-7L),
+ static_cast<T>(-0.1933117898880828348692541394841204288047e-7L),
+ static_cast<T>(0.8690926181038057039526127422002498960172e-8L),
+ static_cast<T>(-0.2499505151487868335680273909354071938387e-8L),
+ static_cast<T>(0.3394643171893132535170101292240837927725e-9L),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ static const T d[12] = {
+ static_cast<T>(6.565936202082889535528455955485877361223L),
+ static_cast<T>(-9.8907772644920670589288081640128194231L),
+ static_cast<T>(4.408830289125943377923077727900630927902L),
+ static_cast<T>(-0.5926941084905061794445733628891024027949L),
+ static_cast<T>(0.01422519127192419234315002746252160965831L),
+ static_cast<T>(-0.4506604409707170077136555010018549819192e-5L),
+ static_cast<T>(-0.8183698410724358930823737982119474130069e-7L),
+ static_cast<T>(0.9142922068165324132060550591210267992072e-7L),
+ static_cast<T>(-0.5746670642147041587497159649318454348117e-7L),
+ static_cast<T>(0.2583592566524439230844378948704262291927e-7L),
+ static_cast<T>(-0.7430396708998719707642735577238449585822e-8L),
+ static_cast<T>(0.1009141566987569892221439918230042368112e-8L),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 6.024680040776729583740234375; }
+};
+
+//
+// Lanczos Coefficients for N=17 G=12.2252227365970611572265625
+// Max experimental error (with arbitary precision arithmetic) 2.7699e-26
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos17m64 : public mpl::int_<64>
+{
+ //
+ // Use for extended-double precision, when evaluated as an extended-double:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[17] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 553681095419291969.2230556393350368550504)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 731918863887667017.2511276782146694632234)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 453393234285807339.4627124634539085143364)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 174701893724452790.3546219631779712198035)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 46866125995234723.82897281620357050883077)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 9281280675933215.169109622777099699054272)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1403600894156674.551057997617468721789536)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 165345984157572.7305349809894046783973837)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 15333629842677.31531822808737907246817024)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1123152927963.956626161137169462874517318)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 64763127437.92329018717775593533620578237)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2908830362.657527782848828237106640944457)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 99764700.56999856729959383751710026787811)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2525791.604886139959837791244686290089331)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 44516.94034970167828580039370201346554872)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 488.0063567520005730476791712814838113252)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2.50662827463100050241576877135758834683))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[17] = {
+ BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(120, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[17] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2715894658327.717377557655133124376674911)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 3590179526097.912105038525528721129550434)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2223966599737.814969312127353235818710172)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 856940834518.9562481809925866825485883417)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 229885871668.749072933597446453399395469)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 45526171687.54610815813502794395753410032)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 6884887713.165178784550917647709216424823)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 811048596.1407531864760282453852372777439)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 75213915.96540822314499613623119501704812)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 5509245.417224265151697527957954952830126)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 317673.5368435419126714931842182369574221)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 14268.27989845035520147014373320337523596)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 489.3618720403263670213909083601787814792)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 12.38941330038454449295883217865458609584)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2183627389504614963941574507281683147897)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.002393749522058449186690627996063983095463)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1229541408909435212800785616808830746135e-4))
+ };
+ static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[17] = {
+ BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(120, uLL),
+ BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[16] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 4.493645054286536365763334986866616581265)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -16.95716370392468543800733966378143997694)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 26.19196892983737527836811770970479846644)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -21.3659076437988814488356323758179283908)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 9.913992596774556590710751047594507535764)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.62888300018780199210536267080940382158)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.3807056693542503606384861890663080735588)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.02714647489697685807340312061034730486958)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0007815484715461206757220527133967191796747)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.6108630817371501052576880554048972272435e-5)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.5037380238864836824167713635482801545086e-8)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1483232144262638814568926925964858237006e-13)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1346609158752142460943888149156716841693e-14)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.660492688923978805315914918995410340796e-15)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1472114697343266749193617793755763792681e-15)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1410901942033374651613542904678399264447e-16)),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[16] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 23.56409085052261327114594781581930373708)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -88.92116338946308797946237246006238652361)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 137.3472822086847596961177383569603988797)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -112.0400438263562152489272966461114852861)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 51.98768915202973863076166956576777843805)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -13.78552090862799358221343319574970124948)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.996371068830872830250406773917646121742)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1423525874909934506274738563671862576161)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.004098338646046865122459664947239111298524)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3203286637326511000882086573060433529094e-4)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2641536751640138646146395939004587594407e-7)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7777876663062235617693516558976641009819e-13)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7061443477097101636871806229515157914789e-14)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3463537849537988455590834887691613484813e-14)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7719578215795234036320348283011129450595e-15)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7398586479708476329563577384044188912075e-16)),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 12.2252227365970611572265625; }
+};
+
+//
+// Lanczos Coefficients for N=24 G=20.3209821879863739013671875
+// Max experimental error (with arbitary precision arithmetic) 1.0541e-38
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos24m113 : public mpl::int_<113>
+{
+ //
+ // Use for long-double precision, when evaluated as an long-double:
+ //
+ template <class T>
+ static T lanczos_sum(const T& z)
+ {
+ lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[24] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2029889364934367661624137213253.22102954656825019111612712252027267955023987678816620961507)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2338599599286656537526273232565.2727349714338768161421882478417543004440597874814359063158)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1288527989493833400335117708406.3953711906175960449186720680201425446299360322830739180195)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 451779745834728745064649902914.550539158066332484594436145043388809847364393288132164411521)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 113141284461097964029239556815.291212318665536114012605167994061291631013303788706545334708)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 21533689802794625866812941616.7509064680880468667055339259146063256555368135236149614592432)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3235510315314840089932120340.71494940111731241353655381919722177496659303550321056514776757)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 393537392344185475704891959.081297108513472083749083165179784098220158201055270548272414314)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 39418265082950435024868801.5005452240816902251477336582325944930252142622315101857742955673)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3290158764187118871697791.05850632319194734270969161036889516414516566453884272345518372696)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 230677110449632078321772.618245845856640677845629174549731890660612368500786684333975350954)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 13652233645509183190158.5916189185218250859402806777406323001463296297553612462737044693697)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 683661466754325350495.216655026531202476397782296585200982429378069417193575896602446904762)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 28967871782219334117.0122379171041074970463982134039409352925258212207710168851968215545064)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1036104088560167006.2022834098572346459442601718514554488352117620272232373622553429728555)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 31128490785613152.8380102669349814751268126141105475287632676569913936040772990253369753962)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 779327504127342.536207878988196814811198475410572992436243686674896894543126229424358472541)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 16067543181294.643350688789124777020407337133926174150582333950666044399234540521336771876)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 268161795520.300916569439413185778557212729611517883948634711190170998896514639936969855484)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3533216359.10528191668842486732408440112703691790824611391987708562111396961696753452085068)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 35378979.5479656110614685178752543826919239614088343789329169535932709470588426584501652577)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 253034.881362204346444503097491737872930637147096453940375713745904094735506180552724766444)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1151.61895453463992438325318456328526085882924197763140514450975619271382783957699017875304)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2.50662827463100050241576528481104515966515623051532908941425544355490413900497467936202516))
+ };
+ static const T denom[24] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0))
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+ template <class T>
+ static T lanczos_sum_expG_scaled(const T& z)
+ {
+ lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T num[24] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3035162425359883494754.02878223286972654682199012688209026810841953293372712802258398358538)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3496756894406430103600.16057175075063458536101374170860226963245118484234495645518505519827)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1926652656689320888654.01954015145958293168365236755537645929361841917596501251362171653478)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 675517066488272766316.083023742440619929434602223726894748181327187670231286180156444871912)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 169172853104918752780.086262749564831660238912144573032141700464995906149421555926000038492)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 32197935167225605785.6444116302160245528783954573163541751756353183343357329404208062043808)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4837849542714083249.37587447454818124327561966323276633775195138872820542242539845253171632)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 588431038090493242.308438203986649553459461798968819276505178004064031201740043314534404158)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 58939585141634058.6206417889192563007809470547755357240808035714047014324843817783741669733)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4919561837722192.82991866530802080996138070630296720420704876654726991998309206256077395868)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 344916580244240.407442753122831512004021081677987651622305356145640394384006997569631719101)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 20413302960687.8250598845969238472629322716685686993835561234733641729957841485003560103066)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1022234822943.78400752460970689311934727763870970686747383486600540378889311406851534545789)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 43313787191.9821354846952908076307094286897439975815501673706144217246093900159173598852503)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1549219505.59667418528481770869280437577581951167003505825834192510436144666564648361001914)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 46544421.1998761919380541579358096705925369145324466147390364674998568485110045455014967149)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1165278.06807504975090675074910052763026564833951579556132777702952882101173607903881127542)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 24024.759267256769471083727721827405338569868270177779485912486668586611981795179894572115)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 400.965008113421955824358063769761286758463521789765880962939528760888853281920872064838918)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 5.28299015654478269617039029170846385138134929147421558771949982217659507918482272439717603)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0528999024412510102409256676599360516359062802002483877724963720047531347449011629466149805)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.000378346710654740685454266569593414561162134092347356968516522170279688139165340746957511115)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.172194142179211139195966608011235161516824700287310869949928393345257114743230967204370963e-5)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.374799931707148855771381263542708435935402853962736029347951399323367765509988401336565436e-8))
+ };
+ static const T denom[24] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0))
+ };
+ return boost::math::tools::evaluate_rational(num, denom, z);
+ }
+
+
+ template<class T>
+ static T lanczos_sum_near_1(const T& dz)
+ {
+ lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[23] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 7.4734083002469026177867421609938203388868806387315406134072298925733950040583068760685908)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -50.4225805042247530267317342133388132970816607563062253708655085754357843064134941138154171)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 152.288200621747008570784082624444625293884063492396162110698238568311211546361189979357019)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -271.894959539150384169327513139846971255640842175739337449692360299099322742181325023644769)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 319.240102980202312307047586791116902719088581839891008532114107693294261542869734803906793)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -259.493144143048088289689500935518073716201741349569864988870534417890269467336454358361499)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 149.747518319689708813209645403067832020714660918583227716408482877303972685262557460145835)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -61.9261301009341333289187201425188698128684426428003249782448828881580630606817104372760037)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 18.3077524177286961563937379403377462608113523887554047531153187277072451294845795496072365)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -3.82011322251948043097070160584761236869363471824695092089556195047949392738162970152230254)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.549382685505691522516705902336780999493262538301283190963770663549981309645795228539620711)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.0524814679715180697633723771076668718265358076235229045603747927518423453658004287459638024)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.00315392664003333528534120626687784812050217700942910879712808180705014754163256855643360698)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000110098373127648510519799564665442121339511198561008748083409549601095293123407080388658329)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.19809382866681658224945717689377373458866950897791116315219376038432014207446832310901893e-5)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.152278977408600291408265615203504153130482270424202400677280558181047344681214058227949755e-7)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.364344768076106268872239259083188037615571711218395765792787047015406264051536972018235217e-10)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.148897510480440424971521542520683536298361220674662555578951242811522959610991621951203526e-13)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.261199241161582662426512749820666625442516059622425213340053324061794752786482115387573582e-18)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.780072664167099103420998436901014795601783313858454665485256897090476089641613851903791529e-24)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.303465867587106629530056603454807425512962762653755513440561256044986695349304176849392735e-24)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.615420597971283870342083342286977366161772327800327789325710571275345878439656918541092056e-25)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.499641233843540749369110053005439398774706583601830828776209650445427083113181961630763702e-26)),
+ };
+ T result = 0;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(k*dz + k*k);
+ }
+ return result;
+ }
+
+ template<class T>
+ static T lanczos_sum_near_2(const T& dz)
+ {
+ lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+ static const T d[23] = {
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 61.4165001061101455341808888883960361969557848005400286332291451422461117307237198559485365)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -414.372973678657049667308134761613915623353625332248315105320470271523320700386200587519147)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1251.50505818554680171298972755376376836161706773644771875668053742215217922228357204561873)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -2234.43389421602399514176336175766511311493214354568097811220122848998413358085613880612158)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2623.51647746991904821899989145639147785427273427135380151752779100215839537090464785708684)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -2132.51572435428751962745870184529534443305617818870214348386131243463614597272260797772423)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1230.62572059218405766499842067263311220019173335523810725664442147670956427061920234820189)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -508.90919151163744999377586956023909888833335885805154492270846381061182696305011395981929)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 150.453184562246579758706538566480316921938628645961177699894388251635886834047343195475395)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -31.3937061525822497422230490071156186113405446381476081565548185848237169870395131828731397)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4.51482916590287954234936829724231512565732528859217337795452389161322923867318809206313688)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.431292919341108177524462194102701868233551186625103849565527515201492276412231365776131952)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0259189820815586225636729971503340447445001375909094681698918294680345547092233915092128323)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000904788882557558697594884691337532557729219389814315972435534723829065673966567231504429712)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.162793589759218213439218473348810982422449144393340433592232065020562974405674317564164312e-4)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.125142926178202562426432039899709511761368233479483128438847484617555752948755923647214487e-6)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.299418680048132583204152682950097239197934281178261879500770485862852229898797687301941982e-9)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.122364035267809278675627784883078206654408225276233049012165202996967011873995261617995421e-12)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.21465364366598631597052073538883430194257709353929022544344097235100199405814005393447785e-17)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.641064035802907518396608051803921688237330857546406669209280666066685733941549058513986818e-23)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.249388374622173329690271566855185869111237201309011956145463506483151054813346819490278951e-23)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.505752900177513489906064295001851463338022055787536494321532352380960774349054239257683149e-24)),
+ static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.410605371184590959139968810080063542546949719163227555918846829816144878123034347778284006e-25)),
+ };
+ T result = 0;
+ T z = dz + 2;
+ for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+ {
+ result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+ }
+ return result;
+ }
+
+ static double g(){ return 20.3209821879863739013671875; }
+};
+
+
+//
+// placeholder for no lanczos info available:
+//
+struct undefined_lanczos : public mpl::int_<INT_MAX - 1> { };
+
+#if 0
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+#define BOOST_MATH_FLT_DIGITS ::std::numeric_limits<float>::digits
+#define BOOST_MATH_DBL_DIGITS ::std::numeric_limits<double>::digits
+#define BOOST_MATH_LDBL_DIGITS ::std::numeric_limits<long double>::digits
+#else
+#define BOOST_MATH_FLT_DIGITS FLT_MANT_DIG
+#define BOOST_MATH_DBL_DIGITS DBL_MANT_DIG
+#define BOOST_MATH_LDBL_DIGITS LDBL_MANT_DIG
+#endif
+#endif
+
+typedef mpl::list<
+ lanczos6m24,
+/* lanczos6, */
+ lanczos13m53,
+/* lanczos13, */
+ lanczos17m64,
+ lanczos24m113,
+ lanczos22,
+ undefined_lanczos> lanczos_list;
+
+template <class Real, class Policy>
+struct lanczos
+{
+ typedef typename mpl::if_<
+ typename mpl::less_equal<
+ typename policies::precision<Real, Policy>::type,
+ mpl::int_<0>
+ >::type,
+ mpl::int_<INT_MAX - 2>,
+ typename policies::precision<Real, Policy>::type
+ >::type target_precision;
+
+ typedef typename mpl::deref<typename mpl::find_if<
+ lanczos_list,
+ mpl::less_equal<target_precision, mpl::_1> >::type>::type type;
+};
+
+} // namespace lanczos
+} // namespace math
+} // namespace boost
+
+#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3)))
+#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__)
+#include <boost/math/special_functions/detail/lanczos_sse2.hpp>
+#endif
+#endif
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/log1p.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/log1p.hpp
new file mode 100644
index 00000000000..62f5b8027c9
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/log1p.hpp
@@ -0,0 +1,503 @@
+// (C) Copyright John Maddock 2005-2006.
+// 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)
+
+#ifndef BOOST_MATH_LOG1P_INCLUDED
+#define BOOST_MATH_LOG1P_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <math.h> // platform's ::log1p
+#include <boost/limits.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+# include <boost/static_assert.hpp>
+#else
+# include <boost/assert.hpp>
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+ // Functor log1p_series returns the next term in the Taylor series
+ // pow(-1, k-1)*pow(x, k) / k
+ // each time that operator() is invoked.
+ //
+ template <class T>
+ struct log1p_series
+ {
+ typedef T result_type;
+
+ log1p_series(T x)
+ : k(0), m_mult(-x), m_prod(-1){}
+
+ T operator()()
+ {
+ m_prod *= m_mult;
+ return m_prod / ++k;
+ }
+
+ int count()const
+ {
+ return k;
+ }
+
+ private:
+ int k;
+ const T m_mult;
+ T m_prod;
+ log1p_series(const log1p_series&);
+ log1p_series& operator=(const log1p_series&);
+ };
+
+// Algorithm log1p is part of C99, but is not yet provided by many compilers.
+//
+// This version uses a Taylor series expansion for 0.5 > x > epsilon, which may
+// require up to std::numeric_limits<T>::digits+1 terms to be calculated.
+// It would be much more efficient to use the equivalence:
+// log(1+x) == (log(1+x) * x) / ((1-x) - 1)
+// Unfortunately many optimizing compilers make such a mess of this, that
+// it performs no better than log(1+x): which is to say not very well at all.
+//
+template <class T, class Policy>
+T log1p_imp(T const & x, const Policy& pol, const mpl::int_<0>&)
+{ // The function returns the natural logarithm of 1 + x.
+ typedef typename tools::promote_args<T>::type result_type;
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+ if(x < -1)
+ return policies::raise_domain_error<T>(
+ function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<T>(
+ function, 0, pol);
+
+ result_type a = abs(result_type(x));
+ if(a > result_type(0.5f))
+ return log(1 + result_type(x));
+ // Note that without numeric_limits specialisation support,
+ // epsilon just returns zero, and our "optimisation" will always fail:
+ if(a < tools::epsilon<result_type>())
+ return x;
+ detail::log1p_series<result_type> s(x);
+ boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) && !BOOST_WORKAROUND(__EDG_VERSION__, <= 245)
+ result_type result = tools::sum_series(s, policies::get_epsilon<result_type, Policy>(), max_iter);
+#else
+ result_type zero = 0;
+ result_type result = tools::sum_series(s, policies::get_epsilon<result_type, Policy>(), max_iter, zero);
+#endif
+ policies::check_series_iterations<T>(function, max_iter, pol);
+ return result;
+}
+
+template <class T, class Policy>
+T log1p_imp(T const& x, const Policy& pol, const mpl::int_<53>&)
+{ // The function returns the natural logarithm of 1 + x.
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+ if(x < -1)
+ return policies::raise_domain_error<T>(
+ function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<T>(
+ function, 0, pol);
+
+ T a = fabs(x);
+ if(a > 0.5f)
+ return log(1 + x);
+ // Note that without numeric_limits specialisation support,
+ // epsilon just returns zero, and our "optimisation" will always fail:
+ if(a < tools::epsilon<T>())
+ return x;
+
+ // Maximum Deviation Found: 1.846e-017
+ // Expected Error Term: 1.843e-017
+ // Maximum Relative Change in Control Points: 8.138e-004
+ // Max Error found at double precision = 3.250766e-016
+ static const T P[] = {
+ 0.15141069795941984e-16L,
+ 0.35495104378055055e-15L,
+ 0.33333333333332835L,
+ 0.99249063543365859L,
+ 1.1143969784156509L,
+ 0.58052937949269651L,
+ 0.13703234928513215L,
+ 0.011294864812099712L
+ };
+ static const T Q[] = {
+ 1L,
+ 3.7274719063011499L,
+ 5.5387948649720334L,
+ 4.159201143419005L,
+ 1.6423855110312755L,
+ 0.31706251443180914L,
+ 0.022665554431410243L,
+ -0.29252538135177773e-5L
+ };
+
+ T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x);
+ result *= x;
+
+ return result;
+}
+
+template <class T, class Policy>
+T log1p_imp(T const& x, const Policy& pol, const mpl::int_<64>&)
+{ // The function returns the natural logarithm of 1 + x.
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+ if(x < -1)
+ return policies::raise_domain_error<T>(
+ function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<T>(
+ function, 0, pol);
+
+ T a = fabs(x);
+ if(a > 0.5f)
+ return log(1 + x);
+ // Note that without numeric_limits specialisation support,
+ // epsilon just returns zero, and our "optimisation" will always fail:
+ if(a < tools::epsilon<T>())
+ return x;
+
+ // Maximum Deviation Found: 8.089e-20
+ // Expected Error Term: 8.088e-20
+ // Maximum Relative Change in Control Points: 9.648e-05
+ // Max Error found at long double precision = 2.242324e-19
+ static const T P[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.807533446680736736712e-19),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.490881544804798926426e-18),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.333333333333333373941),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.17141290782087994162),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.62790522814926264694),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.13156411870766876113),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.408087379932853785336),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.0706537026422828914622),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00441709903782239229447)
+ };
+ static const T Q[] = {
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 4.26423872346263928361),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 7.48189472704477708962),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 6.94757016732904280913),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 3.6493508622280767304),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 1.06884863623790638317),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.158292216998514145947),
+ BOOST_MATH_BIG_CONSTANT(T, 64, 0.00885295524069924328658),
+ BOOST_MATH_BIG_CONSTANT(T, 64, -0.560026216133415663808e-6)
+ };
+
+ T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x);
+ result *= x;
+
+ return result;
+}
+
+template <class T, class Policy>
+T log1p_imp(T const& x, const Policy& pol, const mpl::int_<24>&)
+{ // The function returns the natural logarithm of 1 + x.
+ BOOST_MATH_STD_USING
+
+ static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+ if(x < -1)
+ return policies::raise_domain_error<T>(
+ function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<T>(
+ function, 0, pol);
+
+ T a = fabs(x);
+ if(a > 0.5f)
+ return log(1 + x);
+ // Note that without numeric_limits specialisation support,
+ // epsilon just returns zero, and our "optimisation" will always fail:
+ if(a < tools::epsilon<T>())
+ return x;
+
+ // Maximum Deviation Found: 6.910e-08
+ // Expected Error Term: 6.910e-08
+ // Maximum Relative Change in Control Points: 2.509e-04
+ // Max Error found at double precision = 6.910422e-08
+ // Max Error found at float precision = 8.357242e-08
+ static const T P[] = {
+ -0.671192866803148236519e-7L,
+ 0.119670999140731844725e-6L,
+ 0.333339469182083148598L,
+ 0.237827183019664122066L
+ };
+ static const T Q[] = {
+ 1L,
+ 1.46348272586988539733L,
+ 0.497859871350117338894L,
+ -0.00471666268910169651936L
+ };
+
+ T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x);
+ result *= x;
+
+ return result;
+}
+
+template <class T, class Policy, class tag>
+struct log1p_initializer
+{
+ struct init
+ {
+ init()
+ {
+ do_init(tag());
+ }
+ template <int N>
+ static void do_init(const mpl::int_<N>&){}
+ static void do_init(const mpl::int_<64>&)
+ {
+ boost::math::log1p(static_cast<T>(0.25), Policy());
+ }
+ void force_instantiate()const{}
+ };
+ static const init initializer;
+ static void force_instantiate()
+ {
+ initializer.force_instantiate();
+ }
+};
+
+template <class T, class Policy, class tag>
+const typename log1p_initializer<T, Policy, tag>::init log1p_initializer<T, Policy, tag>::initializer;
+
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type log1p(T x, const Policy&)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ typedef typename policies::evaluation<result_type, Policy>::type value_type;
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+ typedef typename policies::normalise<
+ Policy,
+ policies::promote_float<false>,
+ policies::promote_double<false>,
+ policies::discrete_quantile<>,
+ policies::assert_undefined<> >::type forwarding_policy;
+
+ typedef typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<0> >,
+ mpl::int_<0>,
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<53> >,
+ mpl::int_<53>, // double
+ typename mpl::if_<
+ mpl::less_equal<precision_type, mpl::int_<64> >,
+ mpl::int_<64>, // 80-bit long double
+ mpl::int_<0> // too many bits, use generic version.
+ >::type
+ >::type
+ >::type tag_type;
+
+ detail::log1p_initializer<value_type, forwarding_policy, tag_type>::force_instantiate();
+
+ return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+ detail::log1p_imp(static_cast<value_type>(x), forwarding_policy(), tag_type()), "boost::math::log1p<%1%>(%1%)");
+}
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+// These overloads work around a type deduction bug:
+inline float log1p(float z)
+{
+ return log1p<float>(z);
+}
+inline double log1p(double z)
+{
+ return log1p<double>(z);
+}
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double log1p(long double z)
+{
+ return log1p<long double>(z);
+}
+#endif
+#endif
+
+#ifdef log1p
+# ifndef BOOST_HAS_LOG1P
+# define BOOST_HAS_LOG1P
+# endif
+# undef log1p
+#endif
+
+#if defined(BOOST_HAS_LOG1P) && !(defined(__osf__) && defined(__DECCXX_VER))
+# ifdef BOOST_MATH_USE_C99
+template <class Policy>
+inline float log1p(float x, const Policy& pol)
+{
+ if(x < -1)
+ return policies::raise_domain_error<float>(
+ "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<float>(
+ "log1p<%1%>(%1%)", 0, pol);
+ return ::log1pf(x);
+}
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template <class Policy>
+inline long double log1p(long double x, const Policy& pol)
+{
+ if(x < -1)
+ return policies::raise_domain_error<long double>(
+ "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<long double>(
+ "log1p<%1%>(%1%)", 0, pol);
+ return ::log1pl(x);
+}
+#endif
+#else
+template <class Policy>
+inline float log1p(float x, const Policy& pol)
+{
+ if(x < -1)
+ return policies::raise_domain_error<float>(
+ "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<float>(
+ "log1p<%1%>(%1%)", 0, pol);
+ return ::log1p(x);
+}
+#endif
+template <class Policy>
+inline double log1p(double x, const Policy& pol)
+{
+ if(x < -1)
+ return policies::raise_domain_error<double>(
+ "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<double>(
+ "log1p<%1%>(%1%)", 0, pol);
+ return ::log1p(x);
+}
+#elif defined(_MSC_VER) && (BOOST_MSVC >= 1400)
+//
+// You should only enable this branch if you are absolutely sure
+// that your compilers optimizer won't mess this code up!!
+// Currently tested with VC8 and Intel 9.1.
+//
+template <class Policy>
+inline double log1p(double x, const Policy& pol)
+{
+ if(x < -1)
+ return policies::raise_domain_error<double>(
+ "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<double>(
+ "log1p<%1%>(%1%)", 0, pol);
+ double u = 1+x;
+ if(u == 1.0)
+ return x;
+ else
+ return ::log(u)*(x/(u-1.0));
+}
+template <class Policy>
+inline float log1p(float x, const Policy& pol)
+{
+ return static_cast<float>(boost::math::log1p(static_cast<double>(x), pol));
+}
+#ifndef _WIN32_WCE
+//
+// For some reason this fails to compile under WinCE...
+// Needs more investigation.
+//
+template <class Policy>
+inline long double log1p(long double x, const Policy& pol)
+{
+ if(x < -1)
+ return policies::raise_domain_error<long double>(
+ "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<long double>(
+ "log1p<%1%>(%1%)", 0, pol);
+ long double u = 1+x;
+ if(u == 1.0)
+ return x;
+ else
+ return ::logl(u)*(x/(u-1.0));
+}
+#endif
+#endif
+
+template <class T>
+inline typename tools::promote_args<T>::type log1p(T x)
+{
+ return boost::math::log1p(x, policies::policy<>());
+}
+//
+// Compute log(1+x)-x:
+//
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type
+ log1pmx(T x, const Policy& pol)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ BOOST_MATH_STD_USING
+ static const char* function = "boost::math::log1pmx<%1%>(%1%)";
+
+ if(x < -1)
+ return policies::raise_domain_error<T>(
+ function, "log1pmx(x) requires x > -1, but got x = %1%.", x, pol);
+ if(x == -1)
+ return -policies::raise_overflow_error<T>(
+ function, 0, pol);
+
+ result_type a = abs(result_type(x));
+ if(a > result_type(0.95f))
+ return log(1 + result_type(x)) - result_type(x);
+ // Note that without numeric_limits specialisation support,
+ // epsilon just returns zero, and our "optimisation" will always fail:
+ if(a < tools::epsilon<result_type>())
+ return -x * x / 2;
+ boost::math::detail::log1p_series<T> s(x);
+ s();
+ 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, policies::get_epsilon<T, Policy>(), max_iter, zero);
+#else
+ T result = boost::math::tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter);
+#endif
+ policies::check_series_iterations<T>(function, max_iter, pol);
+ return result;
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type log1pmx(T x)
+{
+ return log1pmx(x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_LOG1P_INCLUDED
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/math_fwd.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/math_fwd.hpp
new file mode 100644
index 00000000000..e952dcdb516
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/math_fwd.hpp
@@ -0,0 +1,1499 @@
+// math_fwd.hpp
+
+// TODO revise completely for new distribution classes.
+
+// Copyright Paul A. Bristow 2006.
+// Copyright John Maddock 2006.
+
+// 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)
+
+// Omnibus list of forward declarations of math special functions.
+
+// IT = Integer type.
+// RT = Real type (built-in floating-point types, float, double, long double) & User Defined Types
+// AT = Integer or Real type
+
+#ifndef BOOST_MATH_SPECIAL_MATH_FWD_HPP
+#define BOOST_MATH_SPECIAL_MATH_FWD_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/detail/round_fwd.hpp>
+#include <boost/math/tools/promotion.hpp> // for argument promotion.
+#include <boost/math/policies/policy.hpp>
+#include <boost/mpl/comparison.hpp>
+#include <boost/config/no_tr1/complex.hpp>
+
+#define BOOST_NO_MACRO_EXPAND /**/
+
+namespace boost
+{
+ namespace math
+ { // Math functions (in roughly alphabetic order).
+
+ // Beta functions.
+ template <class RT1, class RT2>
+ typename tools::promote_args<RT1, RT2>::type
+ beta(RT1 a, RT2 b); // Beta function (2 arguments).
+
+ template <class RT1, class RT2, class A>
+ typename tools::promote_args<RT1, RT2, A>::type
+ beta(RT1 a, RT2 b, A x); // Beta function (3 arguments).
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ beta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Beta function (3 arguments).
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ betac(RT1 a, RT2 b, RT3 x);
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ betac(RT1 a, RT2 b, RT3 x, const Policy& pol);
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta(RT1 a, RT2 b, RT3 x); // Incomplete beta function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta function.
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac(RT1 a, RT2 b, RT3 x); // Incomplete beta complement function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta complement function.
+
+ template <class T1, class T2, class T3, class T4>
+ typename tools::promote_args<T1, T2, T3, T4>::type
+ ibeta_inv(T1 a, T2 b, T3 p, T4* py);
+
+ template <class T1, class T2, class T3, class T4, class Policy>
+ typename tools::promote_args<T1, T2, T3, T4>::type
+ ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol);
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_inv(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_inv(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function.
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_inva(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_inva(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function.
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_invb(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_invb(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function.
+
+ template <class T1, class T2, class T3, class T4>
+ typename tools::promote_args<T1, T2, T3, T4>::type
+ ibetac_inv(T1 a, T2 b, T3 q, T4* py);
+
+ template <class T1, class T2, class T3, class T4, class Policy>
+ typename tools::promote_args<T1, T2, T3, T4>::type
+ ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol);
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inv(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function.
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inva(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_inva(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function.
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_invb(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function.
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibetac_invb(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function.
+
+ template <class RT1, class RT2, class RT3>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_derivative(RT1 a, RT2 b, RT3 x); // derivative of incomplete beta
+
+ template <class RT1, class RT2, class RT3, class Policy>
+ typename tools::promote_args<RT1, RT2, RT3>::type
+ ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy& pol); // derivative of incomplete beta
+
+ // erf & erfc error functions.
+ template <class RT> // Error function.
+ typename tools::promote_args<RT>::type erf(RT z);
+ template <class RT, class Policy> // Error function.
+ typename tools::promote_args<RT>::type erf(RT z, const Policy&);
+
+ template <class RT>// Error function complement.
+ typename tools::promote_args<RT>::type erfc(RT z);
+ template <class RT, class Policy>// Error function complement.
+ typename tools::promote_args<RT>::type erfc(RT z, const Policy&);
+
+ template <class RT>// Error function inverse.
+ typename tools::promote_args<RT>::type erf_inv(RT z);
+ template <class RT, class Policy>// Error function inverse.
+ typename tools::promote_args<RT>::type erf_inv(RT z, const Policy& pol);
+
+ template <class RT>// Error function complement inverse.
+ typename tools::promote_args<RT>::type erfc_inv(RT z);
+ template <class RT, class Policy>// Error function complement inverse.
+ typename tools::promote_args<RT>::type erfc_inv(RT z, const Policy& pol);
+
+ // Polynomials:
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1);
+
+ template <class T>
+ typename tools::promote_args<T>::type
+ legendre_p(int l, T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type
+ legendre_p(int l, T x, const Policy& pol);
+
+ template <class T>
+ typename tools::promote_args<T>::type
+ legendre_q(unsigned l, T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type
+ legendre_q(unsigned l, T x, const Policy& pol);
+
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1);
+
+ template <class T>
+ typename tools::promote_args<T>::type
+ legendre_p(int l, int m, T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type
+ legendre_p(int l, int m, T x, const Policy& pol);
+
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ laguerre_next(unsigned n, T1 x, T2 Ln, T3 Lnm1);
+
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ laguerre_next(unsigned n, unsigned l, T1 x, T2 Pl, T3 Plm1);
+
+ template <class T>
+ typename tools::promote_args<T>::type
+ laguerre(unsigned n, T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type
+ laguerre(unsigned n, unsigned m, T x, const Policy& pol);
+
+ template <class T1, class T2>
+ struct laguerre_result
+ {
+ typedef typename mpl::if_<
+ policies::is_policy<T2>,
+ typename tools::promote_args<T1>::type,
+ typename tools::promote_args<T2>::type
+ >::type type;
+ };
+
+ template <class T1, class T2>
+ typename laguerre_result<T1, T2>::type
+ laguerre(unsigned n, T1 m, T2 x);
+
+ template <class T>
+ typename tools::promote_args<T>::type
+ hermite(unsigned n, T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type
+ hermite(unsigned n, T x, const Policy& pol);
+
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1);
+
+ template <class T1, class T2>
+ std::complex<typename tools::promote_args<T1, T2>::type>
+ spherical_harmonic(unsigned n, int m, T1 theta, T2 phi);
+
+ template <class T1, class T2, class Policy>
+ std::complex<typename tools::promote_args<T1, T2>::type>
+ spherical_harmonic(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type
+ spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type
+ spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type
+ spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type
+ spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);
+
+ // Elliptic integrals:
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ ellint_rf(T1 x, T2 y, T3 z);
+
+ template <class T1, class T2, class T3, class Policy>
+ typename tools::promote_args<T1, T2, T3>::type
+ ellint_rf(T1 x, T2 y, T3 z, const Policy& pol);
+
+ template <class T1, class T2, class T3>
+ typename tools::promote_args<T1, T2, T3>::type
+ ellint_rd(T1 x, T2 y, T3 z);
+
+ template <class T1, class T2, class T3, class Policy>
+ typename tools::promote_args<T1, T2, T3>::type
+ ellint_rd(T1 x, T2 y, T3 z, const Policy& pol);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type
+ ellint_rc(T1 x, T2 y);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type
+ ellint_rc(T1 x, T2 y, const Policy& pol);
+
+ template <class T1, class T2, class T3, class T4>
+ typename tools::promote_args<T1, T2, T3, T4>::type
+ ellint_rj(T1 x, T2 y, T3 z, T4 p);
+
+ template <class T1, class T2, class T3, class T4, class Policy>
+ typename tools::promote_args<T1, T2, T3, T4>::type
+ ellint_rj(T1 x, T2 y, T3 z, T4 p, const Policy& pol);
+
+ template <typename T>
+ typename tools::promote_args<T>::type ellint_2(T k);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type ellint_2(T1 k, T2 phi);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type ellint_2(T1 k, T2 phi, const Policy& pol);
+
+ template <typename T>
+ typename tools::promote_args<T>::type ellint_1(T k);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type ellint_1(T1 k, T2 phi);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type ellint_1(T1 k, T2 phi, const Policy& pol);
+
+ namespace detail{
+
+ template <class T, class U, class V>
+ struct ellint_3_result
+ {
+ typedef typename mpl::if_<
+ policies::is_policy<V>,
+ typename tools::promote_args<T, U>::type,
+ typename tools::promote_args<T, U, V>::type
+ >::type type;
+ };
+
+ } // namespace detail
+
+
+ template <class T1, class T2, class T3>
+ typename detail::ellint_3_result<T1, T2, T3>::type ellint_3(T1 k, T2 v, T3 phi);
+
+ template <class T1, class T2, class T3, class Policy>
+ typename tools::promote_args<T1, T2, T3>::type ellint_3(T1 k, T2 v, T3 phi, const Policy& pol);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type ellint_3(T1 k, T2 v);
+
+ // Factorial functions.
+ // Note: not for integral types, at present.
+ template <class RT>
+ struct max_factorial;
+ template <class RT>
+ RT factorial(unsigned int);
+ template <class RT, class Policy>
+ RT factorial(unsigned int, const Policy& pol);
+ template <class RT>
+ RT unchecked_factorial(unsigned int BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(RT));
+ template <class RT>
+ RT double_factorial(unsigned i);
+ template <class RT, class Policy>
+ RT double_factorial(unsigned i, const Policy& pol);
+
+ template <class RT>
+ typename tools::promote_args<RT>::type falling_factorial(RT x, unsigned n);
+
+ template <class RT, class Policy>
+ typename tools::promote_args<RT>::type falling_factorial(RT x, unsigned n, const Policy& pol);
+
+ template <class RT>
+ typename tools::promote_args<RT>::type rising_factorial(RT x, int n);
+
+ template <class RT, class Policy>
+ typename tools::promote_args<RT>::type rising_factorial(RT x, int n, const Policy& pol);
+
+ // Gamma functions.
+ template <class RT>
+ typename tools::promote_args<RT>::type tgamma(RT z);
+
+ template <class RT>
+ typename tools::promote_args<RT>::type tgamma1pm1(RT z);
+
+ template <class RT, class Policy>
+ typename tools::promote_args<RT>::type tgamma1pm1(RT z, const Policy& pol);
+
+ template <class RT1, class RT2>
+ typename tools::promote_args<RT1, RT2>::type tgamma(RT1 a, RT2 z);
+
+ template <class RT1, class RT2, class Policy>
+ typename tools::promote_args<RT1, RT2>::type tgamma(RT1 a, RT2 z, const Policy& pol);
+
+ template <class RT>
+ typename tools::promote_args<RT>::type lgamma(RT z, int* sign);
+
+ template <class RT, class Policy>
+ typename tools::promote_args<RT>::type lgamma(RT z, int* sign, const Policy& pol);
+
+ template <class RT>
+ typename tools::promote_args<RT>::type lgamma(RT x);
+
+ template <class RT, class Policy>
+ typename tools::promote_args<RT>::type lgamma(RT x, const Policy& pol);
+
+ template <class RT1, class RT2>
+ typename tools::promote_args<RT1, RT2>::type tgamma_lower(RT1 a, RT2 z);
+
+ template <class RT1, class RT2, class Policy>
+ typename tools::promote_args<RT1, RT2>::type tgamma_lower(RT1 a, RT2 z, const Policy&);
+
+ template <class RT1, class RT2>
+ typename tools::promote_args<RT1, RT2>::type gamma_q(RT1 a, RT2 z);
+
+ template <class RT1, class RT2, class Policy>
+ typename tools::promote_args<RT1, RT2>::type gamma_q(RT1 a, RT2 z, const Policy&);
+
+ template <class RT1, class RT2>
+ typename tools::promote_args<RT1, RT2>::type gamma_p(RT1 a, RT2 z);
+
+ template <class RT1, class RT2, class Policy>
+ typename tools::promote_args<RT1, RT2>::type gamma_p(RT1 a, RT2 z, const Policy&);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type tgamma_delta_ratio(T1 z, T2 delta);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type tgamma_delta_ratio(T1 z, T2 delta, const Policy&);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type tgamma_ratio(T1 a, T2 b);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type tgamma_ratio(T1 a, T2 b, const Policy&);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type gamma_p_derivative(T1 a, T2 x);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type gamma_p_derivative(T1 a, T2 x, const Policy&);
+
+ // gamma inverse.
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type gamma_p_inv(T1 a, T2 p);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type gamma_p_inva(T1 a, T2 p, const Policy&);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type gamma_p_inva(T1 a, T2 p);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type gamma_p_inv(T1 a, T2 p, const Policy&);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type gamma_q_inv(T1 a, T2 q);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type gamma_q_inv(T1 a, T2 q, const Policy&);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type gamma_q_inva(T1 a, T2 q);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type gamma_q_inva(T1 a, T2 q, const Policy&);
+
+ // digamma:
+ template <class T>
+ typename tools::promote_args<T>::type digamma(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type digamma(T x, const Policy&);
+
+ // Hypotenuse function sqrt(x ^ 2 + y ^ 2).
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type
+ hypot(T1 x, T2 y);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type
+ hypot(T1 x, T2 y, const Policy&);
+
+ // cbrt - cube root.
+ template <class RT>
+ typename tools::promote_args<RT>::type cbrt(RT z);
+
+ template <class RT, class Policy>
+ typename tools::promote_args<RT>::type cbrt(RT z, const Policy&);
+
+ // log1p is log(x + 1)
+ template <class T>
+ typename tools::promote_args<T>::type log1p(T);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type log1p(T, const Policy&);
+
+ // log1pmx is log(x + 1) - x
+ template <class T>
+ typename tools::promote_args<T>::type log1pmx(T);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type log1pmx(T, const Policy&);
+
+ // Exp (x) minus 1 functions.
+ template <class T>
+ typename tools::promote_args<T>::type expm1(T);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type expm1(T, const Policy&);
+
+ // Power - 1
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type
+ powm1(const T1 a, const T2 z);
+
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type
+ powm1(const T1 a, const T2 z, const Policy&);
+
+ // sqrt(1+x) - 1
+ template <class T>
+ typename tools::promote_args<T>::type sqrt1pm1(const T& val);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type sqrt1pm1(const T& val, const Policy&);
+
+ // sinus cardinals:
+ template <class T>
+ typename tools::promote_args<T>::type sinc_pi(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type sinc_pi(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type sinhc_pi(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type sinhc_pi(T x, const Policy&);
+
+ // inverse hyperbolics:
+ template<typename T>
+ typename tools::promote_args<T>::type asinh(T x);
+
+ template<typename T, class Policy>
+ typename tools::promote_args<T>::type asinh(T x, const Policy&);
+
+ template<typename T>
+ typename tools::promote_args<T>::type acosh(T x);
+
+ template<typename T, class Policy>
+ typename tools::promote_args<T>::type acosh(T x, const Policy&);
+
+ template<typename T>
+ typename tools::promote_args<T>::type atanh(T x);
+
+ template<typename T, class Policy>
+ typename tools::promote_args<T>::type atanh(T x, const Policy&);
+
+ namespace detail{
+
+ typedef mpl::int_<0> bessel_no_int_tag; // No integer optimisation possible.
+ typedef mpl::int_<1> bessel_maybe_int_tag; // Maybe integer optimisation.
+ typedef mpl::int_<2> bessel_int_tag; // Definite integer optimistaion.
+
+ template <class T1, class T2, class Policy>
+ struct bessel_traits
+ {
+ typedef typename tools::promote_args<
+ T1, T2
+ >::type result_type;
+
+ typedef typename policies::precision<result_type, Policy>::type precision_type;
+
+ typedef typename mpl::if_<
+ mpl::or_<
+ mpl::less_equal<precision_type, mpl::int_<0> >,
+ mpl::greater<precision_type, mpl::int_<64> > >,
+ bessel_no_int_tag,
+ typename mpl::if_<
+ is_integral<T1>,
+ bessel_int_tag,
+ bessel_maybe_int_tag
+ >::type
+ >::type optimisation_tag;
+ };
+ } // detail
+
+ // Bessel functions:
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_j(T1 v, T2 x, const Policy& pol);
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_j_prime(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_j(T1 v, T2 x);
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_j_prime(T1 v, T2 x);
+
+ template <class T, class Policy>
+ typename detail::bessel_traits<T, T, Policy>::result_type sph_bessel(unsigned v, T x, const Policy& pol);
+ template <class T, class Policy>
+ typename detail::bessel_traits<T, T, Policy>::result_type sph_bessel_prime(unsigned v, T x, const Policy& pol);
+
+ template <class T>
+ typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_bessel(unsigned v, T x);
+ template <class T>
+ typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_bessel_prime(unsigned v, T x);
+
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_i(T1 v, T2 x, const Policy& pol);
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_i_prime(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_i(T1 v, T2 x);
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_i_prime(T1 v, T2 x);
+
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_k(T1 v, T2 x, const Policy& pol);
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_bessel_k_prime(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_k(T1 v, T2 x);
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_bessel_k_prime(T1 v, T2 x);
+
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_neumann(T1 v, T2 x, const Policy& pol);
+ template <class T1, class T2, class Policy>
+ typename detail::bessel_traits<T1, T2, Policy>::result_type cyl_neumann_prime(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_neumann(T1 v, T2 x);
+ template <class T1, class T2>
+ typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type cyl_neumann_prime(T1 v, T2 x);
+
+ template <class T, class Policy>
+ typename detail::bessel_traits<T, T, Policy>::result_type sph_neumann(unsigned v, T x, const Policy& pol);
+ template <class T, class Policy>
+ typename detail::bessel_traits<T, T, Policy>::result_type sph_neumann_prime(unsigned v, T x, const Policy& pol);
+
+ template <class T>
+ typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_neumann(unsigned v, T x);
+ template <class T>
+ typename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_neumann_prime(unsigned v, T x);
+
+ template <class T, class Policy>
+ typename detail::bessel_traits<T, T, Policy>::result_type cyl_bessel_j_zero(T v, int m, const Policy& pol);
+
+ template <class T>
+ typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_bessel_j_zero(T v, int m);
+
+ template <class T, class OutputIterator>
+ OutputIterator cyl_bessel_j_zero(T v,
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it);
+
+ template <class T, class OutputIterator, class Policy>
+ OutputIterator cyl_bessel_j_zero(T v,
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it,
+ const Policy&);
+
+ template <class T, class Policy>
+ typename detail::bessel_traits<T, T, Policy>::result_type cyl_neumann_zero(T v, int m, const Policy& pol);
+
+ template <class T>
+ typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_neumann_zero(T v, int m);
+
+ template <class T, class OutputIterator>
+ OutputIterator cyl_neumann_zero(T v,
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it);
+
+ template <class T, class OutputIterator, class Policy>
+ OutputIterator cyl_neumann_zero(T v,
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it,
+ const Policy&);
+
+ template <class T1, class T2>
+ std::complex<typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type> cyl_hankel_1(T1 v, T2 x);
+
+ template <class T1, class T2, class Policy>
+ std::complex<typename detail::bessel_traits<T1, T2, Policy>::result_type> cyl_hankel_1(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2, class Policy>
+ std::complex<typename detail::bessel_traits<T1, T2, Policy>::result_type> cyl_hankel_2(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ std::complex<typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type> cyl_hankel_2(T1 v, T2 x);
+
+ template <class T1, class T2, class Policy>
+ std::complex<typename detail::bessel_traits<T1, T2, Policy>::result_type> sph_hankel_1(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ std::complex<typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type> sph_hankel_1(T1 v, T2 x);
+
+ template <class T1, class T2, class Policy>
+ std::complex<typename detail::bessel_traits<T1, T2, Policy>::result_type> sph_hankel_2(T1 v, T2 x, const Policy& pol);
+
+ template <class T1, class T2>
+ std::complex<typename detail::bessel_traits<T1, T2, policies::policy<> >::result_type> sph_hankel_2(T1 v, T2 x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type airy_ai(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type airy_ai(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type airy_bi(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type airy_bi(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type airy_ai_prime(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type airy_ai_prime(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type airy_bi_prime(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type airy_bi_prime(T x);
+
+ template <class T>
+ T airy_ai_zero(int m);
+ template <class T, class Policy>
+ T airy_ai_zero(int m, const Policy&);
+
+ template <class OutputIterator>
+ OutputIterator airy_ai_zero(
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it);
+ template <class OutputIterator, class Policy>
+ OutputIterator airy_ai_zero(
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it,
+ const Policy&);
+
+ template <class T>
+ T airy_bi_zero(int m);
+ template <class T, class Policy>
+ T airy_bi_zero(int m, const Policy&);
+
+ template <class OutputIterator>
+ OutputIterator airy_bi_zero(
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it);
+ template <class OutputIterator, class Policy>
+ OutputIterator airy_bi_zero(
+ int start_index,
+ unsigned number_of_zeros,
+ OutputIterator out_it,
+ const Policy&);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type sin_pi(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type sin_pi(T x);
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type cos_pi(T x, const Policy&);
+
+ template <class T>
+ typename tools::promote_args<T>::type cos_pi(T x);
+
+ template <class T>
+ int fpclassify BOOST_NO_MACRO_EXPAND(T t);
+
+ template <class T>
+ bool isfinite BOOST_NO_MACRO_EXPAND(T z);
+
+ template <class T>
+ bool isinf BOOST_NO_MACRO_EXPAND(T t);
+
+ template <class T>
+ bool isnan BOOST_NO_MACRO_EXPAND(T t);
+
+ template <class T>
+ bool isnormal BOOST_NO_MACRO_EXPAND(T t);
+
+ template<class T>
+ int signbit BOOST_NO_MACRO_EXPAND(T x);
+
+ template <class T>
+ int sign BOOST_NO_MACRO_EXPAND(const T& z);
+
+ template <class T, class U>
+ typename tools::promote_args_permissive<T, U>::type copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y);
+
+ template <class T>
+ typename tools::promote_args_permissive<T>::type changesign BOOST_NO_MACRO_EXPAND(const T& z);
+
+ // Exponential integrals:
+ namespace detail{
+
+ template <class T, class U>
+ struct expint_result
+ {
+ typedef typename mpl::if_<
+ policies::is_policy<U>,
+ typename tools::promote_args<T>::type,
+ typename tools::promote_args<U>::type
+ >::type type;
+ };
+
+ } // namespace detail
+
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type expint(unsigned n, T z, const Policy&);
+
+ template <class T, class U>
+ typename detail::expint_result<T, U>::type expint(T const z, U const u);
+
+ template <class T>
+ typename tools::promote_args<T>::type expint(T z);
+
+ // Zeta:
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type zeta(T s, const Policy&);
+
+ // Owen's T function:
+ template <class T1, class T2, class Policy>
+ typename tools::promote_args<T1, T2>::type owens_t(T1 h, T2 a, const Policy& pol);
+
+ template <class T1, class T2>
+ typename tools::promote_args<T1, T2>::type owens_t(T1 h, T2 a);
+
+ // Jacobi Functions:
+ template <class T, class U, class V, class Policy>
+ typename tools::promote_args<T, U, V>::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&);
+
+ template <class T, class U, class V>
+ typename tools::promote_args<T, U, V>::type jacobi_elliptic(T k, U theta, V* pcn = 0, V* pdn = 0);
+
+ template <class U, class T, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_sn(U k, T theta, const Policy& pol);
+
+ template <class U, class T>
+ typename tools::promote_args<T, U>::type jacobi_sn(U k, T theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_cn(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_cn(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_dn(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_dn(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_cd(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_cd(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_dc(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_dc(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_ns(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_ns(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_sd(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_sd(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_ds(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_ds(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_nc(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_nc(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_nd(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_nd(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_sc(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_sc(T k, U theta);
+
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type jacobi_cs(T k, U theta, const Policy& pol);
+
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type jacobi_cs(T k, U theta);
+
+
+ template <class T>
+ typename tools::promote_args<T>::type zeta(T s);
+
+ // pow:
+ template <int N, typename T, class Policy>
+ typename tools::promote_args<T>::type pow(T base, const Policy& policy);
+
+ template <int N, typename T>
+ typename tools::promote_args<T>::type pow(T base);
+
+ // next:
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type nextafter(const T&, const U&, const Policy&);
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type nextafter(const T&, const U&);
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type float_next(const T&, const Policy&);
+ template <class T>
+ typename tools::promote_args<T>::type float_next(const T&);
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type float_prior(const T&, const Policy&);
+ template <class T>
+ typename tools::promote_args<T>::type float_prior(const T&);
+ template <class T, class U, class Policy>
+ typename tools::promote_args<T, U>::type float_distance(const T&, const U&, const Policy&);
+ template <class T, class U>
+ typename tools::promote_args<T, U>::type float_distance(const T&, const U&);
+ template <class T, class Policy>
+ typename tools::promote_args<T>::type float_advance(T val, int distance, const Policy& pol);
+ template <class T>
+ typename tools::promote_args<T>::type float_advance(const T& val, int distance);
+
+ template<class T>
+ T unchecked_bernoulli_b2n(const std::size_t n);
+ template <class T, class Policy>
+ T bernoulli_b2n(const int i, const Policy &pol);
+ template <class T>
+ T bernoulli_b2n(const int i);
+ template <class T, class OutputIterator, class Policy>
+ OutputIterator bernoulli_b2n(const int start_index,
+ const unsigned number_of_bernoullis_b2n,
+ OutputIterator out_it,
+ const Policy& pol);
+ template <class T, class OutputIterator>
+ OutputIterator bernoulli_b2n(const int start_index,
+ const unsigned number_of_bernoullis_b2n,
+ OutputIterator out_it);
+ template <class T, class Policy>
+ T tangent_t2n(const int i, const Policy &pol);
+ template <class T>
+ T tangent_t2n(const int i);
+ template <class T, class OutputIterator, class Policy>
+ OutputIterator tangent_t2n(const int start_index,
+ const unsigned number_of_bernoullis_b2n,
+ OutputIterator out_it,
+ const Policy& pol);
+ template <class T, class OutputIterator>
+ OutputIterator tangent_t2n(const int start_index,
+ const unsigned number_of_bernoullis_b2n,
+ OutputIterator out_it);
+
+ } // namespace math
+} // namespace boost
+
+#ifdef BOOST_HAS_LONG_LONG
+#define BOOST_MATH_DETAIL_LL_FUNC(Policy)\
+ \
+ template <class T>\
+ inline T modf(const T& v, boost::long_long_type* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\
+ \
+ template <class T>\
+ inline boost::long_long_type lltrunc(const T& v){ using boost::math::lltrunc; return lltrunc(v, Policy()); }\
+ \
+ template <class T>\
+ inline boost::long_long_type llround(const T& v){ using boost::math::llround; return llround(v, Policy()); }\
+
+#else
+#define BOOST_MATH_DETAIL_LL_FUNC(Policy)
+#endif
+
+#define BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)\
+ \
+ BOOST_MATH_DETAIL_LL_FUNC(Policy)\
+ \
+ template <class RT1, class RT2>\
+ inline typename boost::math::tools::promote_args<RT1, RT2>::type \
+ beta(RT1 a, RT2 b) { return ::boost::math::beta(a, b, Policy()); }\
+\
+ template <class RT1, class RT2, class A>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, A>::type \
+ beta(RT1 a, RT2 b, A x){ return ::boost::math::beta(a, b, x, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ betac(RT1 a, RT2 b, RT3 x) { return ::boost::math::betac(a, b, x, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibeta(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta(a, b, x, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibetac(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibetac(a, b, x, Policy()); }\
+\
+ template <class T1, class T2, class T3, class T4>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3, T4>::type \
+ ibeta_inv(T1 a, T2 b, T3 p, T4* py){ return ::boost::math::ibeta_inv(a, b, p, py, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibeta_inv(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inv(a, b, p, Policy()); }\
+\
+ template <class T1, class T2, class T3, class T4>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3, T4>::type \
+ ibetac_inv(T1 a, T2 b, T3 q, T4* py){ return ::boost::math::ibetac_inv(a, b, q, py, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibeta_inva(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inva(a, b, p, Policy()); }\
+\
+ template <class T1, class T2, class T3>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3>::type \
+ ibetac_inva(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_inva(a, b, q, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibeta_invb(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_invb(a, b, p, Policy()); }\
+\
+ template <class T1, class T2, class T3>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3>::type \
+ ibetac_invb(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_invb(a, b, q, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibetac_inv(RT1 a, RT2 b, RT3 q){ return ::boost::math::ibetac_inv(a, b, q, Policy()); }\
+\
+ template <class RT1, class RT2, class RT3>\
+ inline typename boost::math::tools::promote_args<RT1, RT2, RT3>::type \
+ ibeta_derivative(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta_derivative(a, b, x, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type erf(RT z) { return ::boost::math::erf(z, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type erfc(RT z){ return ::boost::math::erfc(z, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type erf_inv(RT z) { return ::boost::math::erf_inv(z, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type erfc_inv(RT z){ return ::boost::math::erfc_inv(z, Policy()); }\
+\
+ using boost::math::legendre_next;\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type \
+ legendre_p(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type \
+ legendre_q(unsigned l, T x){ return ::boost::math::legendre_q(l, x, Policy()); }\
+\
+ using ::boost::math::legendre_next;\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type \
+ legendre_p(int l, int m, T x){ return ::boost::math::legendre_p(l, m, x, Policy()); }\
+\
+ using ::boost::math::laguerre_next;\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type \
+ laguerre(unsigned n, T x){ return ::boost::math::laguerre(n, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::laguerre_result<T1, T2>::type \
+ laguerre(unsigned n, T1 m, T2 x) { return ::boost::math::laguerre(n, m, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type \
+ hermite(unsigned n, T x){ return ::boost::math::hermite(n, x, Policy()); }\
+\
+ using boost::math::hermite_next;\
+\
+ template <class T1, class T2>\
+ inline std::complex<typename boost::math::tools::promote_args<T1, T2>::type> \
+ spherical_harmonic(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic(n, m, theta, phi, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type \
+ spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi){ return ::boost::math::spherical_harmonic_r(n, m, theta, phi, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type \
+ spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic_i(n, m, theta, phi, Policy()); }\
+\
+ template <class T1, class T2, class Policy>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type \
+ spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);\
+\
+ template <class T1, class T2, class T3>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3>::type \
+ ellint_rf(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rf(x, y, z, Policy()); }\
+\
+ template <class T1, class T2, class T3>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3>::type \
+ ellint_rd(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rd(x, y, z, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type \
+ ellint_rc(T1 x, T2 y){ return ::boost::math::ellint_rc(x, y, Policy()); }\
+\
+ template <class T1, class T2, class T3, class T4>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3, T4>::type \
+ ellint_rj(T1 x, T2 y, T3 z, T4 p){ return boost::math::ellint_rj(x, y, z, p, Policy()); }\
+\
+ template <typename T>\
+ inline typename boost::math::tools::promote_args<T>::type ellint_2(T k){ return boost::math::ellint_2(k, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type ellint_2(T1 k, T2 phi){ return boost::math::ellint_2(k, phi, Policy()); }\
+\
+ template <typename T>\
+ inline typename boost::math::tools::promote_args<T>::type ellint_1(T k){ return boost::math::ellint_1(k, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type ellint_1(T1 k, T2 phi){ return boost::math::ellint_1(k, phi, Policy()); }\
+\
+ template <class T1, class T2, class T3>\
+ inline typename boost::math::tools::promote_args<T1, T2, T3>::type ellint_3(T1 k, T2 v, T3 phi){ return boost::math::ellint_3(k, v, phi, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type ellint_3(T1 k, T2 v){ return boost::math::ellint_3(k, v, Policy()); }\
+\
+ using boost::math::max_factorial;\
+ template <class RT>\
+ inline RT factorial(unsigned int i) { return boost::math::factorial<RT>(i, Policy()); }\
+ using boost::math::unchecked_factorial;\
+ template <class RT>\
+ inline RT double_factorial(unsigned i){ return boost::math::double_factorial<RT>(i, Policy()); }\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type falling_factorial(RT x, unsigned n){ return boost::math::falling_factorial(x, n, Policy()); }\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type rising_factorial(RT x, unsigned n){ return boost::math::rising_factorial(x, n, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type tgamma(RT z){ return boost::math::tgamma(z, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type tgamma1pm1(RT z){ return boost::math::tgamma1pm1(z, Policy()); }\
+\
+ template <class RT1, class RT2>\
+ inline typename boost::math::tools::promote_args<RT1, RT2>::type tgamma(RT1 a, RT2 z){ return boost::math::tgamma(a, z, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type lgamma(RT z, int* sign){ return boost::math::lgamma(z, sign, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type lgamma(RT x){ return boost::math::lgamma(x, Policy()); }\
+\
+ template <class RT1, class RT2>\
+ inline typename boost::math::tools::promote_args<RT1, RT2>::type tgamma_lower(RT1 a, RT2 z){ return boost::math::tgamma_lower(a, z, Policy()); }\
+\
+ template <class RT1, class RT2>\
+ inline typename boost::math::tools::promote_args<RT1, RT2>::type gamma_q(RT1 a, RT2 z){ return boost::math::gamma_q(a, z, Policy()); }\
+\
+ template <class RT1, class RT2>\
+ inline typename boost::math::tools::promote_args<RT1, RT2>::type gamma_p(RT1 a, RT2 z){ return boost::math::gamma_p(a, z, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type tgamma_delta_ratio(T1 z, T2 delta){ return boost::math::tgamma_delta_ratio(z, delta, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type tgamma_ratio(T1 a, T2 b) { return boost::math::tgamma_ratio(a, b, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type gamma_p_derivative(T1 a, T2 x){ return boost::math::gamma_p_derivative(a, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type gamma_p_inv(T1 a, T2 p){ return boost::math::gamma_p_inv(a, p, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type gamma_p_inva(T1 a, T2 p){ return boost::math::gamma_p_inva(a, p, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type gamma_q_inv(T1 a, T2 q){ return boost::math::gamma_q_inv(a, q, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type gamma_q_inva(T1 a, T2 q){ return boost::math::gamma_q_inva(a, q, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type digamma(T x){ return boost::math::digamma(x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type \
+ hypot(T1 x, T2 y){ return boost::math::hypot(x, y, Policy()); }\
+\
+ template <class RT>\
+ inline typename boost::math::tools::promote_args<RT>::type cbrt(RT z){ return boost::math::cbrt(z, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type log1p(T x){ return boost::math::log1p(x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type log1pmx(T x){ return boost::math::log1pmx(x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type expm1(T x){ return boost::math::expm1(x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::tools::promote_args<T1, T2>::type \
+ powm1(const T1 a, const T2 z){ return boost::math::powm1(a, z, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type sqrt1pm1(const T& val){ return boost::math::sqrt1pm1(val, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type sinc_pi(T x){ return boost::math::sinc_pi(x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type sinhc_pi(T x){ return boost::math::sinhc_pi(x, Policy()); }\
+\
+ template<typename T>\
+ inline typename boost::math::tools::promote_args<T>::type asinh(const T x){ return boost::math::asinh(x, Policy()); }\
+\
+ template<typename T>\
+ inline typename boost::math::tools::promote_args<T>::type acosh(const T x){ return boost::math::acosh(x, Policy()); }\
+\
+ template<typename T>\
+ inline typename boost::math::tools::promote_args<T>::type atanh(const T x){ return boost::math::atanh(x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type cyl_bessel_j(T1 v, T2 x)\
+ { return boost::math::cyl_bessel_j(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type cyl_bessel_j_prime(T1 v, T2 x)\
+ { return boost::math::cyl_bessel_j_prime(v, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::detail::bessel_traits<T, T, Policy >::result_type sph_bessel(unsigned v, T x)\
+ { return boost::math::sph_bessel(v, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::detail::bessel_traits<T, T, Policy >::result_type sph_bessel_prime(unsigned v, T x)\
+ { return boost::math::sph_bessel_prime(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type \
+ cyl_bessel_i(T1 v, T2 x) { return boost::math::cyl_bessel_i(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type \
+ cyl_bessel_i_prime(T1 v, T2 x) { return boost::math::cyl_bessel_i_prime(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type \
+ cyl_bessel_k(T1 v, T2 x) { return boost::math::cyl_bessel_k(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type \
+ cyl_bessel_k_prime(T1 v, T2 x) { return boost::math::cyl_bessel_k_prime(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type \
+ cyl_neumann(T1 v, T2 x){ return boost::math::cyl_neumann(v, x, Policy()); }\
+\
+ template <class T1, class T2>\
+ inline typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type \
+ cyl_neumann_prime(T1 v, T2 x){ return boost::math::cyl_neumann_prime(v, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::detail::bessel_traits<T, T, Policy >::result_type \
+ sph_neumann(unsigned v, T x){ return boost::math::sph_neumann(v, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::detail::bessel_traits<T, T, Policy >::result_type \
+ sph_neumann_prime(unsigned v, T x){ return boost::math::sph_neumann_prime(v, x, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::detail::bessel_traits<T, T, Policy >::result_type cyl_bessel_j_zero(T v, int m)\
+ { return boost::math::cyl_bessel_j_zero(v, m, Policy()); }\
+\
+template <class OutputIterator, class T>\
+ inline void cyl_bessel_j_zero(T v,\
+ int start_index,\
+ unsigned number_of_zeros,\
+ OutputIterator out_it)\
+ { boost::math::cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::detail::bessel_traits<T, T, Policy >::result_type cyl_neumann_zero(T v, int m)\
+ { return boost::math::cyl_neumann_zero(v, m, Policy()); }\
+\
+template <class OutputIterator, class T>\
+ inline void cyl_neumann_zero(T v,\
+ int start_index,\
+ unsigned number_of_zeros,\
+ OutputIterator out_it)\
+ { boost::math::cyl_neumann_zero(v, start_index, number_of_zeros, out_it, Policy()); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type sin_pi(T x){ return boost::math::sin_pi(x); }\
+\
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type cos_pi(T x){ return boost::math::cos_pi(x); }\
+\
+ using boost::math::fpclassify;\
+ using boost::math::isfinite;\
+ using boost::math::isinf;\
+ using boost::math::isnan;\
+ using boost::math::isnormal;\
+ using boost::math::signbit;\
+ using boost::math::sign;\
+ using boost::math::copysign;\
+ using boost::math::changesign;\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T,U>::type expint(T const& z, U const& u)\
+ { return boost::math::expint(z, u, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type expint(T z){ return boost::math::expint(z, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type zeta(T s){ return boost::math::zeta(s, Policy()); }\
+ \
+ template <class T>\
+ inline T round(const T& v){ using boost::math::round; return round(v, Policy()); }\
+ \
+ template <class T>\
+ inline int iround(const T& v){ using boost::math::iround; return iround(v, Policy()); }\
+ \
+ template <class T>\
+ inline long lround(const T& v){ using boost::math::lround; return lround(v, Policy()); }\
+ \
+ template <class T>\
+ inline T trunc(const T& v){ using boost::math::trunc; return trunc(v, Policy()); }\
+ \
+ template <class T>\
+ inline int itrunc(const T& v){ using boost::math::itrunc; return itrunc(v, Policy()); }\
+ \
+ template <class T>\
+ inline long ltrunc(const T& v){ using boost::math::ltrunc; return ltrunc(v, Policy()); }\
+ \
+ template <class T>\
+ inline T modf(const T& v, T* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\
+ \
+ template <class T>\
+ inline T modf(const T& v, int* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\
+ \
+ template <class T>\
+ inline T modf(const T& v, long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\
+ \
+ template <int N, class T>\
+ inline typename boost::math::tools::promote_args<T>::type pow(T v){ return boost::math::pow<N>(v, Policy()); }\
+ \
+ template <class T> T nextafter(const T& a, const T& b){ return boost::math::nextafter(a, b, Policy()); }\
+ template <class T> T float_next(const T& a){ return boost::math::float_next(a, Policy()); }\
+ template <class T> T float_prior(const T& a){ return boost::math::float_prior(a, Policy()); }\
+ template <class T> T float_distance(const T& a, const T& b){ return boost::math::float_distance(a, b, Policy()); }\
+ \
+ template <class RT1, class RT2>\
+ inline typename boost::math::tools::promote_args<RT1, RT2>::type owens_t(RT1 a, RT2 z){ return boost::math::owens_t(a, z, Policy()); }\
+ \
+ template <class T1, class T2>\
+ inline std::complex<typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type> cyl_hankel_1(T1 v, T2 x)\
+ { return boost::math::cyl_hankel_1(v, x, Policy()); }\
+ \
+ template <class T1, class T2>\
+ inline std::complex<typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type> cyl_hankel_2(T1 v, T2 x)\
+ { return boost::math::cyl_hankel_2(v, x, Policy()); }\
+ \
+ template <class T1, class T2>\
+ inline std::complex<typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type> sph_hankel_1(T1 v, T2 x)\
+ { return boost::math::sph_hankel_1(v, x, Policy()); }\
+ \
+ template <class T1, class T2>\
+ inline std::complex<typename boost::math::detail::bessel_traits<T1, T2, Policy >::result_type> sph_hankel_2(T1 v, T2 x)\
+ { return boost::math::sph_hankel_2(v, x, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type jacobi_elliptic(T k, T theta, T* pcn, T* pdn)\
+ { return boost::math::jacobi_elliptic(k, theta, pcn, pdn, Policy()); }\
+ \
+ template <class U, class T>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_sn(U k, T theta)\
+ { return boost::math::jacobi_sn(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_cn(T k, U theta)\
+ { return boost::math::jacobi_cn(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_dn(T k, U theta)\
+ { return boost::math::jacobi_dn(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_cd(T k, U theta)\
+ { return boost::math::jacobi_cd(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_dc(T k, U theta)\
+ { return boost::math::jacobi_dc(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_ns(T k, U theta)\
+ { return boost::math::jacobi_ns(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_sd(T k, U theta)\
+ { return boost::math::jacobi_sd(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_ds(T k, U theta)\
+ { return boost::math::jacobi_ds(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_nc(T k, U theta)\
+ { return boost::math::jacobi_nc(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_nd(T k, U theta)\
+ { return boost::math::jacobi_nd(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_sc(T k, U theta)\
+ { return boost::math::jacobi_sc(k, theta, Policy()); }\
+ \
+ template <class T, class U>\
+ inline typename boost::math::tools::promote_args<T, U>::type jacobi_cs(T k, U theta)\
+ { return boost::math::jacobi_cs(k, theta, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type airy_ai(T x)\
+ { return boost::math::airy_ai(x, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type airy_bi(T x)\
+ { return boost::math::airy_bi(x, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type airy_ai_prime(T x)\
+ { return boost::math::airy_ai_prime(x, Policy()); }\
+ \
+ template <class T>\
+ inline typename boost::math::tools::promote_args<T>::type airy_bi_prime(T x)\
+ { return boost::math::airy_bi_prime(x, Policy()); }\
+ \
+ template <class T>\
+ inline T airy_ai_zero(int m)\
+ { return boost::math::airy_ai_zero<T>(m, Policy()); }\
+ template <class T, class OutputIterator>\
+ OutputIterator airy_ai_zero(int start_index, unsigned number_of_zeros, OutputIterator out_it)\
+ { return boost::math::airy_ai_zero<T>(start_index, number_of_zeros, out_it, Policy()); }\
+ \
+ template <class T>\
+ inline T airy_bi_zero(int m)\
+ { return boost::math::airy_bi_zero<T>(m, Policy()); }\
+ template <class T, class OutputIterator>\
+ OutputIterator airy_bi_zero(int start_index, unsigned number_of_zeros, OutputIterator out_it)\
+ { return boost::math::airy_bi_zero<T>(start_index, number_of_zeros, out_it, Policy()); }\
+ \
+ template <class T>\
+ T bernoulli_b2n(const int i)\
+ { return boost::math::bernoulli_b2n<T>(i, Policy()); }\
+ template <class T, class OutputIterator>\
+ OutputIterator bernoulli_b2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\
+ { return boost::math::bernoulli_b2n<T>(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\
+ \
+ template <class T>\
+ T tangent_t2n(const int i)\
+ { return boost::math::tangent_t2n<T>(i, Policy()); }\
+ template <class T, class OutputIterator>\
+ OutputIterator tangent_t2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\
+ { return boost::math::tangent_t2n<T>(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\
+ \
+
+
+
+
+
+#endif // BOOST_MATH_SPECIAL_MATH_FWD_HPP
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/pow.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/pow.hpp
new file mode 100644
index 00000000000..4e9a252c0b8
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/pow.hpp
@@ -0,0 +1,141 @@
+// Boost pow.hpp header file
+// Computes a power with exponent known at compile-time
+
+// (C) Copyright Bruno Lalande 2008.
+// Distributed under 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+
+#ifndef BOOST_MATH_POW_HPP
+#define BOOST_MATH_POW_HPP
+
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/policies/policy.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/mpl/greater_equal.hpp>
+
+
+namespace boost {
+namespace math {
+
+
+namespace detail {
+
+
+template <int N, int M = N%2>
+struct positive_power
+{
+ template <typename T>
+ static T result(T base)
+ {
+ T power = positive_power<N/2>::result(base);
+ return power * power;
+ }
+};
+
+template <int N>
+struct positive_power<N, 1>
+{
+ template <typename T>
+ static T result(T base)
+ {
+ T power = positive_power<N/2>::result(base);
+ return base * power * power;
+ }
+};
+
+template <>
+struct positive_power<1, 1>
+{
+ template <typename T>
+ static T result(T base){ return base; }
+};
+
+
+template <int N, bool>
+struct power_if_positive
+{
+ template <typename T, class Policy>
+ static T result(T base, const Policy&)
+ { return positive_power<N>::result(base); }
+};
+
+template <int N>
+struct power_if_positive<N, false>
+{
+ template <typename T, class Policy>
+ static T result(T base, const Policy& policy)
+ {
+ if (base == 0)
+ {
+ return policies::raise_overflow_error<T>(
+ "boost::math::pow(%1%)",
+ "Attempted to compute a negative power of 0",
+ policy
+ );
+ }
+
+ return T(1) / positive_power<-N>::result(base);
+ }
+};
+
+template <>
+struct power_if_positive<0, true>
+{
+ template <typename T, class Policy>
+ static T result(T base, const Policy& policy)
+ {
+ if (base == 0)
+ {
+ return policies::raise_indeterminate_result_error<T>(
+ "boost::math::pow(%1%)",
+ "The result of pow<0>(%1%) is undetermined",
+ base,
+ T(1),
+ policy
+ );
+ }
+
+ return T(1);
+ }
+};
+
+
+template <int N>
+struct select_power_if_positive
+{
+ typedef typename mpl::greater_equal<
+ mpl::int_<N>,
+ mpl::int_<0>
+ >::type is_positive;
+
+ typedef power_if_positive<N, is_positive::value> type;
+};
+
+
+} // namespace detail
+
+
+template <int N, typename T, class Policy>
+inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy);
+}
+
+
+template <int N, typename T>
+inline typename tools::promote_args<T>::type pow(T base)
+{ return pow<N>(base, policies::policy<>()); }
+
+
+} // namespace math
+} // namespace boost
+
+
+#endif
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/powm1.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/powm1.hpp
new file mode 100644
index 00000000000..f3af3d6e59a
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/powm1.hpp
@@ -0,0 +1,61 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_POWM1
+#define BOOST_MATH_POWM1
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/expm1.hpp>
+#include <boost/assert.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+inline T powm1_imp(const T a, const T z, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+
+ if((fabs(a) < 1) || (fabs(z) < 1))
+ {
+ T p = log(a) * z;
+ if(fabs(p) < 2)
+ return boost::math::expm1(p, pol);
+ // otherwise fall though:
+ }
+ return pow(a, z) - 1;
+}
+
+} // detail
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+ powm1(const T1 a, const T2 z)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ return detail::powm1_imp(static_cast<result_type>(a), static_cast<result_type>(z), policies::policy<>());
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+ powm1(const T1 a, const T2 z, const Policy& pol)
+{
+ typedef typename tools::promote_args<T1, T2>::type result_type;
+ return detail::powm1_imp(static_cast<result_type>(a), static_cast<result_type>(z), pol);
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_POWM1
+
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/round.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/round.hpp
new file mode 100644
index 00000000000..7f33cdfbbf2
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/round.hpp
@@ -0,0 +1,109 @@
+// Copyright John Maddock 2007.
+// 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)
+
+#ifndef BOOST_MATH_ROUND_HPP
+#define BOOST_MATH_ROUND_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/config.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail{
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type round(const T& v, const Policy& pol, const mpl::false_)
+{
+ BOOST_MATH_STD_USING
+ typedef typename tools::promote_args<T>::type result_type;
+ if(!(boost::math::isfinite)(v))
+ return policies::raise_rounding_error("boost::math::round<%1%>(%1%)", 0, static_cast<result_type>(v), static_cast<result_type>(v), pol);
+ return v < 0 ? static_cast<result_type>(ceil(v - 0.5f)) : static_cast<result_type>(floor(v + 0.5f));
+}
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type round(const T& v, const Policy&, const mpl::true_)
+{
+ return v;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type round(const T& v, const Policy& pol)
+{
+ return detail::round(v, pol, mpl::bool_<detail::is_integer_for_rounding<T>::value>());
+}
+template <class T>
+inline typename tools::promote_args<T>::type round(const T& v)
+{
+ return round(v, policies::policy<>());
+}
+//
+// The following functions will not compile unless T has an
+// implicit convertion to the integer types. For user-defined
+// number types this will likely not be the case. In that case
+// these functions should either be specialized for the UDT in
+// question, or else overloads should be placed in the same
+// namespace as the UDT: these will then be found via argument
+// dependent lookup. See our concept archetypes for examples.
+//
+template <class T, class Policy>
+inline int iround(const T& v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ T r = boost::math::round(v, pol);
+ if((r > (std::numeric_limits<int>::max)()) || (r < (std::numeric_limits<int>::min)()))
+ return static_cast<int>(policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol));
+ return static_cast<int>(r);
+}
+template <class T>
+inline int iround(const T& v)
+{
+ return iround(v, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline long lround(const T& v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ T r = boost::math::round(v, pol);
+ if((r > (std::numeric_limits<long>::max)()) || (r < (std::numeric_limits<long>::min)()))
+ return static_cast<long int>(policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol));
+ return static_cast<long int>(r);
+}
+template <class T>
+inline long lround(const T& v)
+{
+ return lround(v, policies::policy<>());
+}
+
+#ifdef BOOST_HAS_LONG_LONG
+
+template <class T, class Policy>
+inline boost::long_long_type llround(const T& v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ T r = boost::math::round(v, pol);
+ if((r > (std::numeric_limits<boost::long_long_type>::max)()) || (r < (std::numeric_limits<boost::long_long_type>::min)()))
+ return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", 0, v, static_cast<boost::long_long_type>(0), pol));
+ return static_cast<boost::long_long_type>(r);
+}
+template <class T>
+inline boost::long_long_type llround(const T& v)
+{
+ return llround(v, policies::policy<>());
+}
+
+#endif
+
+}} // namespaces
+
+#endif // BOOST_MATH_ROUND_HPP
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/sign.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/sign.hpp
new file mode 100644
index 00000000000..f5c562d44cb
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/sign.hpp
@@ -0,0 +1,194 @@
+// (C) Copyright John Maddock 2006.
+// (C) Copyright Johan Rade 2006.
+// (C) Copyright Paul A. Bristow 2011 (added changesign).
+
+// 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)
+
+#ifndef BOOST_MATH_TOOLS_SIGN_HPP
+#define BOOST_MATH_TOOLS_SIGN_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/detail/fp_traits.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail {
+
+ // signbit
+
+#ifdef BOOST_MATH_USE_STD_FPCLASSIFY
+ template<class T>
+ inline int signbit_impl(T x, native_tag const&)
+ {
+ return (std::signbit)(x);
+ }
+#endif
+
+ // Generic versions first, note that these do not handle
+ // signed zero or NaN.
+
+ template<class T>
+ inline int signbit_impl(T x, generic_tag<true> const&)
+ {
+ return x < 0;
+ }
+
+ template<class T>
+ inline int signbit_impl(T x, generic_tag<false> const&)
+ {
+ return x < 0;
+ }
+
+#if defined(__GNUC__) && (LDBL_MANT_DIG == 106)
+ //
+ // Special handling for GCC's "double double" type,
+ // in this case the sign is the same as the sign we
+ // get by casting to double, no overflow/underflow
+ // can occur since the exponents are the same magnitude
+ // for the two types:
+ //
+ inline int signbit_impl(long double x, generic_tag<true> const&)
+ {
+ return boost::math::signbit(static_cast<double>(x));
+ }
+ inline int signbit_impl(long double x, generic_tag<false> const&)
+ {
+ return boost::math::signbit(static_cast<double>(x));
+ }
+#endif
+
+ template<class T>
+ inline int signbit_impl(T x, ieee_copy_all_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ return a & traits::sign ? 1 : 0;
+ }
+
+ template<class T>
+ inline int signbit_impl(T x, ieee_copy_leading_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+
+ return a & traits::sign ? 1 : 0;
+ }
+
+ // Changesign
+
+ // Generic versions first, note that these do not handle
+ // signed zero or NaN.
+
+ template<class T>
+ inline T (changesign_impl)(T x, generic_tag<true> const&)
+ {
+ return -x;
+ }
+
+ template<class T>
+ inline T (changesign_impl)(T x, generic_tag<false> const&)
+ {
+ return -x;
+ }
+#if defined(__GNUC__) && (LDBL_MANT_DIG == 106)
+ //
+ // Special handling for GCC's "double double" type,
+ // in this case we need to change the sign of both
+ // components of the "double double":
+ //
+ inline long double (changesign_impl)(long double x, generic_tag<true> const&)
+ {
+ double* pd = reinterpret_cast<double*>(&x);
+ pd[0] = boost::math::changesign(pd[0]);
+ pd[1] = boost::math::changesign(pd[1]);
+ return x;
+ }
+ inline long double (changesign_impl)(long double x, generic_tag<false> const&)
+ {
+ double* pd = reinterpret_cast<double*>(&x);
+ pd[0] = boost::math::changesign(pd[0]);
+ pd[1] = boost::math::changesign(pd[1]);
+ return x;
+ }
+#endif
+
+ template<class T>
+ inline T changesign_impl(T x, ieee_copy_all_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a ^= traits::sign;
+ traits::set_bits(x,a);
+ return x;
+ }
+
+ template<class T>
+ inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&)
+ {
+ typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::sign_change_type traits;
+
+ BOOST_DEDUCED_TYPENAME traits::bits a;
+ traits::get_bits(x,a);
+ a ^= traits::sign;
+ traits::set_bits(x,a);
+ return x;
+ }
+
+
+} // namespace detail
+
+template<class T> int (signbit)(T x)
+{
+ typedef typename detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+ // typedef typename boost::is_floating_point<T>::type fp_tag;
+ typedef typename tools::promote_args_permissive<T>::type result_type;
+ return detail::signbit_impl(static_cast<result_type>(x), method());
+}
+
+template <class T>
+inline int sign BOOST_NO_MACRO_EXPAND(const T& z)
+{
+ return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1;
+}
+
+template <class T> typename tools::promote_args_permissive<T>::type (changesign)(const T& x)
+{ //!< \brief return unchanged binary pattern of x, except for change of sign bit.
+ typedef typename detail::fp_traits<T>::sign_change_type traits;
+ typedef typename traits::method method;
+ // typedef typename boost::is_floating_point<T>::type fp_tag;
+ typedef typename tools::promote_args_permissive<T>::type result_type;
+
+ return detail::changesign_impl(static_cast<result_type>(x), method());
+}
+
+template <class T, class U>
+inline typename tools::promote_args_permissive<T, U>::type
+ copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y)
+{
+ BOOST_MATH_STD_USING
+ typedef typename tools::promote_args_permissive<T, U>::type result_type;
+ return (boost::math::signbit)(static_cast<result_type>(x)) != (boost::math::signbit)(static_cast<result_type>(y))
+ ? (boost::math::changesign)(static_cast<result_type>(x)) : static_cast<result_type>(x);
+}
+
+} // namespace math
+} // namespace boost
+
+
+#endif // BOOST_MATH_TOOLS_SIGN_HPP
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/sqrt1pm1.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/sqrt1pm1.hpp
new file mode 100644
index 00000000000..293a9d97b31
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/sqrt1pm1.hpp
@@ -0,0 +1,48 @@
+// (C) Copyright John Maddock 2006.
+// 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)
+
+#ifndef BOOST_MATH_SQRT1PM1
+#define BOOST_MATH_SQRT1PM1
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/expm1.hpp>
+
+//
+// This algorithm computes sqrt(1+x)-1 for small x:
+//
+
+namespace boost{ namespace math{
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type sqrt1pm1(const T& val, const Policy& pol)
+{
+ typedef typename tools::promote_args<T>::type result_type;
+ BOOST_MATH_STD_USING
+
+ if(fabs(result_type(val)) > 0.75)
+ return sqrt(1 + result_type(val)) - 1;
+ return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type sqrt1pm1(const T& val)
+{
+ return sqrt1pm1(val, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SQRT1PM1
+
+
+
+
+
diff --git a/src/third_party/boost-1.56.0/boost/math/special_functions/trunc.hpp b/src/third_party/boost-1.56.0/boost/math/special_functions/trunc.hpp
new file mode 100644
index 00000000000..3f80c96fee4
--- /dev/null
+++ b/src/third_party/boost-1.56.0/boost/math/special_functions/trunc.hpp
@@ -0,0 +1,111 @@
+// Copyright John Maddock 2007.
+// 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)
+
+#ifndef BOOST_MATH_TRUNC_HPP
+#define BOOST_MATH_TRUNC_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol, const mpl::false_&)
+{
+ BOOST_MATH_STD_USING
+ typedef typename tools::promote_args<T>::type result_type;
+ if(!(boost::math::isfinite)(v))
+ return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", 0, static_cast<result_type>(v), static_cast<result_type>(v), pol);
+ return (v >= 0) ? static_cast<result_type>(floor(v)) : static_cast<result_type>(ceil(v));
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type trunc(const T& v, const Policy&, const mpl::true_&)
+{
+ return v;
+}
+
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol)
+{
+ return detail::trunc(v, pol, mpl::bool_<detail::is_integer_for_rounding<T>::value>());
+}
+template <class T>
+inline typename tools::promote_args<T>::type trunc(const T& v)
+{
+ return trunc(v, policies::policy<>());
+}
+//
+// The following functions will not compile unless T has an
+// implicit convertion to the integer types. For user-defined
+// number types this will likely not be the case. In that case
+// these functions should either be specialized for the UDT in
+// question, or else overloads should be placed in the same
+// namespace as the UDT: these will then be found via argument
+// dependent lookup. See our concept archetypes for examples.
+//
+template <class T, class Policy>
+inline int itrunc(const T& v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ typedef typename tools::promote_args<T>::type result_type;
+ result_type r = boost::math::trunc(v, pol);
+ if((r > (std::numeric_limits<int>::max)()) || (r < (std::numeric_limits<int>::min)()))
+ return static_cast<int>(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0, pol));
+ return static_cast<int>(r);
+}
+template <class T>
+inline int itrunc(const T& v)
+{
+ return itrunc(v, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline long ltrunc(const T& v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ typedef typename tools::promote_args<T>::type result_type;
+ result_type r = boost::math::trunc(v, pol);
+ if((r > (std::numeric_limits<long>::max)()) || (r < (std::numeric_limits<long>::min)()))
+ return static_cast<long>(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0L, pol));
+ return static_cast<long>(r);
+}
+template <class T>
+inline long ltrunc(const T& v)
+{
+ return ltrunc(v, policies::policy<>());
+}
+
+#ifdef BOOST_HAS_LONG_LONG
+
+template <class T, class Policy>
+inline boost::long_long_type lltrunc(const T& v, const Policy& pol)
+{
+ BOOST_MATH_STD_USING
+ typedef typename tools::promote_args<T>::type result_type;
+ result_type r = boost::math::trunc(v, pol);
+ if((r > (std::numeric_limits<boost::long_long_type>::max)()) || (r < (std::numeric_limits<boost::long_long_type>::min)()))
+ return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, static_cast<boost::long_long_type>(0), pol));
+ return static_cast<boost::long_long_type>(r);
+}
+template <class T>
+inline boost::long_long_type lltrunc(const T& v)
+{
+ return lltrunc(v, policies::policy<>());
+}
+
+#endif
+
+}} // namespaces
+
+#endif // BOOST_MATH_TRUNC_HPP