Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/math/special_functions/bessel.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 |
---|---|
13 | 13 |
14 #ifdef _MSC_VER | 14 #ifdef _MSC_VER |
15 # pragma once | 15 # pragma once |
16 #endif | 16 #endif |
17 | 17 |
18 #include <limits> | |
19 #include <boost/math/special_functions/math_fwd.hpp> | |
18 #include <boost/math/special_functions/detail/bessel_jy.hpp> | 20 #include <boost/math/special_functions/detail/bessel_jy.hpp> |
19 #include <boost/math/special_functions/detail/bessel_jn.hpp> | 21 #include <boost/math/special_functions/detail/bessel_jn.hpp> |
20 #include <boost/math/special_functions/detail/bessel_yn.hpp> | 22 #include <boost/math/special_functions/detail/bessel_yn.hpp> |
21 #include <boost/math/special_functions/detail/bessel_jy_zero.hpp> | 23 #include <boost/math/special_functions/detail/bessel_jy_zero.hpp> |
22 #include <boost/math/special_functions/detail/bessel_ik.hpp> | 24 #include <boost/math/special_functions/detail/bessel_ik.hpp> |
190 "boost::math::cyl_bessel_i<%1%>(%1%,%1%)", | 192 "boost::math::cyl_bessel_i<%1%>(%1%,%1%)", |
191 "Got x = %1%, but we need x >= 0", x, pol); | 193 "Got x = %1%, but we need x >= 0", x, pol); |
192 } | 194 } |
193 if(x == 0) | 195 if(x == 0) |
194 { | 196 { |
195 return (v == 0) ? 1 : 0; | 197 return (v == 0) ? static_cast<T>(1) : static_cast<T>(0); |
196 } | 198 } |
197 if(v == 0.5f) | 199 if(v == 0.5f) |
198 { | 200 { |
199 // common special case, note try and avoid overflow in exp(x): | 201 // common special case, note try and avoid overflow in exp(x): |
200 if(x >= tools::log_max_value<T>()) | 202 if(x >= tools::log_max_value<T>()) |
382 | 384 |
383 // Handle negative rank. | 385 // Handle negative rank. |
384 if(m < 0) | 386 if(m < 0) |
385 { | 387 { |
386 // Zeros of Jv(x) with negative rank are not defined and requesting one raises a domain error. | 388 // Zeros of Jv(x) with negative rank are not defined and requesting one raises a domain error. |
387 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", m, pol); | 389 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast<T>(m), pol); |
388 } | 390 } |
389 | 391 |
390 // Get the absolute value of the order. | 392 // Get the absolute value of the order. |
391 const bool order_is_negative = (v < 0); | 393 const bool order_is_negative = (v < 0); |
392 const T vv((!order_is_negative) ? v : T(-v)); | 394 const T vv((!order_is_negative) ? v : T(-v)); |
398 if(m == 0) | 400 if(m == 0) |
399 { | 401 { |
400 if(order_is_zero) | 402 if(order_is_zero) |
401 { | 403 { |
402 // The zero'th zero of J0(x) is not defined and requesting it raises a domain error. | 404 // The zero'th zero of J0(x) is not defined and requesting it raises a domain error. |
403 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of J0, but the rank must be > 0 !", m, pol); | 405 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of J0, but the rank must be > 0 !", static_cast<T>(m), pol); |
404 } | 406 } |
405 | 407 |
406 // The zero'th zero of Jv(x) for v < 0 is not defined | 408 // The zero'th zero of Jv(x) for v < 0 is not defined |
407 // unless the order is a negative integer. | 409 // unless the order is a negative integer. |
408 if(order_is_negative && (!order_is_integer)) | 410 if(order_is_negative && (!order_is_integer)) |
409 { | 411 { |
410 // For non-integer, negative order, requesting the zero'th zero raises a domain error. | 412 // For non-integer, negative order, requesting the zero'th zero raises a domain error. |
411 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of Jv for negative, non-integer order, but the rank must be > 0 !", m, pol); | 413 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of Jv for negative, non-integer order, but the rank must be > 0 !", static_cast<T>(m), pol); |
412 } | 414 } |
413 | 415 |
414 // The zero'th zero does exist and its value is zero. | 416 // The zero'th zero does exist and its value is zero. |
415 return T(0); | 417 return T(0); |
416 } | 418 } |
420 // positive integer for the order. | 422 // positive integer for the order. |
421 const T guess_root = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess<T, Policy>((order_is_integer ? vv : v), m, pol); | 423 const T guess_root = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess<T, Policy>((order_is_integer ? vv : v), m, pol); |
422 | 424 |
423 // Select the maximum allowed iterations from the policy. | 425 // Select the maximum allowed iterations from the policy. |
424 boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>(); | 426 boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>(); |
425 | |
426 // Select the desired number of binary digits of precision. | |
427 // Account for the radix of number representations having non-two radix! | |
428 const int my_digits2 = policies::digits<T, Policy>(); | |
429 | 427 |
430 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); | 428 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); |
431 | 429 |
432 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. | 430 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. |
433 const T jvm = | 431 const T jvm = |
434 boost::math::tools::newton_raphson_iterate( | 432 boost::math::tools::newton_raphson_iterate( |
435 boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv_and_jv_prime<T, Policy>((order_is_integer ? vv : v), order_is_zero, pol), | 433 boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv_and_jv_prime<T, Policy>((order_is_integer ? vv : v), order_is_zero, pol), |
436 guess_root, | 434 guess_root, |
437 T(guess_root - delta_lo), | 435 T(guess_root - delta_lo), |
438 T(guess_root + 0.2F), | 436 T(guess_root + 0.2F), |
439 my_digits2, | 437 policies::digits<T, Policy>(), |
440 number_of_iterations); | 438 number_of_iterations); |
441 | 439 |
442 if(number_of_iterations >= policies::get_max_root_iterations<Policy>()) | 440 if(number_of_iterations >= policies::get_max_root_iterations<Policy>()) |
443 { | 441 { |
444 policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:" | 442 return policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:" |
445 " Current best guess is %1%", jvm, Policy()); | 443 " Current best guess is %1%", jvm, Policy()); |
446 } | 444 } |
447 | 445 |
448 return jvm; | 446 return jvm; |
449 } | 447 } |
462 } | 460 } |
463 | 461 |
464 // Handle negative rank. | 462 // Handle negative rank. |
465 if(m < 0) | 463 if(m < 0) |
466 { | 464 { |
467 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", m, pol); | 465 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast<T>(m), pol); |
468 } | 466 } |
469 | 467 |
470 const T half_epsilon(boost::math::tools::epsilon<T>() / 2U); | 468 const T half_epsilon(boost::math::tools::epsilon<T>() / 2U); |
471 | 469 |
472 // Get the absolute value of the order. | 470 // Get the absolute value of the order. |
488 // The zero'th zero of Yv(x) for v < 0 is not defined | 486 // The zero'th zero of Yv(x) for v < 0 is not defined |
489 // unless the order is a negative integer. | 487 // unless the order is a negative integer. |
490 if((m == 0) && (!order_is_negative_half_integer)) | 488 if((m == 0) && (!order_is_negative_half_integer)) |
491 { | 489 { |
492 // For non-integer, negative order, requesting the zero'th zero raises a domain error. | 490 // For non-integer, negative order, requesting the zero'th zero raises a domain error. |
493 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of Yv for negative, non-half-integer order, but the rank must be > 0 !", m, pol); | 491 return policies::raise_domain_error<T>(function, "Requested the %1%'th zero of Yv for negative, non-half-integer order, but the rank must be > 0 !", static_cast<T>(m), pol); |
494 } | 492 } |
495 | 493 |
496 // For negative half-integers, use the corresponding | 494 // For negative half-integers, use the corresponding |
497 // spherical Bessel function of positive half-integer order. | 495 // spherical Bessel function of positive half-integer order. |
498 if(order_is_negative_half_integer) | 496 if(order_is_negative_half_integer) |
503 // positive integer for the order. | 501 // positive integer for the order. |
504 const T guess_root = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess<T, Policy>(v, m, pol); | 502 const T guess_root = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess<T, Policy>(v, m, pol); |
505 | 503 |
506 // Select the maximum allowed iterations from the policy. | 504 // Select the maximum allowed iterations from the policy. |
507 boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>(); | 505 boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>(); |
508 | |
509 // Select the desired number of binary digits of precision. | |
510 // Account for the radix of number representations having non-two radix! | |
511 const int my_digits2 = policies::digits<T, Policy>(); | |
512 | 506 |
513 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); | 507 const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); |
514 | 508 |
515 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. | 509 // Perform the root-finding using Newton-Raphson iteration from Boost.Math. |
516 const T yvm = | 510 const T yvm = |
517 boost::math::tools::newton_raphson_iterate( | 511 boost::math::tools::newton_raphson_iterate( |
518 boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv_and_yv_prime<T, Policy>(v, pol), | 512 boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv_and_yv_prime<T, Policy>(v, pol), |
519 guess_root, | 513 guess_root, |
520 T(guess_root - delta_lo), | 514 T(guess_root - delta_lo), |
521 T(guess_root + 0.2F), | 515 T(guess_root + 0.2F), |
522 my_digits2, | 516 policies::digits<T, Policy>(), |
523 number_of_iterations); | 517 number_of_iterations); |
524 | 518 |
525 if(number_of_iterations >= policies::get_max_root_iterations<Policy>()) | 519 if(number_of_iterations >= policies::get_max_root_iterations<Policy>()) |
526 { | 520 { |
527 policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:" | 521 return policies::raise_evaluation_error<T>(function, "Unable to locate root in a reasonable time:" |
528 " Current best guess is %1%", yvm, Policy()); | 522 " Current best guess is %1%", yvm, Policy()); |
529 } | 523 } |
530 | 524 |
531 return yvm; | 525 return yvm; |
532 } | 526 } |
672 Policy, | 666 Policy, |
673 policies::promote_float<false>, | 667 policies::promote_float<false>, |
674 policies::promote_double<false>, | 668 policies::promote_double<false>, |
675 policies::discrete_quantile<>, | 669 policies::discrete_quantile<>, |
676 policies::assert_undefined<> >::type forwarding_policy; | 670 policies::assert_undefined<> >::type forwarding_policy; |
677 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<value_type>::is_integer, "Order must be a floating-point type."); | 671 |
672 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized | |
673 || ( true == std::numeric_limits<T>::is_specialized | |
674 && false == std::numeric_limits<T>::is_integer), | |
675 "Order must be a floating-point type."); | |
676 | |
678 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_j_zero_imp<value_type>(v, m, forwarding_policy()), "boost::math::cyl_bessel_j_zero<%1%>(%1%,%1%)"); | 677 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_bessel_j_zero_imp<value_type>(v, m, forwarding_policy()), "boost::math::cyl_bessel_j_zero<%1%>(%1%,%1%)"); |
679 } | 678 } |
680 | 679 |
681 template <class T> | 680 template <class T> |
682 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_bessel_j_zero(T v, int m) | 681 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_bessel_j_zero(T v, int m) |
683 { | 682 { |
684 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type."); | 683 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized |
684 || ( true == std::numeric_limits<T>::is_specialized | |
685 && false == std::numeric_limits<T>::is_integer), | |
686 "Order must be a floating-point type."); | |
687 | |
685 return cyl_bessel_j_zero<T, policies::policy<> >(v, m, policies::policy<>()); | 688 return cyl_bessel_j_zero<T, policies::policy<> >(v, m, policies::policy<>()); |
686 } | 689 } |
687 | 690 |
688 template <class T, class OutputIterator, class Policy> | 691 template <class T, class OutputIterator, class Policy> |
689 inline OutputIterator cyl_bessel_j_zero(T v, | 692 inline OutputIterator cyl_bessel_j_zero(T v, |
690 int start_index, | 693 int start_index, |
691 unsigned number_of_zeros, | 694 unsigned number_of_zeros, |
692 OutputIterator out_it, | 695 OutputIterator out_it, |
693 const Policy& pol) | 696 const Policy& pol) |
694 { | 697 { |
695 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type."); | 698 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized |
696 for(unsigned i = 0; i < number_of_zeros; ++i) | 699 || ( true == std::numeric_limits<T>::is_specialized |
700 && false == std::numeric_limits<T>::is_integer), | |
701 "Order must be a floating-point type."); | |
702 | |
703 for(int i = 0; i < static_cast<int>(number_of_zeros); ++i) | |
697 { | 704 { |
698 *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol); | 705 *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol); |
699 ++out_it; | 706 ++out_it; |
700 } | 707 } |
701 return out_it; | 708 return out_it; |
720 Policy, | 727 Policy, |
721 policies::promote_float<false>, | 728 policies::promote_float<false>, |
722 policies::promote_double<false>, | 729 policies::promote_double<false>, |
723 policies::discrete_quantile<>, | 730 policies::discrete_quantile<>, |
724 policies::assert_undefined<> >::type forwarding_policy; | 731 policies::assert_undefined<> >::type forwarding_policy; |
725 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<value_type>::is_integer, "Order must be a floating-point type."); | 732 |
733 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized | |
734 || ( true == std::numeric_limits<T>::is_specialized | |
735 && false == std::numeric_limits<T>::is_integer), | |
736 "Order must be a floating-point type."); | |
737 | |
726 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_neumann_zero_imp<value_type>(v, m, forwarding_policy()), "boost::math::cyl_neumann_zero<%1%>(%1%,%1%)"); | 738 return policies::checked_narrowing_cast<result_type, Policy>(detail::cyl_neumann_zero_imp<value_type>(v, m, forwarding_policy()), "boost::math::cyl_neumann_zero<%1%>(%1%,%1%)"); |
727 } | 739 } |
728 | 740 |
729 template <class T> | 741 template <class T> |
730 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_neumann_zero(T v, int m) | 742 inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type cyl_neumann_zero(T v, int m) |
731 { | 743 { |
732 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type."); | 744 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized |
745 || ( true == std::numeric_limits<T>::is_specialized | |
746 && false == std::numeric_limits<T>::is_integer), | |
747 "Order must be a floating-point type."); | |
748 | |
733 return cyl_neumann_zero<T, policies::policy<> >(v, m, policies::policy<>()); | 749 return cyl_neumann_zero<T, policies::policy<> >(v, m, policies::policy<>()); |
734 } | 750 } |
735 | 751 |
736 template <class T, class OutputIterator, class Policy> | 752 template <class T, class OutputIterator, class Policy> |
737 inline OutputIterator cyl_neumann_zero(T v, | 753 inline OutputIterator cyl_neumann_zero(T v, |
738 int start_index, | 754 int start_index, |
739 unsigned number_of_zeros, | 755 unsigned number_of_zeros, |
740 OutputIterator out_it, | 756 OutputIterator out_it, |
741 const Policy& pol) | 757 const Policy& pol) |
742 { | 758 { |
743 BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<T>::is_integer, "Order must be a floating-point type."); | 759 BOOST_STATIC_ASSERT_MSG( false == std::numeric_limits<T>::is_specialized |
744 for(unsigned i = 0; i < number_of_zeros; ++i) | 760 || ( true == std::numeric_limits<T>::is_specialized |
761 && false == std::numeric_limits<T>::is_integer), | |
762 "Order must be a floating-point type."); | |
763 | |
764 for(int i = 0; i < static_cast<int>(number_of_zeros); ++i) | |
745 { | 765 { |
746 *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol); | 766 *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol); |
747 ++out_it; | 767 ++out_it; |
748 } | 768 } |
749 return out_it; | 769 return out_it; |