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;