Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/math/special_functions/airy.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
5 // or copy at http://www.boost.org/LICENSE_1_0.txt) | 5 // or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | 6 |
7 #ifndef BOOST_MATH_AIRY_HPP | 7 #ifndef BOOST_MATH_AIRY_HPP |
8 #define BOOST_MATH_AIRY_HPP | 8 #define BOOST_MATH_AIRY_HPP |
9 | 9 |
10 #include <limits> | |
11 #include <boost/math/special_functions/math_fwd.hpp> | |
10 #include <boost/math/special_functions/bessel.hpp> | 12 #include <boost/math/special_functions/bessel.hpp> |
11 #include <boost/math/special_functions/cbrt.hpp> | 13 #include <boost/math/special_functions/cbrt.hpp> |
12 #include <boost/math/special_functions/detail/airy_ai_bi_zero.hpp> | 14 #include <boost/math/special_functions/detail/airy_ai_bi_zero.hpp> |
13 #include <boost/math/tools/roots.hpp> | 15 #include <boost/math/tools/roots.hpp> |
14 | 16 |
152 return aip; | 154 return aip; |
153 } | 155 } |
154 } | 156 } |
155 | 157 |
156 template <class T, class Policy> | 158 template <class T, class Policy> |
157 T airy_ai_zero_imp(unsigned m, const Policy& pol) | 159 T airy_ai_zero_imp(int m, const Policy& pol) |
158 { | 160 { |
159 BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. | 161 BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. |
162 | |
163 // Handle cases when a negative zero (negative rank) is requested. | |
164 if(m < 0) | |
165 { | |
166 return policies::raise_domain_error<T>("boost::math::airy_ai_zero<%1%>(%1%, int)", | |
167 "Requested the %1%'th zero, but the rank must be 1 or more !", static_cast<T>(m), pol); | |
168 } | |
160 | 169 |
161 // Handle case when the zero'th zero is requested. | 170 // Handle case when the zero'th zero is requested. |
162 if(m == 0U) | 171 if(m == 0U) |
163 { | 172 { |
164 return policies::raise_domain_error<T>("boost::math::airy_ai_zero<%1%>(%1%,%1%)", | 173 return policies::raise_domain_error<T>("boost::math::airy_ai_zero<%1%>(%1%,%1%)", |
166 } | 175 } |
167 | 176 |
168 // Set up the initial guess for the upcoming root-finding. | 177 // Set up the initial guess for the upcoming root-finding. |
169 const T guess_root = boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess<T>(m); | 178 const T guess_root = boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess<T>(m); |
170 | 179 |
171 // Select the maximum allowed iterations, being at least 24. | 180 // Select the maximum allowed iterations based on the number |
172 boost::uintmax_t number_of_iterations = (std::max)(24, int(std::numeric_limits<T>::digits10)); | 181 // of decimal digits in the numeric type T, being at least 12. |
173 | 182 const int my_digits10 = static_cast<int>(static_cast<float>(policies::digits<T, Policy>() * 0.301F)); |
174 // Select the desired number of binary digits of precision. | 183 |
175 // Account for the radix of number representations having non-two radix! | 184 const boost::uintmax_t iterations_allowed = static_cast<boost::uintmax_t>((std::max)(12, my_digits10 * 2)); |
176 const int my_digits2 = int(float(std::numeric_limits<T>::digits) | 185 |
177 * ( log(float(std::numeric_limits<T>::radix)) | 186 boost::uintmax_t iterations_used = iterations_allowed; |
178 / log(2.0F))); | |
179 | 187 |
180 // Use a dynamic tolerance because the roots get closer the higher m gets. | 188 // Use a dynamic tolerance because the roots get closer the higher m gets. |
181 T tolerance; | 189 T tolerance; |
182 | 190 |
183 if (m <= 10U) { tolerance = T(0.3F); } | 191 if (m <= 10) { tolerance = T(0.3F); } |
184 else if(m <= 100U) { tolerance = T(0.1F); } | 192 else if(m <= 100) { tolerance = T(0.1F); } |
185 else if(m <= 1000U) { tolerance = T(0.05F); } | 193 else if(m <= 1000) { tolerance = T(0.05F); } |
186 else { tolerance = T(1) / sqrt(T(m)); } | 194 else { tolerance = T(1) / sqrt(T(m)); } |
187 | 195 |
188 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. | 196 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. |
189 const T am = | 197 const T am = |
190 boost::math::tools::newton_raphson_iterate( | 198 boost::math::tools::newton_raphson_iterate( |
191 boost::math::detail::airy_zero::airy_ai_zero_detail::function_object_ai_and_ai_prime<T, Policy>(pol), | 199 boost::math::detail::airy_zero::airy_ai_zero_detail::function_object_ai_and_ai_prime<T, Policy>(pol), |
192 guess_root, | 200 guess_root, |
193 T(guess_root - tolerance), | 201 T(guess_root - tolerance), |
194 T(guess_root + tolerance), | 202 T(guess_root + tolerance), |
195 my_digits2, | 203 policies::digits<T, Policy>(), |
196 number_of_iterations); | 204 iterations_used); |
197 | 205 |
198 static_cast<void>(number_of_iterations); | 206 static_cast<void>(iterations_used); |
199 | 207 |
200 return am; | 208 return am; |
201 } | 209 } |
202 | 210 |
203 template <class T, class Policy> | 211 template <class T, class Policy> |
204 T airy_bi_zero_imp(unsigned m, const Policy& pol) | 212 T airy_bi_zero_imp(int m, const Policy& pol) |
205 { | 213 { |
206 BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. | 214 BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. |
215 | |
216 // Handle cases when a negative zero (negative rank) is requested. | |
217 if(m < 0) | |
218 { | |
219 return policies::raise_domain_error<T>("boost::math::airy_bi_zero<%1%>(%1%, int)", | |
220 "Requested the %1%'th zero, but the rank must 1 or more !", static_cast<T>(m), pol); | |
221 } | |
207 | 222 |
208 // Handle case when the zero'th zero is requested. | 223 // Handle case when the zero'th zero is requested. |
209 if(m == 0U) | 224 if(m == 0U) |
210 { | 225 { |
211 return policies::raise_domain_error<T>("boost::math::airy_bi_zero<%1%>(%1%,%1%)", | 226 return policies::raise_domain_error<T>("boost::math::airy_bi_zero<%1%>(%1%,%1%)", |
212 "The requested rank of the zero is %1%, but must be 1 or more !", static_cast<T>(m), pol); | 227 "The requested rank of the zero is %1%, but must be 1 or more !", static_cast<T>(m), pol); |
213 } | 228 } |
214 // Set up the initial guess for the upcoming root-finding. | 229 // Set up the initial guess for the upcoming root-finding. |
215 const T guess_root = boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess<T>(m); | 230 const T guess_root = boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess<T>(m); |
216 | 231 |
217 // Select the maximum allowed iterations, being at least 24. | 232 // Select the maximum allowed iterations based on the number |
218 boost::uintmax_t number_of_iterations = (std::max)(24, int(std::numeric_limits<T>::digits10)); | 233 // of decimal digits in the numeric type T, being at least 12. |
219 | 234 const int my_digits10 = static_cast<int>(static_cast<float>(policies::digits<T, Policy>() * 0.301F)); |
220 // Select the desired number of binary digits of precision. | 235 |
221 // Account for the radix of number representations having non-two radix! | 236 const boost::uintmax_t iterations_allowed = static_cast<boost::uintmax_t>((std::max)(12, my_digits10 * 2)); |
222 const int my_digits2 = int(float(std::numeric_limits<T>::digits) | 237 |
223 * ( log(float(std::numeric_limits<T>::radix)) | 238 boost::uintmax_t iterations_used = iterations_allowed; |
224 / log(2.0F))); | |
225 | 239 |
226 // Use a dynamic tolerance because the roots get closer the higher m gets. | 240 // Use a dynamic tolerance because the roots get closer the higher m gets. |
227 T tolerance; | 241 T tolerance; |
228 | 242 |
229 if (m <= 10U) { tolerance = T(0.3F); } | 243 if (m <= 10) { tolerance = T(0.3F); } |
230 else if(m <= 100U) { tolerance = T(0.1F); } | 244 else if(m <= 100) { tolerance = T(0.1F); } |
231 else if(m <= 1000U) { tolerance = T(0.05F); } | 245 else if(m <= 1000) { tolerance = T(0.05F); } |
232 else { tolerance = T(1) / sqrt(T(m)); } | 246 else { tolerance = T(1) / sqrt(T(m)); } |
233 | 247 |
234 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. | 248 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. |
235 const T bm = | 249 const T bm = |
236 boost::math::tools::newton_raphson_iterate( | 250 boost::math::tools::newton_raphson_iterate( |
237 boost::math::detail::airy_zero::airy_bi_zero_detail::function_object_bi_and_bi_prime<T, Policy>(pol), | 251 boost::math::detail::airy_zero::airy_bi_zero_detail::function_object_bi_and_bi_prime<T, Policy>(pol), |
238 guess_root, | 252 guess_root, |
239 T(guess_root - tolerance), | 253 T(guess_root - tolerance), |
240 T(guess_root + tolerance), | 254 T(guess_root + tolerance), |
241 my_digits2, | 255 policies::digits<T, Policy>(), |
242 number_of_iterations); | 256 iterations_used); |
243 | 257 |
244 static_cast<void>(number_of_iterations); | 258 static_cast<void>(iterations_used); |
245 | 259 |
246 return bm; | 260 return bm; |
247 } | 261 } |
248 | 262 |
249 } // namespace detail | 263 } // namespace detail |
335 { | 349 { |
336 return airy_bi_prime(x, policies::policy<>()); | 350 return airy_bi_prime(x, policies::policy<>()); |
337 } | 351 } |
338 | 352 |
339 template <class T, class Policy> | 353 template <class T, class Policy> |
340 inline T airy_ai_zero(unsigned m, const Policy& /*pol*/) | 354 inline T airy_ai_zero(int m, const Policy& /*pol*/) |
341 { | 355 { |
342 BOOST_FPU_EXCEPTION_GUARD | 356 BOOST_FPU_EXCEPTION_GUARD |
343 typedef typename policies::evaluation<T, Policy>::type value_type; | 357 typedef typename policies::evaluation<T, Policy>::type value_type; |
344 typedef typename policies::normalise< | 358 typedef typename policies::normalise< |
345 Policy, | 359 Policy, |
346 policies::promote_float<false>, | 360 policies::promote_float<false>, |
347 policies::promote_double<false>, | 361 policies::promote_double<false>, |
348 policies::discrete_quantile<>, | 362 policies::discrete_quantile<>, |
349 policies::assert_undefined<> >::type forwarding_policy; | 363 policies::assert_undefined<> >::type forwarding_policy; |
350 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Airy return type must be a floating-point type."); | 364 |
365 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized | |
366 || ( true == std::numeric_limits<T>::is_specialized | |
367 && false == std::numeric_limits<T>::is_integer), | |
368 "Airy value type must be a floating-point type."); | |
369 | |
351 return policies::checked_narrowing_cast<T, Policy>(detail::airy_ai_zero_imp<value_type>(m, forwarding_policy()), "boost::math::airy_ai_zero<%1%>(unsigned)"); | 370 return policies::checked_narrowing_cast<T, Policy>(detail::airy_ai_zero_imp<value_type>(m, forwarding_policy()), "boost::math::airy_ai_zero<%1%>(unsigned)"); |
352 } | 371 } |
353 | 372 |
354 template <class T> | 373 template <class T> |
355 inline T airy_ai_zero(unsigned m) | 374 inline T airy_ai_zero(int m) |
356 { | 375 { |
357 return airy_ai_zero<T>(m, policies::policy<>()); | 376 return airy_ai_zero<T>(m, policies::policy<>()); |
358 } | 377 } |
359 | 378 |
360 template <class T, class OutputIterator, class Policy> | 379 template <class T, class OutputIterator, class Policy> |
361 inline OutputIterator airy_ai_zero( | 380 inline OutputIterator airy_ai_zero( |
362 unsigned start_index, | 381 int start_index, |
363 unsigned number_of_zeros, | 382 unsigned number_of_zeros, |
364 OutputIterator out_it, | 383 OutputIterator out_it, |
365 const Policy& pol) | 384 const Policy& pol) |
366 { | 385 { |
367 typedef T result_type; | 386 typedef T result_type; |
368 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<result_type>::is_integer, "Airy return type must be a floating-point type."); | 387 |
388 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized | |
389 || ( true == std::numeric_limits<T>::is_specialized | |
390 && false == std::numeric_limits<T>::is_integer), | |
391 "Airy value type must be a floating-point type."); | |
369 | 392 |
370 for(unsigned i = 0; i < number_of_zeros; ++i) | 393 for(unsigned i = 0; i < number_of_zeros; ++i) |
371 { | 394 { |
372 *out_it = boost::math::airy_ai_zero<result_type>(start_index + i, pol); | 395 *out_it = boost::math::airy_ai_zero<result_type>(start_index + i, pol); |
373 ++out_it; | 396 ++out_it; |
375 return out_it; | 398 return out_it; |
376 } | 399 } |
377 | 400 |
378 template <class T, class OutputIterator> | 401 template <class T, class OutputIterator> |
379 inline OutputIterator airy_ai_zero( | 402 inline OutputIterator airy_ai_zero( |
380 unsigned start_index, | 403 int start_index, |
381 unsigned number_of_zeros, | 404 unsigned number_of_zeros, |
382 OutputIterator out_it) | 405 OutputIterator out_it) |
383 { | 406 { |
384 return airy_ai_zero<T>(start_index, number_of_zeros, out_it, policies::policy<>()); | 407 return airy_ai_zero<T>(start_index, number_of_zeros, out_it, policies::policy<>()); |
385 } | 408 } |
386 | 409 |
387 template <class T, class Policy> | 410 template <class T, class Policy> |
388 inline T airy_bi_zero(unsigned m, const Policy& /*pol*/) | 411 inline T airy_bi_zero(int m, const Policy& /*pol*/) |
389 { | 412 { |
390 BOOST_FPU_EXCEPTION_GUARD | 413 BOOST_FPU_EXCEPTION_GUARD |
391 typedef typename policies::evaluation<T, Policy>::type value_type; | 414 typedef typename policies::evaluation<T, Policy>::type value_type; |
392 typedef typename policies::normalise< | 415 typedef typename policies::normalise< |
393 Policy, | 416 Policy, |
394 policies::promote_float<false>, | 417 policies::promote_float<false>, |
395 policies::promote_double<false>, | 418 policies::promote_double<false>, |
396 policies::discrete_quantile<>, | 419 policies::discrete_quantile<>, |
397 policies::assert_undefined<> >::type forwarding_policy; | 420 policies::assert_undefined<> >::type forwarding_policy; |
398 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Airy return type must be a floating-point type."); | 421 |
422 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized | |
423 || ( true == std::numeric_limits<T>::is_specialized | |
424 && false == std::numeric_limits<T>::is_integer), | |
425 "Airy value type must be a floating-point type."); | |
426 | |
399 return policies::checked_narrowing_cast<T, Policy>(detail::airy_bi_zero_imp<value_type>(m, forwarding_policy()), "boost::math::airy_bi_zero<%1%>(unsigned)"); | 427 return policies::checked_narrowing_cast<T, Policy>(detail::airy_bi_zero_imp<value_type>(m, forwarding_policy()), "boost::math::airy_bi_zero<%1%>(unsigned)"); |
400 } | 428 } |
401 | 429 |
402 template <typename T> | 430 template <typename T> |
403 inline T airy_bi_zero(unsigned m) | 431 inline T airy_bi_zero(int m) |
404 { | 432 { |
405 return airy_bi_zero<T>(m, policies::policy<>()); | 433 return airy_bi_zero<T>(m, policies::policy<>()); |
406 } | 434 } |
407 | 435 |
408 template <class T, class OutputIterator, class Policy> | 436 template <class T, class OutputIterator, class Policy> |
409 inline OutputIterator airy_bi_zero( | 437 inline OutputIterator airy_bi_zero( |
410 unsigned start_index, | 438 int start_index, |
411 unsigned number_of_zeros, | 439 unsigned number_of_zeros, |
412 OutputIterator out_it, | 440 OutputIterator out_it, |
413 const Policy& pol) | 441 const Policy& pol) |
414 { | 442 { |
415 typedef T result_type; | 443 typedef T result_type; |
416 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<result_type>::is_integer, "Airy return type must be a floating-point type."); | 444 |
445 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized | |
446 || ( true == std::numeric_limits<T>::is_specialized | |
447 && false == std::numeric_limits<T>::is_integer), | |
448 "Airy value type must be a floating-point type."); | |
417 | 449 |
418 for(unsigned i = 0; i < number_of_zeros; ++i) | 450 for(unsigned i = 0; i < number_of_zeros; ++i) |
419 { | 451 { |
420 *out_it = boost::math::airy_bi_zero<result_type>(start_index + i, pol); | 452 *out_it = boost::math::airy_bi_zero<result_type>(start_index + i, pol); |
421 ++out_it; | 453 ++out_it; |
423 return out_it; | 455 return out_it; |
424 } | 456 } |
425 | 457 |
426 template <class T, class OutputIterator> | 458 template <class T, class OutputIterator> |
427 inline OutputIterator airy_bi_zero( | 459 inline OutputIterator airy_bi_zero( |
428 unsigned start_index, | 460 int start_index, |
429 unsigned number_of_zeros, | 461 unsigned number_of_zeros, |
430 OutputIterator out_it) | 462 OutputIterator out_it) |
431 { | 463 { |
432 return airy_bi_zero<T>(start_index, number_of_zeros, out_it, policies::policy<>()); | 464 return airy_bi_zero<T>(start_index, number_of_zeros, out_it, policies::policy<>()); |
433 } | 465 } |