test_autodiff_6.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // Copyright Matthew Pulver 2018 - 2019.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. #include "test_autodiff.hpp"
  6. BOOST_AUTO_TEST_SUITE(test_autodiff_6)
  7. /*********************************************************************************************************************
  8. * special functions tests
  9. *********************************************************************************************************************/
  10. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_1_hpp, T, all_float_types) {
  11. using test_constants = test_constants_t<T>;
  12. static constexpr auto m = test_constants::order;
  13. test_detail::RandomSample<T> k_sampler{T{-1}, T{1}};
  14. test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
  15. boost::math::constants::two_pi<T>()};
  16. for (auto i : boost::irange(test_constants::n_samples)) {
  17. std::ignore = i;
  18. auto k = k_sampler.next();
  19. auto phi = phi_sampler.next();
  20. BOOST_CHECK_CLOSE(boost::math::ellint_1(make_fvar<T, m>(k)).derivative(0u),
  21. boost::math::ellint_1(k),
  22. 2.5e3 * test_constants::pct_epsilon());
  23. BOOST_CHECK_CLOSE(
  24. boost::math::ellint_1(make_fvar<T, m>(k), make_fvar<T, m>(phi))
  25. .derivative(0u),
  26. boost::math::ellint_1(k, phi), 1e4 * test_constants::pct_epsilon());
  27. }
  28. }
  29. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_2_hpp, T, all_float_types) {
  30. using test_constants = test_constants_t<T>;
  31. static constexpr auto m = test_constants::order;
  32. test_detail::RandomSample<T> k_sampler{-1, 1};
  33. test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
  34. boost::math::constants::two_pi<T>()};
  35. for (auto i : boost::irange(test_constants::n_samples)) {
  36. std::ignore = i;
  37. auto k = k_sampler.next();
  38. auto phi = phi_sampler.next();
  39. BOOST_CHECK_CLOSE(boost::math::ellint_2(make_fvar<T, m>(k)).derivative(0u),
  40. boost::math::ellint_2(k),
  41. 2.5e3 * test_constants::pct_epsilon());
  42. BOOST_CHECK_CLOSE(
  43. boost::math::ellint_2(make_fvar<T, m>(k), make_fvar<T, m>(phi))
  44. .derivative(0u),
  45. boost::math::ellint_2(k, phi), 2.5e3 * test_constants::pct_epsilon());
  46. }
  47. }
  48. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_3_hpp, T, all_float_types) {
  49. using boost::math::nextafter;
  50. using boost::multiprecision::nextafter;
  51. using boost::math::differentiation::detail::sin;
  52. using boost::multiprecision::min;
  53. using std::min;
  54. using std::sin;
  55. using test_constants = test_constants_t<T>;
  56. static constexpr auto m = test_constants::order;
  57. test_detail::RandomSample<T> k_sampler{-1, 1};
  58. test_detail::RandomSample<T> n_sampler{-2000, 2000};
  59. test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
  60. boost::math::constants::two_pi<T>()};
  61. for (auto i : boost::irange(test_constants::n_samples)) {
  62. std::ignore = i;
  63. auto k = k_sampler.next();
  64. auto phi = phi_sampler.next();
  65. auto n = (min)((min)(n_sampler.next(), T(1) / (sin(phi) * sin(phi))),
  66. nextafter(T(1), T(0)));
  67. BOOST_CHECK_CLOSE(boost::math::ellint_3(make_fvar<T, m>(k),
  68. make_fvar<T, m>(n),
  69. make_fvar<T, m>(phi))
  70. .derivative(0u),
  71. boost::math::ellint_3(k, n, phi),
  72. 2.5e3 * test_constants::pct_epsilon());
  73. }
  74. }
  75. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_d_hpp, T, all_float_types) {
  76. using test_constants = test_constants_t<T>;
  77. static constexpr auto m = test_constants::order;
  78. test_detail::RandomSample<T> k_sampler{-1, 1};
  79. test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
  80. boost::math::constants::two_pi<T>()};
  81. for (auto i : boost::irange(test_constants::n_samples)) {
  82. std::ignore = i;
  83. auto k = k_sampler.next();
  84. auto phi = phi_sampler.next();
  85. BOOST_CHECK_CLOSE(boost::math::ellint_d(make_fvar<T, m>(k)).derivative(0u),
  86. boost::math::ellint_d(k),
  87. 2.5e3 * test_constants::pct_epsilon());
  88. BOOST_CHECK_CLOSE(
  89. boost::math::ellint_d(make_fvar<T, m>(k), make_fvar<T, m>(phi))
  90. .derivative(0u),
  91. boost::math::ellint_d(k, phi), 2.5e3 * test_constants::pct_epsilon());
  92. }
  93. }
  94. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rf_hpp, T, all_float_types) {
  95. using boost::math::tools::max;
  96. using std::max;
  97. using boost::math::nextafter;
  98. using std::nextafter;
  99. using test_constants = test_constants_t<T>;
  100. static constexpr auto m = test_constants::order;
  101. test_detail::RandomSample<T> x_sampler{0, 2000};
  102. test_detail::RandomSample<T> y_sampler{0, 2000};
  103. test_detail::RandomSample<T> z_sampler{0, 2000};
  104. for (auto i : boost::irange(test_constants::n_samples)) {
  105. std::ignore = i;
  106. auto x = nextafter(x_sampler.next(), ((std::numeric_limits<T>::max))());
  107. auto y = nextafter(y_sampler.next(), ((std::numeric_limits<T>::max))());
  108. auto z = nextafter(z_sampler.next(), ((std::numeric_limits<T>::max))());
  109. BOOST_CHECK_CLOSE(
  110. boost::math::ellint_rf(make_fvar<T, m>(x), make_fvar<T, m>(y),
  111. make_fvar<T, m>(z))
  112. .derivative(0u),
  113. boost::math::ellint_rf(x, y, z), 2.5e3 * test_constants::pct_epsilon());
  114. }
  115. }
  116. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rc_hpp, T, all_float_types) {
  117. using boost::math::fpclassify;
  118. using boost::math::nextafter;
  119. using boost::math::signbit;
  120. using boost::math::tools::max;
  121. using boost::multiprecision::fpclassify;
  122. using boost::multiprecision::signbit;
  123. using std::max;
  124. using std::nextafter;
  125. using test_constants = test_constants_t<T>;
  126. static constexpr auto m = test_constants::order;
  127. test_detail::RandomSample<T> x_sampler{0, 2000};
  128. test_detail::RandomSample<T> y_sampler{0, 2000};
  129. for (auto i : boost::irange(test_constants::n_samples)) {
  130. std::ignore = i;
  131. auto x = x_sampler.next();
  132. auto y = T(0);
  133. while (fpclassify(T(y)) == FP_ZERO) {
  134. y = (max)(y_sampler.next(),
  135. nextafter(T(0), T(signbit(y) ? -1 : 1) *
  136. ((std::numeric_limits<T>::max))()));
  137. }
  138. BOOST_CHECK_CLOSE(
  139. boost::math::ellint_rc(make_fvar<T, m>(x), make_fvar<T, m>(y))
  140. .derivative(0u),
  141. boost::math::ellint_rc(x, y), 2.5e3 * test_constants::pct_epsilon());
  142. }
  143. }
  144. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rj_hpp, T, all_float_types) {
  145. using boost::math::fpclassify;
  146. using boost::math::nextafter;
  147. using boost::math::signbit;
  148. using boost::math::tools::max;
  149. using boost::multiprecision::fpclassify;
  150. using boost::multiprecision::signbit;
  151. using std::max;
  152. using std::nextafter;
  153. using test_constants = test_constants_t<T>;
  154. static constexpr auto m = test_constants::order;
  155. test_detail::RandomSample<T> x_sampler{0, 2000};
  156. test_detail::RandomSample<T> y_sampler{0, 2000};
  157. test_detail::RandomSample<T> z_sampler{0, 2000};
  158. test_detail::RandomSample<T> p_sampler{-2000, 2000};
  159. for (auto i : boost::irange(test_constants::n_samples)) {
  160. std::ignore = i;
  161. auto x = x_sampler.next();
  162. auto y = (x != 0 ? 1 : 0) + y_sampler.next();
  163. auto z = ((x == 0 || y == 0) ? 1 : 0) + z_sampler.next();
  164. auto p = T(0);
  165. while (fpclassify(T(p)) == FP_ZERO) {
  166. p = (max)(p_sampler.next(),
  167. nextafter(T(0), T(signbit(p) ? -1 : 1) *
  168. ((std::numeric_limits<T>::max))()));
  169. }
  170. BOOST_CHECK_CLOSE(
  171. boost::math::ellint_rj(make_fvar<T, m>(x), make_fvar<T, m>(y),
  172. make_fvar<T, m>(z), make_fvar<T, m>(p))
  173. .derivative(0u),
  174. boost::math::ellint_rj(x, y, z, p),
  175. 2.5e3 * test_constants::pct_epsilon());
  176. }
  177. }
  178. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rd_hpp, T, all_float_types) {
  179. using test_constants = test_constants_t<T>;
  180. static constexpr auto m = test_constants::order;
  181. test_detail::RandomSample<T> x_sampler{0, 2000};
  182. test_detail::RandomSample<T> y_sampler{0, 2000};
  183. test_detail::RandomSample<T> z_sampler{0, 2000};
  184. for (auto i : boost::irange(test_constants::n_samples)) {
  185. std::ignore = i;
  186. auto x = x_sampler.next();
  187. auto y = (x == 0 ? 1 : 0) + y_sampler.next();
  188. auto z = z_sampler.next();
  189. BOOST_CHECK_CLOSE(
  190. boost::math::ellint_rd(make_fvar<T, m>(x), make_fvar<T, m>(y),
  191. make_fvar<T, m>(z))
  192. .derivative(0u),
  193. boost::math::ellint_rd(x, y, z), 2.5e3 * test_constants::pct_epsilon());
  194. }
  195. }
  196. BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rg_hpp, T, all_float_types) {
  197. using boost::math::nextafter;
  198. using std::nextafter;
  199. using test_constants = test_constants_t<T>;
  200. static constexpr auto m = test_constants::order;
  201. test_detail::RandomSample<T> x_sampler{0, 2000};
  202. test_detail::RandomSample<T> y_sampler{0, 2000};
  203. test_detail::RandomSample<T> z_sampler{0, 2000};
  204. for (auto i : boost::irange(test_constants::n_samples)) {
  205. std::ignore = i;
  206. auto x = nextafter(x_sampler.next(), ((std::numeric_limits<T>::max))());
  207. auto y = nextafter(y_sampler.next(), ((std::numeric_limits<T>::max))());
  208. auto z = z_sampler.next();
  209. BOOST_CHECK_CLOSE(
  210. boost::math::ellint_rg(make_fvar<T, m>(x), make_fvar<T, m>(y),
  211. make_fvar<T, m>(z))
  212. .derivative(0u),
  213. boost::math::ellint_rg(x, y, z), 50 * test_constants::pct_epsilon());
  214. }
  215. }
  216. BOOST_AUTO_TEST_CASE_TEMPLATE(erf_hpp, T, all_float_types) {
  217. using test_constants = test_constants_t<T>;
  218. static constexpr auto m = test_constants::order;
  219. test_detail::RandomSample<T> x_sampler{-2000, 2000};
  220. for (auto i : boost::irange(test_constants::n_samples)) {
  221. std::ignore = i;
  222. auto x = x_sampler.next();
  223. BOOST_CHECK(isNearZero(erf(make_fvar<T, m>(x)).derivative(0u) -
  224. boost::math::erf(x)));
  225. BOOST_CHECK(isNearZero(erfc(make_fvar<T, m>(x)).derivative(0u) -
  226. boost::math::erfc(x)));
  227. }
  228. }
  229. BOOST_AUTO_TEST_CASE_TEMPLATE(expint_hpp, T, all_float_types) {
  230. using test_constants = test_constants_t<T>;
  231. static constexpr auto m = test_constants::order;
  232. test_detail::RandomSample<T> x_sampler{1, 83};
  233. for (auto n :
  234. boost::irange(1u, static_cast<unsigned>(test_constants::n_samples))) {
  235. auto x = x_sampler.next();
  236. BOOST_CHECK_CLOSE(boost::math::expint(n, make_fvar<T, m>(x)).derivative(0u),
  237. boost::math::expint(n, x),
  238. 200 * test_constants::pct_epsilon());
  239. for (auto y : {-1, 1}) {
  240. BOOST_CHECK_CLOSE(
  241. boost::math::expint(make_fvar<T, m>(x * y)).derivative(0u),
  242. boost::math::expint(x * y), 200 * test_constants::pct_epsilon());
  243. }
  244. }
  245. }
  246. BOOST_AUTO_TEST_SUITE_END()