11// (C) Copyright John Maddock 2006.
2+ // (C) Copyright Matt Borland 2024.
23// Use, modification and distribution are subject to the
34// Boost Software License, Version 1.0. (See accompanying file
45// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1314#pragma warning(disable:4702) // Unreachable code: optimization warning
1415#endif
1516
17+ #include < boost/math/tools/config.hpp>
1618#include < type_traits>
1719
1820namespace boost { namespace math {
@@ -23,7 +25,7 @@ namespace detail{
2325// this version is for 80-bit long double's and smaller:
2426//
2527template <class T , class Policy >
26- T erf_inv_imp (const T& p, const T& q, const Policy&, const std::integral_constant<int , 64 >* )
28+ BOOST_MATH_GPU_ENABLED T erf_inv_imp (const T& p, const T& q, const Policy&, const std::integral_constant<int , 64 >& )
2729{
2830 BOOST_MATH_STD_USING // for ADL of std names.
2931
@@ -44,8 +46,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
4446 // Maximum Deviation Found (actual error term at infinite precision) 8.030e-21
4547 //
4648 // LCOV_EXCL_START
47- static const float Y = 0 .0891314744949340820313f ;
48- static const T P[] = {
49+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0 .0891314744949340820313f ;
50+ BOOST_MATH_STATIC const T P[] = {
4951 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.000508781949658280665617 ),
5052 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.00836874819741736770379 ),
5153 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.0334806625409744615033 ),
@@ -55,7 +57,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
5557 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.00822687874676915743155 ),
5658 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.00538772965071242932965 )
5759 };
58- static const T Q[] = {
60+ BOOST_MATH_STATIC const T Q[] = {
5961 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
6062 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.970005043303290640362 ),
6163 BOOST_MATH_BIG_CONSTANT (T, 64 , -1.56574558234175846809 ),
@@ -87,8 +89,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
8789 // Maximum Deviation Found (error term) 4.811e-20
8890 //
8991 // LCOV_EXCL_START
90- static const float Y = 2 .249481201171875f ;
91- static const T P[] = {
92+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 2 .249481201171875f ;
93+ BOOST_MATH_STATIC const T P[] = {
9294 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.202433508355938759655 ),
9395 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.105264680699391713268 ),
9496 BOOST_MATH_BIG_CONSTANT (T, 64 , 8.37050328343119927838 ),
@@ -99,7 +101,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
99101 BOOST_MATH_BIG_CONSTANT (T, 64 , 21.1294655448340526258 ),
100102 BOOST_MATH_BIG_CONSTANT (T, 64 , -3.67192254707729348546 )
101103 };
102- static const T Q[] = {
104+ BOOST_MATH_STATIC const T Q[] = {
103105 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
104106 BOOST_MATH_BIG_CONSTANT (T, 64 , 6.24264124854247537712 ),
105107 BOOST_MATH_BIG_CONSTANT (T, 64 , 3.9713437953343869095 ),
@@ -142,8 +144,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
142144 {
143145 // LCOV_EXCL_START
144146 // Max error found: 1.089051e-20
145- static const float Y = 0 .807220458984375f ;
146- static const T P[] = {
147+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0 .807220458984375f ;
148+ BOOST_MATH_STATIC const T P[] = {
147149 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.131102781679951906451 ),
148150 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.163794047193317060787 ),
149151 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.117030156341995252019 ),
@@ -156,7 +158,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
156158 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.285225331782217055858e-7 ),
157159 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.681149956853776992068e-9 )
158160 };
159- static const T Q[] = {
161+ BOOST_MATH_STATIC const T Q[] = {
160162 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
161163 BOOST_MATH_BIG_CONSTANT (T, 64 , 3.46625407242567245975 ),
162164 BOOST_MATH_BIG_CONSTANT (T, 64 , 5.38168345707006855425 ),
@@ -175,8 +177,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
175177 {
176178 // LCOV_EXCL_START
177179 // Max error found: 8.389174e-21
178- static const float Y = 0 .93995571136474609375f ;
179- static const T P[] = {
180+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0 .93995571136474609375f ;
181+ BOOST_MATH_STATIC const T P[] = {
180182 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.0350353787183177984712 ),
181183 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.00222426529213447927281 ),
182184 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.0185573306514231072324 ),
@@ -187,7 +189,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
187189 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.230404776911882601748e-9 ),
188190 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.266339227425782031962e-11 )
189191 };
190- static const T Q[] = {
192+ BOOST_MATH_STATIC const T Q[] = {
191193 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
192194 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.3653349817554063097 ),
193195 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.762059164553623404043 ),
@@ -205,8 +207,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
205207 {
206208 // LCOV_EXCL_START
207209 // Max error found: 1.481312e-19
208- static const float Y = 0 .98362827301025390625f ;
209- static const T P[] = {
210+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0 .98362827301025390625f ;
211+ BOOST_MATH_STATIC const T P[] = {
210212 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.0167431005076633737133 ),
211213 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.00112951438745580278863 ),
212214 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.00105628862152492910091 ),
@@ -217,7 +219,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
217219 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.281128735628831791805e-13 ),
218220 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.99055709973310326855e-16 )
219221 };
220- static const T Q[] = {
222+ BOOST_MATH_STATIC const T Q[] = {
221223 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
222224 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.591429344886417493481 ),
223225 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.138151865749083321638 ),
@@ -235,8 +237,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
235237 {
236238 // LCOV_EXCL_START
237239 // Max error found: 5.697761e-20
238- static const float Y = 0 .99714565277099609375f ;
239- static const T P[] = {
240+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0 .99714565277099609375f ;
241+ BOOST_MATH_STATIC const T P[] = {
240242 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.0024978212791898131227 ),
241243 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.779190719229053954292e-5 ),
242244 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.254723037413027451751e-4 ),
@@ -246,7 +248,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
246248 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.145596286718675035587e-11 ),
247249 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.116765012397184275695e-17 )
248250 };
249- static const T Q[] = {
251+ BOOST_MATH_STATIC const T Q[] = {
250252 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
251253 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.207123112214422517181 ),
252254 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.0169410838120975906478 ),
@@ -264,8 +266,8 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
264266 {
265267 // LCOV_EXCL_START
266268 // Max error found: 1.279746e-20
267- static const float Y = 0 .99941349029541015625f ;
268- static const T P[] = {
269+ BOOST_MATH_STATIC_LOCAL_VARIABLE const float Y = 0 .99941349029541015625f ;
270+ BOOST_MATH_STATIC const T P[] = {
269271 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.000539042911019078575891 ),
270272 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.28398759004727721098e-6 ),
271273 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.899465114892291446442e-6 ),
@@ -275,7 +277,7 @@ T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constan
275277 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.135880130108924861008e-14 ),
276278 BOOST_MATH_BIG_CONSTANT (T, 64 , -0.348890393399948882918e-21 )
277279 };
278- static const T Q[] = {
280+ BOOST_MATH_STATIC const T Q[] = {
279281 BOOST_MATH_BIG_CONSTANT (T, 64 , 1.0 ),
280282 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.0845746234001899436914 ),
281283 BOOST_MATH_BIG_CONSTANT (T, 64 , 0.00282092984726264681981 ),
@@ -310,12 +312,13 @@ struct erf_roots
310312};
311313
312314template <class T , class Policy >
313- T erf_inv_imp (const T& p, const T& q, const Policy& pol, const std::integral_constant<int , 0 >* )
315+ T erf_inv_imp (const T& p, const T& q, const Policy& pol, const std::integral_constant<int , 0 >& )
314316{
315317 //
316318 // Generic version, get a guess that's accurate to 64-bits (10^-19)
317319 //
318- T guess = erf_inv_imp (p, q, pol, static_cast <std::integral_constant<int , 64 > const *>(nullptr ));
320+ using tag_type = std::integral_constant<int , 64 >;
321+ T guess = erf_inv_imp (p, q, pol, tag_type ());
319322 T result;
320323 //
321324 // If T has more bit's than 64 in it's mantissa then we need to iterate,
@@ -344,14 +347,14 @@ T erf_inv_imp(const T& p, const T& q, const Policy& pol, const std::integral_con
344347} // namespace detail
345348
346349template <class T , class Policy >
347- typename tools::promote_args<T>::type erfc_inv (T z, const Policy& pol)
350+ BOOST_MATH_GPU_ENABLED typename tools::promote_args<T>::type erfc_inv (T z, const Policy& pol)
348351{
349352 typedef typename tools::promote_args<T>::type result_type;
350353
351354 //
352355 // Begin by testing for domain errors, and other special cases:
353356 //
354- static const char * function = " boost::math::erfc_inv<%1%>(%1%, %1%)" ;
357+ constexpr auto function = " boost::math::erfc_inv<%1%>(%1%, %1%)" ;
355358 if ((z < 0 ) || (z > 2 ))
356359 return policies::raise_domain_error<result_type>(function, " Argument outside range [0,2] in inverse erfc function (got p=%1%)." , z, pol);
357360 if (z == 0 )
@@ -401,18 +404,18 @@ typename tools::promote_args<T>::type erfc_inv(T z, const Policy& pol)
401404 // And get the result, negating where required:
402405 //
403406 return s * policies::checked_narrowing_cast<result_type, forwarding_policy>(
404- detail::erf_inv_imp (static_cast <eval_type>(p), static_cast <eval_type>(q), forwarding_policy (), static_cast < tag_type const *>( nullptr )), function);
407+ detail::erf_inv_imp (static_cast <eval_type>(p), static_cast <eval_type>(q), forwarding_policy (), tag_type ( )), function);
405408}
406409
407410template <class T , class Policy >
408- typename tools::promote_args<T>::type erf_inv (T z, const Policy& pol)
411+ BOOST_MATH_GPU_ENABLED typename tools::promote_args<T>::type erf_inv (T z, const Policy& pol)
409412{
410413 typedef typename tools::promote_args<T>::type result_type;
411414
412415 //
413416 // Begin by testing for domain errors, and other special cases:
414417 //
415- static const char * function = " boost::math::erf_inv<%1%>(%1%, %1%)" ;
418+ constexpr auto function = " boost::math::erf_inv<%1%>(%1%, %1%)" ;
416419 if ((z < -1 ) || (z > 1 ))
417420 return policies::raise_domain_error<result_type>(function, " Argument outside range [-1, 1] in inverse erf function (got p=%1%)." , z, pol);
418421 if (z == 1 )
@@ -469,17 +472,17 @@ typename tools::promote_args<T>::type erf_inv(T z, const Policy& pol)
469472 // And get the result, negating where required:
470473 //
471474 return s * policies::checked_narrowing_cast<result_type, forwarding_policy>(
472- detail::erf_inv_imp (static_cast <eval_type>(p), static_cast <eval_type>(q), forwarding_policy (), static_cast < tag_type const *>( nullptr )), function);
475+ detail::erf_inv_imp (static_cast <eval_type>(p), static_cast <eval_type>(q), forwarding_policy (), tag_type ( )), function);
473476}
474477
475478template <class T >
476- inline typename tools::promote_args<T>::type erfc_inv (T z)
479+ BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type erfc_inv (T z)
477480{
478481 return erfc_inv (z, policies::policy<>());
479482}
480483
481484template <class T >
482- inline typename tools::promote_args<T>::type erf_inv (T z)
485+ BOOST_MATH_GPU_ENABLED inline typename tools::promote_args<T>::type erf_inv (T z)
483486{
484487 return erf_inv (z, policies::policy<>());
485488}
0 commit comments