X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Fmath%2Fspecial_functions%2Fdetail%2Ferf_inv.hpp;h=ab926ad8cb1a4952c275b8871c170f2442286cb2;hp=33f84651eeb2f1885b1030546f524b006775a59f;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/math/special_functions/detail/erf_inv.hpp b/boost/math/special_functions/detail/erf_inv.hpp index 33f8465..ab926ad 100644 --- a/boost/math/special_functions/detail/erf_inv.hpp +++ b/boost/math/special_functions/detail/erf_inv.hpp @@ -40,26 +40,26 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // static const float Y = 0.0891314744949340820313f; static const T P[] = { - -0.000508781949658280665617L, - -0.00836874819741736770379L, - 0.0334806625409744615033L, - -0.0126926147662974029034L, - -0.0365637971411762664006L, - 0.0219878681111168899165L, - 0.00822687874676915743155L, - -0.00538772965071242932965L + 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[] = { - 1, - -0.970005043303290640362L, - -1.56574558234175846809L, - 1.56221558398423026363L, - 0.662328840472002992063L, - -0.71228902341542847553L, - -0.0527396382340099713954L, - 0.0795283687341571680018L, - -0.00233393759374190016776L, - 0.000886216390456424707504L + 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); @@ -81,26 +81,26 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // static const float Y = 2.249481201171875f; static const T P[] = { - -0.202433508355938759655L, - 0.105264680699391713268L, - 8.37050328343119927838L, - 17.6447298408374015486L, - -18.8510648058714251895L, - -44.6382324441786960818L, - 17.445385985570866523L, - 21.1294655448340526258L, - -3.67192254707729348546L + 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[] = { - 1L, - 6.24264124854247537712L, - 3.9713437953343869095L, - -28.6608180499800029974L, - -20.1432634680485188801L, - 48.5609213108739935468L, - 10.8268667355460159008L, - -22.6436933413139721736L, - 1.72114765761200282724L + BOOST_MATH_BIG_CONSTANT(T, 64, 1), + 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; @@ -134,27 +134,27 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // Max error found: 1.089051e-20 static const float Y = 0.807220458984375f; static const T P[] = { - -0.131102781679951906451L, - -0.163794047193317060787L, - 0.117030156341995252019L, - 0.387079738972604337464L, - 0.337785538912035898924L, - 0.142869534408157156766L, - 0.0290157910005329060432L, - 0.00214558995388805277169L, - -0.679465575181126350155e-6L, - 0.285225331782217055858e-7L, - -0.681149956853776992068e-9L + 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[] = { - 1, - 3.46625407242567245975L, - 5.38168345707006855425L, - 4.77846592945843778382L, - 2.59301921623620271374L, - 0.848854343457902036425L, - 0.152264338295331783612L, - 0.01105924229346489121L + 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); @@ -165,24 +165,24 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // Max error found: 8.389174e-21 static const float Y = 0.93995571136474609375f; static const T P[] = { - -0.0350353787183177984712L, - -0.00222426529213447927281L, - 0.0185573306514231072324L, - 0.00950804701325919603619L, - 0.00187123492819559223345L, - 0.000157544617424960554631L, - 0.460469890584317994083e-5L, - -0.230404776911882601748e-9L, - 0.266339227425782031962e-11L + 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[] = { - 1L, - 1.3653349817554063097L, - 0.762059164553623404043L, - 0.220091105764131249824L, - 0.0341589143670947727934L, - 0.00263861676657015992959L, - 0.764675292302794483503e-4L + BOOST_MATH_BIG_CONSTANT(T, 64, 1), + 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); @@ -193,24 +193,24 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // Max error found: 1.481312e-19 static const float Y = 0.98362827301025390625f; static const T P[] = { - -0.0167431005076633737133L, - -0.00112951438745580278863L, - 0.00105628862152492910091L, - 0.000209386317487588078668L, - 0.149624783758342370182e-4L, - 0.449696789927706453732e-6L, - 0.462596163522878599135e-8L, - -0.281128735628831791805e-13L, - 0.99055709973310326855e-16L + 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[] = { - 1L, - 0.591429344886417493481L, - 0.138151865749083321638L, - 0.0160746087093676504695L, - 0.000964011807005165528527L, - 0.275335474764726041141e-4L, - 0.282243172016108031869e-6L + BOOST_MATH_BIG_CONSTANT(T, 64, 1), + 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); @@ -221,23 +221,23 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // Max error found: 5.697761e-20 static const float Y = 0.99714565277099609375f; static const T P[] = { - -0.0024978212791898131227L, - -0.779190719229053954292e-5L, - 0.254723037413027451751e-4L, - 0.162397777342510920873e-5L, - 0.396341011304801168516e-7L, - 0.411632831190944208473e-9L, - 0.145596286718675035587e-11L, - -0.116765012397184275695e-17L + 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[] = { - 1L, - 0.207123112214422517181L, - 0.0169410838120975906478L, - 0.000690538265622684595676L, - 0.145007359818232637924e-4L, - 0.144437756628144157666e-6L, - 0.509761276599778486139e-9L + BOOST_MATH_BIG_CONSTANT(T, 64, 1), + 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); @@ -248,23 +248,23 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* // Max error found: 1.279746e-20 static const float Y = 0.99941349029541015625f; static const T P[] = { - -0.000539042911019078575891L, - -0.28398759004727721098e-6L, - 0.899465114892291446442e-6L, - 0.229345859265920864296e-7L, - 0.225561444863500149219e-9L, - 0.947846627503022684216e-12L, - 0.135880130108924861008e-14L, - -0.348890393399948882918e-21L + 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[] = { - 1L, - 0.0845746234001899436914L, - 0.00282092984726264681981L, - 0.468292921940894236786e-4L, - 0.399968812193862100054e-6L, - 0.161809290887904476097e-8L, - 0.231558608310259605225e-11L + BOOST_MATH_BIG_CONSTANT(T, 64, 1), + 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); @@ -277,12 +277,12 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::mpl::int_<64>* template struct erf_roots { - std::tr1::tuple operator()(const T& guess) + boost::math::tuple operator()(const T& guess) { BOOST_MATH_STD_USING T derivative = sign * (2 / sqrt(constants::pi())) * exp(-(guess * guess)); T derivative2 = -2 * guess * derivative; - return std::tr1::make_tuple(((sign > 0) ? boost::math::erf(guess, Policy()) : boost::math::erfc(guess, Policy())) - target, derivative, derivative2); + return boost::math::make_tuple(((sign > 0) ? static_cast(boost::math::erf(guess, Policy()) - target) : static_cast(boost::math::erfc(guess, Policy())) - target), derivative, derivative2); } erf_roots(T z, int s) : target(z), sign(s) {} private: @@ -313,7 +313,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy& pol, const boost::mpl::int_< { result = tools::halley_iterate(detail::erf_roots::type, Policy>(q, -1), guess, static_cast(0), tools::max_value(), (policies::digits() * 2) / 3, max_iter); } - policies::check_root_iterations("boost::math::erf_inv<%1%>", max_iter, pol); + policies::check_root_iterations("boost::math::erf_inv<%1%>", max_iter, pol); } else { @@ -322,12 +322,57 @@ T erf_inv_imp(const T& p, const T& q, const Policy& pol, const boost::mpl::int_< return result; } +template +struct erf_inv_initializer +{ + struct init + { + init() + { + do_init(); + } + static void do_init() + { + boost::math::erf_inv(static_cast(0.25), Policy()); + boost::math::erf_inv(static_cast(0.55), Policy()); + boost::math::erf_inv(static_cast(0.95), Policy()); + boost::math::erfc_inv(static_cast(1e-15), Policy()); + if(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130)) != 0) + boost::math::erfc_inv(static_cast(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(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800)) != 0) + boost::math::erfc_inv(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800)), Policy()); + if(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900)) != 0) + boost::math::erfc_inv(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900)), Policy()); +#else + if(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800)) != 0) + boost::math::erfc_inv(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800)), Policy()); + if(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900)) != 0) + boost::math::erfc_inv(static_cast(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 +const typename erf_inv_initializer::init erf_inv_initializer::initializer; + } // namespace detail template typename tools::promote_args::type erfc_inv(T z, const Policy& pol) { typedef typename tools::promote_args::type result_type; + // // Begin by testing for domain errors, and other special cases: // @@ -378,6 +423,8 @@ typename tools::promote_args::type erfc_inv(T z, const Policy& pol) policies::discrete_quantile<>, policies::assert_undefined<> >::type forwarding_policy; + detail::erf_inv_initializer::force_instantiate(); + // // And get the result, negating where required: // @@ -389,6 +436,7 @@ template typename tools::promote_args::type erf_inv(T z, const Policy& pol) { typedef typename tools::promote_args::type result_type; + // // Begin by testing for domain errors, and other special cases: // @@ -445,6 +493,8 @@ typename tools::promote_args::type erf_inv(T z, const Policy& pol) // precision internally if it's appropriate: // typedef typename policies::evaluation::type eval_type; + + detail::erf_inv_initializer::force_instantiate(); // // And get the result, negating where required: //