test_ibeta_derivative.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright John Maddock 2006.
  2. // Copyright Paul A. Bristow 2007, 2009
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  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/beta.hpp>
  11. #include <boost/math/tools/stats.hpp>
  12. #include <boost/math/tools/test.hpp>
  13. #include <boost/math/constants/constants.hpp>
  14. #include <boost/type_traits/is_floating_point.hpp>
  15. #include <boost/array.hpp>
  16. #include "functor.hpp"
  17. #include "handle_test_result.hpp"
  18. #include "table_type.hpp"
  19. #ifndef SC_
  20. #define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L))
  21. #endif
  22. template <class T>
  23. T ibeta_forwarder(T a, T b, T x)
  24. {
  25. T derivative;
  26. boost::math::detail::ibeta_imp(a, b, x, boost::math::policies::policy<>(), false, true, &derivative);
  27. return derivative;
  28. }
  29. template <class Real, class T>
  30. void do_test_beta(const T& data, const char* type_name, const char* test_name)
  31. {
  32. typedef Real value_type;
  33. typedef value_type (*pg)(value_type, value_type, value_type);
  34. #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  35. pg funcp = boost::math::ibeta_derivative<value_type, value_type, value_type>;
  36. #else
  37. pg funcp = boost::math::ibeta_derivative;
  38. #endif
  39. boost::math::tools::test_result<value_type> result;
  40. #if !(defined(ERROR_REPORTING_MODE) && !defined(BETA_INC_FUNCTION_TO_TEST))
  41. std::cout << "Testing " << test_name << " with type " << type_name
  42. << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  43. //
  44. // test ibeta_derivative against data:
  45. //
  46. result = boost::math::tools::test_hetero<Real>(
  47. data,
  48. bind_func<Real>(funcp, 0, 1, 2),
  49. extract_result<Real>(3));
  50. handle_test_result(result, data[result.worst()], result.worst(), type_name, "beta (incomplete)", test_name);
  51. #endif
  52. #if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  53. funcp = ibeta_forwarder<value_type>;
  54. #else
  55. funcp = ibeta_forwarder;
  56. #endif
  57. if(boost::math::tools::digits<value_type>() > 40)
  58. {
  59. //
  60. // test ibeta_derivative against data:
  61. //
  62. result = boost::math::tools::test_hetero<Real>(
  63. data,
  64. bind_func<Real>(funcp, 0, 1, 2),
  65. extract_result<Real>(3));
  66. handle_test_result(result, data[result.worst()], result.worst(), type_name, "beta (incomplete, internal call test)", test_name);
  67. }
  68. }
  69. template <class T>
  70. void test_beta(T, const char* name)
  71. {
  72. //
  73. // The actual test data is rather verbose, so it's in a separate file
  74. //
  75. // The contents are as follows, each row of data contains
  76. // five items, input value a, input value b, integration limits x, beta(a, b, x) and ibeta(a, b, x):
  77. //
  78. #if !defined(TEST_DATA) || (TEST_DATA == 1)
  79. # include "ibeta_derivative_small_data.ipp"
  80. do_test_beta<T>(ibeta_derivative_small_data, name, "Incomplete Beta Function Derivative: Small Values");
  81. #endif
  82. #if !defined(TEST_DATA) || (TEST_DATA == 2)
  83. # include "ibeta_derivative_data.ipp"
  84. do_test_beta<T>(ibeta_derivative_data, name, "Incomplete Beta Function Derivative: Medium Values");
  85. #endif
  86. #ifndef __SUNPRO_CC
  87. #if !defined(TEST_DATA) || (TEST_DATA == 3)
  88. # include "ibeta_derivative_large_data.ipp"
  89. do_test_beta<T>(ibeta_derivative_large_data, name, "Incomplete Beta Function Derivative: Large and Diverse Values");
  90. #endif
  91. #endif
  92. #if !defined(TEST_DATA) || (TEST_DATA == 4)
  93. # include "ibeta_derivative_int_data.ipp"
  94. do_test_beta<T>(ibeta_derivative_int_data, name, "Incomplete Beta Function Derivative: Small Integer Values");
  95. #endif
  96. }
  97. template <class T>
  98. void test_spots(T)
  99. {
  100. using std::ldexp;
  101. T tolerance = boost::math::tools::epsilon<T>() * 40000;
  102. BOOST_CHECK_CLOSE(
  103. ::boost::math::ibeta_derivative(
  104. static_cast<T>(2),
  105. static_cast<T>(4),
  106. ldexp(static_cast<T>(1), -557)),
  107. static_cast<T>(4.23957586190238472641508753637420672781472122471791800210e-167L), tolerance * 4);
  108. BOOST_CHECK_CLOSE(
  109. ::boost::math::ibeta_derivative(
  110. static_cast<T>(2),
  111. static_cast<T>(4.5),
  112. ldexp(static_cast<T>(1), -557)),
  113. static_cast<T>(5.24647512910420109893867082626308082567071751558842352760e-167L), tolerance * 4);
  114. }