test_bessel_i_prime.hpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (c) 2013 Anton Bikineev
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
  6. #include <boost/math/concepts/real_concept.hpp>
  7. #define BOOST_TEST_MAIN
  8. #include <boost/test/unit_test.hpp>
  9. #include <boost/test/tools/floating_point_comparison.hpp>
  10. #include <boost/math/special_functions/math_fwd.hpp>
  11. #include <boost/type_traits/is_floating_point.hpp>
  12. #include <boost/array.hpp>
  13. #include "functor.hpp"
  14. #include "handle_test_result.hpp"
  15. #include "table_type.hpp"
  16. #ifndef SC_
  17. # define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L))
  18. #endif
  19. template <class T>
  20. T cyl_bessel_i_prime_int_wrapper(T v, T x)
  21. {
  22. #ifdef BESSEL_IPN_FUNCTION_TO_TEST
  23. return static_cast<T>(
  24. BESSEL_IPN_FUNCTION_TO_TEST(
  25. boost::math::itrunc(v), x));
  26. #else
  27. return static_cast<T>(
  28. boost::math::cyl_bessel_i_prime(
  29. boost::math::itrunc(v), x));
  30. #endif
  31. }
  32. template <class Real, class T>
  33. void do_test_cyl_bessel_i_prime(const T& data, const char* type_name, const char* test_name)
  34. {
  35. #if !(defined(ERROR_REPORTING_MODE) && !defined(BESSEL_IP_FUNCTION_TO_TEST))
  36. typedef Real value_type;
  37. typedef value_type (*pg)(value_type, value_type);
  38. #ifdef BESSEL_IP_FUNCTION_TO_TEST
  39. pg funcp = BESSEL_IP_FUNCTION_TO_TEST;
  40. #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  41. pg funcp = boost::math::cyl_bessel_i_prime<value_type, value_type>;
  42. #else
  43. pg funcp = boost::math::cyl_bessel_i_prime;
  44. #endif
  45. boost::math::tools::test_result<value_type> result;
  46. std::cout << "Testing " << test_name << " with type " << type_name
  47. << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  48. //
  49. // test cyl_bessel_i_prime against data:
  50. //
  51. result = boost::math::tools::test_hetero<Real>(
  52. data,
  53. bind_func<Real>(funcp, 0, 1),
  54. extract_result<Real>(2));
  55. handle_test_result(result, data[result.worst()], result.worst(), type_name, "cyl_bessel_i_prime", test_name);
  56. std::cout << std::endl;
  57. #endif
  58. }
  59. template <class Real, class T>
  60. void do_test_cyl_bessel_i_prime_int(const T& data, const char* type_name, const char* test_name)
  61. {
  62. #if !(defined(ERROR_REPORTING_MODE) && !defined(BESSEL_IPN_FUNCTION_TO_TEST))
  63. typedef Real value_type;
  64. typedef value_type (*pg)(value_type, value_type);
  65. #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  66. pg funcp = cyl_bessel_i_prime_int_wrapper<value_type>;
  67. #else
  68. pg funcp = cyl_bessel_i_prime_int_wrapper;
  69. #endif
  70. boost::math::tools::test_result<value_type> result;
  71. std::cout << "Testing " << test_name << " with type " << type_name
  72. << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  73. //
  74. // test cyl_bessel_i_prime against data:
  75. //
  76. result = boost::math::tools::test_hetero<Real>(
  77. data,
  78. bind_func<Real>(funcp, 0, 1),
  79. extract_result<Real>(2));
  80. handle_test_result(result, data[result.worst()], result.worst(), type_name, "cyl_bessel_i_prime (integer orders)", test_name);
  81. std::cout << std::endl;
  82. #endif
  83. }
  84. template <class T>
  85. void test_bessel(T, const char* name)
  86. {
  87. BOOST_MATH_STD_USING
  88. // function values calculated on wolframalpha.com
  89. static const boost::array<boost::array<T, 3>, 10> i0_prime_data = {{
  90. {{ SC_(0.0), SC_(0.0), SC_(0.0) }},
  91. {{ SC_(0.0), SC_(1.0), SC_(0.565159103992485027207696027609863307328899621621) }},
  92. {{ SC_(0.0), SC_(-2.0), SC_(-1.590636854637329063382254424999666247954478159496) }},
  93. {{ SC_(0.0), SC_(4.0), SC_(9.75946515370444990947519256731268090005597033325) }},
  94. {{ SC_(0.0), SC_(-7.0), SC_(-156.039092869955453462390580660711155630031052042) }},
  95. {{ SC_(0.0), T(1) / 1024, SC_(0.000488281308207663226432087816784315537514225208473395) }},
  96. {{ SC_(0.0), T(SC_(1.0)) / (1024*1024), SC_(4.76837158203179210108624277276025646653133998635957e-7) }},
  97. {{ SC_(0.0), SC_(-1.0), SC_(-0.565159103992485027207696027609863307328899621621) }},
  98. {{ SC_(0.0), SC_(100.0), SC_(1.068369390338162481206145763224295265446122844056e42) }},
  99. {{ SC_(0.0), SC_(200.0), SC_(2.034581549332062703427427977139069503896611616811e85) }},
  100. }};
  101. static const boost::array<boost::array<T, 3>, 10> i1_prime_data = {{
  102. {{ SC_(1.0), SC_(0.0), SC_(0.5) }},
  103. {{ SC_(1.0), SC_(1.0), SC_(0.700906773759523308390548597604854230278770689734) }},
  104. {{ SC_(1.0), SC_(-2.0), SC_(1.484266875017402735746077228311700229308602023038) }},
  105. {{ SC_(1.0), SC_(4.0), SC_(8.86205566371021801898747204138893227239862401112) }},
  106. {{ SC_(1.0), SC_(-8.0), SC_(377.579973623984772900011405549855040764360549303) }},
  107. {{ SC_(1.0), T(SC_(1.0))/1024, SC_(0.500000178813946168551133736709856567600996119560422) }},
  108. {{ SC_(1.0), T(SC_(1.0))/(1024*1024), SC_(0.500000000000170530256582434815189962442052310320626) }},
  109. {{ SC_(1.0), SC_(-10.0), SC_(2548.6177980961290060357079567493748381638767230173) }},
  110. {{ SC_(1.0), SC_(100.0), SC_(1.063068013227692198707659399971251708633941964885e42) }},
  111. {{ SC_(1.0), SC_(200.0), SC_(2.029514265663064306024535986893764274813192678064e85) }},
  112. }};
  113. static const boost::array<boost::array<T, 3>, 11> in_prime_data = {{
  114. {{ SC_(-2.0), SC_(0.0), SC_(0.0) }},
  115. {{ SC_(2.0), T(SC_(1.0))/(1024*1024), SC_(2.38418579101598640072416185021877537269848820467704e-7) }},
  116. {{ SC_(5.0), SC_(10.0), SC_(837.8963945578616177877239800250165373153505679130) }},
  117. {{ SC_(-5.0), SC_(100.0), SC_(9.434574089052212641696648538570565739509851953166e41) }},
  118. {{ SC_(-5.0), SC_(-1.0), SC_(0.001379804441262006949232714689824343061461150959112) }},
  119. {{ SC_(10.0), SC_(20.0), SC_(3.887291476282816593964936516887942731146400030466e6) }},
  120. {{ SC_(10.0), SC_(-5.0), SC_(-0.0101556299784624552653083645193223022003797137770) }},
  121. {{ SC_(1e+02), SC_(9.0), SC_(3.0600487816519872979909028718737622834061708443e-92) }},
  122. {{ SC_(1e+02), SC_(80.0), SC_(7.43545006374466980237328068214707549314834217923e8) }},
  123. {{ SC_(-100.0), SC_(-200.0), SC_(-4.8578174816088978115191937982677942557681326349558e74) }},
  124. {{ SC_(10.0), SC_(1e-100), SC_(2.6911444554673721340388007054673721340e-909) }},
  125. }};
  126. static const boost::array<boost::array<T, 3>, 10> iv_prime_data = {{
  127. {{ SC_(2.25), T(1)/(1024*1024), SC_(5.5296993766970839641084373853875345330202883e-9) }},
  128. {{ SC_(5.5), SC_(3.125), SC_(0.11607917746126037030394881599790144677553715606) }},
  129. {{ T(-5) + T(1)/1024, SC_(2.125), SC_(0.0001131925559871199041270456478317398625046249903864372470342210384462922281) }},
  130. {{ SC_(-5.5), SC_(10.0), SC_(659.1902595786901927596924259811320437384361101) }},
  131. {{ SC_(-5.5), SC_(100.0), SC_(9.191476042191556775282339209385028823905941708e41) }},
  132. {{ T(-10486074)/(1024*1024), T(1)/1024, SC_(-1.44873720736417608945635957884937466861026978539e39) }},
  133. {{ T(-10486074)/(1024*1024), SC_(50.0), SC_(1.082410021443599516897183930739816215073642812109e20) }},
  134. {{ T(144794)/1024, SC_(100.0), SC_(3575.11008553328328036816705258135747714241715202) }},
  135. {{ T(144794)/1024, SC_(200.0), SC_(2.7358895637426974377937620224627094172800852276956e64) }},
  136. {{ T(-144794)/1024, SC_(100.0), SC_(3575.11008700037933897402396449269857968451879323) }},
  137. }};
  138. static const boost::array<boost::array<T, 3>, 5> iv_prime_large_data = {{
  139. {{ SC_(-1.0), static_cast<T>(ldexp(0.5, -512)), SC_(0.5) }},
  140. {{ SC_(1.0), static_cast<T>(ldexp(0.5, -512)), SC_(0.5) }},
  141. {{ SC_(1.125), static_cast<T>(ldexp(0.5, -512)), SC_(2.42025162605150606399395900489934587657244145536315936432966315563638e-20) }},
  142. {{ SC_(0.5), static_cast<T>(ldexp(0.5, -683)), SC_(3.5741154998461284276309443770923823816821202344841143399486401387635e102) }},
  143. #if LDBL_MAX_10_EXP > 326
  144. {{ SC_(-1.125), static_cast<T>(ldexp(0.5, -512)), SC_(4.0715272050947359203430409041001937149343363573066460226173390878707e327) }},
  145. #else
  146. { { SC_(-1.125), static_cast<T>(ldexp(0.5, -512)), std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>() } },
  147. #endif
  148. }};
  149. do_test_cyl_bessel_i_prime<T>(i0_prime_data, name, "Bessel I'0: Mathworld Data");
  150. do_test_cyl_bessel_i_prime<T>(i1_prime_data, name, "Bessel I'1: Mathworld Data");
  151. do_test_cyl_bessel_i_prime<T>(in_prime_data, name, "Bessel I'n: Mathworld Data");
  152. do_test_cyl_bessel_i_prime_int<T>(i0_prime_data, name, "Bessel I'0: Mathworld Data (Integer Version)");
  153. do_test_cyl_bessel_i_prime_int<T>(i1_prime_data, name, "Bessel I'1: Mathworld Data (Integer Version)");
  154. do_test_cyl_bessel_i_prime_int<T>(in_prime_data, name, "Bessel I'n: Mathworld Data (Integer Version)");
  155. do_test_cyl_bessel_i_prime<T>(iv_prime_data, name, "Bessel I'v: Mathworld Data");
  156. #include "bessel_i_prime_int_data.ipp"
  157. do_test_cyl_bessel_i_prime<T>(bessel_i_prime_int_data, name, "Bessel I'n: Random Data");
  158. #include "bessel_i_prime_data.ipp"
  159. do_test_cyl_bessel_i_prime<T>(bessel_i_prime_data, name, "Bessel I'v: Random Data");
  160. if(0 != static_cast<T>(ldexp(static_cast<T>(0.5), -700)))
  161. do_test_cyl_bessel_i_prime<T>(iv_prime_large_data, name, "Bessel I'v: Mathworld Data (large values)");
  162. }