test_autodiff_4.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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_4)
  7. BOOST_AUTO_TEST_CASE_TEMPLATE(lround_llround_lltrunc_truncl, T,
  8. all_float_types) {
  9. using boost::math::llround;
  10. using boost::math::lltrunc;
  11. using boost::math::lround;
  12. using boost::multiprecision::llround;
  13. using boost::multiprecision::lltrunc;
  14. using boost::multiprecision::lround;
  15. using detail::llround;
  16. using detail::lltrunc;
  17. using detail::lround;
  18. using detail::truncl;
  19. using std::truncl;
  20. constexpr std::size_t m = 3;
  21. const auto &cx = static_cast<T>(3.25);
  22. auto x = make_fvar<T, m>(cx);
  23. auto yl = lround(x);
  24. BOOST_CHECK_EQUAL(yl, lround(cx));
  25. auto yll = llround(x);
  26. BOOST_CHECK_EQUAL(yll, llround(cx));
  27. BOOST_CHECK_EQUAL(lltrunc(cx), lltrunc(x));
  28. #ifndef BOOST_NO_CXX17_IF_CONSTEXPR
  29. if constexpr (!bmp::is_number<T>::value &&
  30. !bmp::is_number_expression<T>::value) {
  31. BOOST_CHECK_EQUAL(truncl(x), truncl(cx));
  32. }
  33. #endif
  34. }
  35. BOOST_AUTO_TEST_CASE_TEMPLATE(equality, T, all_float_types) {
  36. BOOST_MATH_STD_USING
  37. using boost::math::epsilon_difference;
  38. using boost::math::fpclassify;
  39. using boost::math::ulp;
  40. using std::fpclassify;
  41. constexpr std::size_t m = 3;
  42. // check zeros
  43. {
  44. auto x = make_fvar<T, m>(0.0);
  45. auto y = T(-0.0);
  46. BOOST_CHECK_EQUAL(x.derivative(0u), y);
  47. }
  48. }
  49. #if defined(BOOST_AUTODIFF_TESTING_INCLUDE_MULTIPRECISION)
  50. BOOST_AUTO_TEST_CASE_TEMPLATE(multiprecision, T, multiprecision_float_types) {
  51. using boost::multiprecision::fabs;
  52. using detail::fabs;
  53. using std::fabs;
  54. const T eps = 3000 * std::numeric_limits<T>::epsilon();
  55. constexpr std::size_t Nw = 3;
  56. constexpr std::size_t Nx = 2;
  57. constexpr std::size_t Ny = 4;
  58. constexpr std::size_t Nz = 3;
  59. const auto w = make_fvar<T, Nw>(11);
  60. const auto x = make_fvar<T, 0, Nx>(12);
  61. const auto y = make_fvar<T, 0, 0, Ny>(13);
  62. const auto z = make_fvar<T, 0, 0, 0, Nz>(14);
  63. const auto v =
  64. mixed_partials_f(w, x, y, z); // auto = autodiff_fvar<T,Nw,Nx,Ny,Nz>
  65. // Calculated from Mathematica symbolic differentiation.
  66. const T answer = boost::lexical_cast<T>(
  67. "1976.3196007477977177798818752904187209081211892187"
  68. "5499076582535951111845769110560421820940516423255314");
  69. // BOOST_CHECK_CLOSE(v.derivative(Nw,Nx,Ny,Nz), answer, eps); // Doesn't work
  70. // for cpp_dec_float
  71. const T relative_error =
  72. static_cast<T>(fabs(v.derivative(Nw, Nx, Ny, Nz) / answer - 1));
  73. BOOST_CHECK_LT(relative_error, eps);
  74. }
  75. #endif
  76. BOOST_AUTO_TEST_CASE_TEMPLATE(acosh_hpp, T, all_float_types) {
  77. using boost::math::acosh;
  78. using test_constants = test_constants_t<T>;
  79. static constexpr auto m = test_constants::order;
  80. test_detail::RandomSample<T> x_sampler{1, 100};
  81. for (auto i : boost::irange(test_constants::n_samples)) {
  82. std::ignore = i;
  83. auto x = x_sampler.next();
  84. auto autodiff_v = acosh(make_fvar<T, m>(x));
  85. auto anchor_v = acosh(x);
  86. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  87. 1e3 * test_constants::pct_epsilon());
  88. }
  89. }
  90. BOOST_AUTO_TEST_CASE_TEMPLATE(asinh_hpp, T, all_float_types) {
  91. using boost::math::asinh;
  92. using test_constants = test_constants_t<T>;
  93. static constexpr auto m = test_constants::order;
  94. test_detail::RandomSample<T> x_sampler{-100, 100};
  95. for (auto i : boost::irange(test_constants::n_samples)) {
  96. std::ignore = i;
  97. auto x = x_sampler.next();
  98. auto autodiff_v = asinh(make_fvar<T, m>(x));
  99. auto anchor_v = asinh(x);
  100. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  101. 1e3 * test_constants::pct_epsilon());
  102. }
  103. }
  104. BOOST_AUTO_TEST_CASE_TEMPLATE(atanh_hpp, T, all_float_types) {
  105. using boost::math::nextafter;
  106. using std::nextafter;
  107. using boost::math::atanh;
  108. using test_constants = test_constants_t<T>;
  109. static constexpr auto m = test_constants::order;
  110. test_detail::RandomSample<T> x_sampler{-1, 1};
  111. for (auto i : boost::irange(test_constants::n_samples)) {
  112. std::ignore = i;
  113. auto x = nextafter(x_sampler.next(), T(0));
  114. auto autodiff_v = atanh(make_fvar<T, m>(x));
  115. auto anchor_v = atanh(x);
  116. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  117. 1e3 * test_constants::pct_epsilon());
  118. }
  119. }
  120. BOOST_AUTO_TEST_CASE_TEMPLATE(atan_hpp, T, all_float_types) {
  121. using boost::math::float_prior;
  122. using boost::math::fpclassify;
  123. using boost::math::signbit;
  124. using boost::math::differentiation::detail::atan;
  125. using boost::multiprecision::atan;
  126. using boost::multiprecision::fabs;
  127. using boost::multiprecision::fpclassify;
  128. using boost::multiprecision::signbit;
  129. using detail::fabs;
  130. using std::atan;
  131. using std::fabs;
  132. using test_constants = test_constants_t<T>;
  133. static constexpr auto m = test_constants::order;
  134. test_detail::RandomSample<T> x_sampler{-1, 1};
  135. for (auto i : boost::irange(test_constants::n_samples)) {
  136. std::ignore = i;
  137. auto x = T(1);
  138. while (fpclassify(T(fabs(x) - 1)) == FP_ZERO) {
  139. x = x_sampler.next();
  140. }
  141. auto autodiff_v = atan(make_fvar<T, m>(x));
  142. auto anchor_v = atan(x);
  143. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  144. 1e3 * test_constants::pct_epsilon());
  145. }
  146. }
  147. BOOST_AUTO_TEST_CASE_TEMPLATE(bernoulli_hpp, T, all_float_types) {
  148. using boost::multiprecision::min;
  149. using std::min;
  150. using test_constants = test_constants_t<T>;
  151. static constexpr auto m = test_constants::order;
  152. for (auto i : boost::irange(test_constants::n_samples)) {
  153. {
  154. auto autodiff_v = boost::math::bernoulli_b2n<autodiff_fvar<T, m>>(i);
  155. auto anchor_v = boost::math::bernoulli_b2n<T>(i);
  156. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  157. 50 * test_constants::pct_epsilon());
  158. }
  159. {
  160. auto i_ = (min)(19, i);
  161. auto autodiff_v = boost::math::tangent_t2n<autodiff_fvar<T, m>>(i_);
  162. auto anchor_v = boost::math::tangent_t2n<T>(i_);
  163. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  164. 50 * test_constants::pct_epsilon());
  165. }
  166. }
  167. }
  168. BOOST_AUTO_TEST_SUITE_END()