test_autodiff_8.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  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_8)
  7. BOOST_AUTO_TEST_CASE_TEMPLATE(hermite_hpp, T, all_float_types) {
  8. using test_constants = test_constants_t<T>;
  9. static constexpr auto m = test_constants::order;
  10. test_detail::RandomSample<T> x_sampler{-200, 200};
  11. for (auto i : boost::irange(14u)) {
  12. auto x = x_sampler.next();
  13. auto autodiff_v = boost::math::hermite(i, make_fvar<T, m>(x));
  14. auto anchor_v = boost::math::hermite(i, x);
  15. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  16. }
  17. }
  18. BOOST_AUTO_TEST_CASE_TEMPLATE(heuman_lambda_hpp, T, all_float_types) {
  19. using test_constants = test_constants_t<T>;
  20. static constexpr auto m = test_constants::order;
  21. test_detail::RandomSample<T> x_sampler{-1, 1};
  22. test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
  23. boost::math::constants::two_pi<T>()};
  24. for (auto i : boost::irange(test_constants::n_samples)) {
  25. std::ignore = i;
  26. auto x = x_sampler.next();
  27. auto phi = phi_sampler.next();
  28. auto autodiff_v =
  29. boost::math::heuman_lambda(make_fvar<T, m>(x), make_fvar<T, m>(phi));
  30. auto anchor_v = boost::math::heuman_lambda(x, phi);
  31. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  32. }
  33. }
  34. BOOST_AUTO_TEST_CASE_TEMPLATE(hypot_hpp, T, all_float_types) {
  35. using test_constants = test_constants_t<T>;
  36. static constexpr auto m = test_constants::order;
  37. test_detail::RandomSample<T> x_sampler{-2000, 2000};
  38. test_detail::RandomSample<T> y_sampler{-2000, 2000};
  39. for (auto i : boost::irange(test_constants::n_samples)) {
  40. std::ignore = i;
  41. auto x = x_sampler.next();
  42. auto y = y_sampler.next();
  43. auto autodiff_v =
  44. boost::math::hypot(make_fvar<T, m>(x), make_fvar<T, m>(y));
  45. auto anchor_v = boost::math::hypot(x, y);
  46. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  47. }
  48. }
  49. BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi_elliptic_hpp, T, all_float_types) {
  50. using test_constants = test_constants_t<T>;
  51. static constexpr auto m = test_constants::order;
  52. test_detail::RandomSample<T> k_sampler{0, 1};
  53. test_detail::RandomSample<T> theta_sampler{-100, 100};
  54. for (auto i : boost::irange(test_constants::n_samples)) {
  55. std::ignore = i;
  56. auto k = k_sampler.next();
  57. auto theta = theta_sampler.next();
  58. BOOST_CHECK(isNearZero(
  59. boost::math::jacobi_cd(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  60. .derivative(0u) -
  61. boost::math::jacobi_cd(k, theta)));
  62. BOOST_CHECK(isNearZero(
  63. boost::math::jacobi_cn(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  64. .derivative(0u) -
  65. boost::math::jacobi_cn(k, theta)));
  66. BOOST_CHECK(isNearZero(
  67. boost::math::jacobi_cs(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  68. .derivative(0u) -
  69. boost::math::jacobi_cs(k, theta)));
  70. BOOST_CHECK(isNearZero(
  71. boost::math::jacobi_dc(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  72. .derivative(0u) -
  73. boost::math::jacobi_dc(k, theta)));
  74. BOOST_CHECK(isNearZero(
  75. boost::math::jacobi_dn(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  76. .derivative(0u) -
  77. boost::math::jacobi_dn(k, theta)));
  78. BOOST_CHECK(isNearZero(
  79. boost::math::jacobi_ds(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  80. .derivative(0u) -
  81. boost::math::jacobi_ds(k, theta)));
  82. BOOST_CHECK(isNearZero(
  83. boost::math::jacobi_nc(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  84. .derivative(0u) -
  85. boost::math::jacobi_nc(k, theta)));
  86. BOOST_CHECK(isNearZero(
  87. boost::math::jacobi_nd(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  88. .derivative(0u) -
  89. boost::math::jacobi_nd(k, theta)));
  90. BOOST_CHECK(isNearZero(
  91. boost::math::jacobi_ns(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  92. .derivative(0u) -
  93. boost::math::jacobi_ns(k, theta)));
  94. BOOST_CHECK(isNearZero(
  95. boost::math::jacobi_sc(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  96. .derivative(0u) -
  97. boost::math::jacobi_sc(k, theta)));
  98. BOOST_CHECK(isNearZero(
  99. boost::math::jacobi_sd(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  100. .derivative(0u) -
  101. boost::math::jacobi_sd(k, theta)));
  102. BOOST_CHECK(isNearZero(
  103. boost::math::jacobi_sn(make_fvar<T, m>(k), make_fvar<T, m>(theta))
  104. .derivative(0u) -
  105. boost::math::jacobi_sn(k, theta)));
  106. }
  107. }
  108. BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi_zeta_hpp, T, all_float_types) {
  109. using test_constants = test_constants_t<T>;
  110. static constexpr auto m = test_constants::order;
  111. test_detail::RandomSample<T> x_sampler{-1, 1};
  112. test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
  113. boost::math::constants::two_pi<T>()};
  114. for (auto i : boost::irange(test_constants::n_samples)) {
  115. std::ignore = i;
  116. auto x = x_sampler.next();
  117. auto phi = phi_sampler.next();
  118. BOOST_CHECK(isNearZero(
  119. boost::math::jacobi_zeta(make_fvar<T, m>(x), make_fvar<T, m>(phi))
  120. .derivative(0u) -
  121. boost::math::jacobi_zeta(x, phi)));
  122. }
  123. }
  124. BOOST_AUTO_TEST_CASE_TEMPLATE(laguerre_hpp, T, all_float_types) {
  125. using boost::multiprecision::min;
  126. using std::min;
  127. using test_constants = test_constants_t<T>;
  128. static constexpr auto m = test_constants::order;
  129. test_detail::RandomSample<unsigned> n_sampler{1, 50};
  130. test_detail::RandomSample<unsigned> r_sampler{0, 50};
  131. test_detail::RandomSample<T> x_sampler{0, 50};
  132. for (auto i : boost::irange(test_constants::n_samples)) {
  133. std::ignore = i;
  134. auto n = n_sampler.next();
  135. auto r = (min)(n - 1, r_sampler.next());
  136. auto x = x_sampler.next();
  137. {
  138. auto autodiff_v = boost::math::laguerre(n, make_fvar<T, m>(x));
  139. auto anchor_v = boost::math::laguerre(n, x);
  140. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  141. }
  142. {
  143. auto autodiff_v = boost::math::laguerre(n, r, make_fvar<T, m>(x));
  144. auto anchor_v = boost::math::laguerre(n, r, x);
  145. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  146. }
  147. }
  148. }
  149. BOOST_AUTO_TEST_CASE_TEMPLATE(lambert_w_hpp, T, all_float_types) {
  150. using boost::math::nextafter;
  151. using boost::math::tools::max;
  152. using boost::multiprecision::fabs;
  153. using boost::multiprecision::min;
  154. using detail::fabs;
  155. using std::fabs;
  156. using std::max;
  157. using std::min;
  158. using std::nextafter;
  159. using promoted_t = promote<T, double>;
  160. using test_constants = test_constants_t<T>;
  161. static constexpr auto m = test_constants::order;
  162. test_detail::RandomSample<T> x_sampler{static_cast<T>(-1 / std::exp(-1)),
  163. ((std::numeric_limits<T>::max))()};
  164. for (auto i : boost::irange(test_constants::n_samples)) {
  165. std::ignore = i;
  166. auto x = x_sampler.next();
  167. {
  168. auto x_ = (min<T>)(static_cast<T>(((max<promoted_t>))(
  169. -exp(promoted_t(-1)), promoted_t(x))),
  170. ((std::numeric_limits<T>::max))());
  171. {
  172. auto autodiff_v = boost::math::lambert_w0(make_fvar<T, m>(x_));
  173. auto anchor_v = boost::math::lambert_w0(x_);
  174. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  175. }
  176. {
  177. auto autodiff_v = boost::math::lambert_w0_prime(make_fvar<T, m>(x_));
  178. auto anchor_v = boost::math::lambert_w0_prime(x_);
  179. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  180. }
  181. }
  182. {
  183. auto x_ = nextafter(
  184. static_cast<T>(nextafter(
  185. ((max))(static_cast<promoted_t>(-exp(-1)), -fabs(promoted_t(x))),
  186. ((std::numeric_limits<promoted_t>::max))())),
  187. ((std::numeric_limits<T>::max))());
  188. x_ = (max)(static_cast<T>(-0.36), x_);
  189. BOOST_CHECK(isNearZero(
  190. boost::math::lambert_wm1(make_fvar<T, m>(x_)).derivative(0u) -
  191. boost::math::lambert_wm1(x_)));
  192. BOOST_CHECK(isNearZero(
  193. boost::math::lambert_wm1_prime(make_fvar<T, m>(x_)).derivative(0u) -
  194. boost::math::lambert_wm1_prime(x_)));
  195. }
  196. }
  197. }
  198. BOOST_AUTO_TEST_CASE_TEMPLATE(log1p_hpp, T, all_float_types) {
  199. using boost::math::log1p;
  200. using boost::multiprecision::log1p;
  201. using test_constants = test_constants_t<T>;
  202. static constexpr auto m = test_constants::order;
  203. test_detail::RandomSample<T> x_sampler{-1, 2000};
  204. for (auto i : boost::irange(test_constants::n_samples)) {
  205. std::ignore = i;
  206. auto x = x_sampler.next();
  207. BOOST_CHECK(
  208. isNearZero(log1p(make_fvar<T, m>(x)).derivative(0u) - log1p(x)));
  209. }
  210. }
  211. BOOST_AUTO_TEST_CASE_TEMPLATE(next_hpp, T, all_float_types) {
  212. using boost::math::float_advance;
  213. using boost::math::float_distance;
  214. using boost::math::float_next;
  215. using boost::math::float_prior;
  216. using boost::math::nextafter;
  217. using boost::multiprecision::nextafter;
  218. using test_constants = test_constants_t<T>;
  219. static constexpr auto m = test_constants::order;
  220. for (auto i : boost::irange(test_constants::n_samples)) {
  221. const auto j = static_cast<T>(i);
  222. auto fvar_j = make_fvar<T, m>(j);
  223. BOOST_CHECK(isNearZero(float_next(fvar_j).derivative(0u) - float_next(j)));
  224. BOOST_CHECK(
  225. isNearZero(float_prior(fvar_j).derivative(0u) - float_prior(j)));
  226. BOOST_CHECK(isNearZero(
  227. nextafter(fvar_j, make_fvar<T, m>(static_cast<T>(1))).derivative(0u) -
  228. nextafter(j, static_cast<T>(1))));
  229. BOOST_CHECK(
  230. isNearZero(nextafter(fvar_j, make_fvar<T, m>(static_cast<T>(i + 2))) -
  231. nextafter(j, static_cast<T>(i + 2))));
  232. BOOST_CHECK(
  233. isNearZero(nextafter(fvar_j, make_fvar<T, m>(static_cast<T>(i + 1)))
  234. .derivative(0u) -
  235. nextafter(j, static_cast<T>(i + 2))));
  236. BOOST_CHECK(isNearZero(
  237. nextafter(fvar_j, make_fvar<T, m>(static_cast<T>(-1))).derivative(0u) -
  238. nextafter(j, static_cast<T>(-1))));
  239. BOOST_CHECK(isNearZero(
  240. nextafter(fvar_j, make_fvar<T, m>(static_cast<T>(-1 * (i + 2))))
  241. .derivative(0u) -
  242. nextafter(j, -1 * static_cast<T>(i + 2))));
  243. BOOST_CHECK(isNearZero(
  244. nextafter(fvar_j, make_fvar<T, m>(static_cast<T>(-1 * (i + 1))))
  245. .derivative(0u) -
  246. nextafter(j, -1 * static_cast<T>(i + 2))));
  247. BOOST_CHECK(isNearZero(nextafter(fvar_j, fvar_j) - fvar_j));
  248. BOOST_CHECK(isNearZero(float_advance(fvar_j, 1).derivative(0u) -
  249. float_advance(j, 1)));
  250. BOOST_CHECK(isNearZero(float_advance(fvar_j, i + 2).derivative(0u) -
  251. float_advance(j, i + 2)));
  252. BOOST_CHECK(isNearZero(
  253. float_advance(fvar_j, i + 1).derivative(0u) -
  254. float_advance(float_advance(fvar_j, i + 2), -1).derivative(0u)));
  255. BOOST_CHECK(isNearZero(float_advance(fvar_j, -1).derivative(0u) -
  256. float_advance(j, -1)));
  257. BOOST_CHECK(isNearZero(
  258. float_advance(fvar_j, -i - 1).derivative(0u) -
  259. float_advance(float_advance(fvar_j, -i - 2), 1).derivative(0u)));
  260. BOOST_CHECK(isNearZero(float_advance(fvar_j, 0) - fvar_j));
  261. BOOST_CHECK(isNearZero(float_distance(fvar_j, j).derivative(0u) -
  262. static_cast<T>(0)));
  263. BOOST_CHECK(
  264. isNearZero(float_distance(float_next(fvar_j), fvar_j).derivative(0u) -
  265. ((make_fvar<T, m>(-1))).derivative(0u)));
  266. BOOST_CHECK(
  267. isNearZero(float_distance(float_prior(fvar_j), fvar_j).derivative(0u) -
  268. (make_fvar<T, m>(1)).derivative(0u)));
  269. }
  270. }
  271. BOOST_AUTO_TEST_CASE_TEMPLATE(owens_t_hpp, T, bin_float_types) {
  272. BOOST_MATH_STD_USING;
  273. using test_constants = test_constants_t<T>;
  274. static constexpr auto m = test_constants::order;
  275. test_detail::RandomSample<T> h_sampler{-2000, 2000};
  276. test_detail::RandomSample<T> a_sampler{-2000, 2000};
  277. for (auto i : boost::irange(test_constants::n_samples)) {
  278. std::ignore = i;
  279. auto h = h_sampler.next();
  280. auto a = a_sampler.next();
  281. auto autodiff_v =
  282. boost::math::owens_t(make_fvar<T, m>(h), make_fvar<T, m>(a));
  283. auto anchor_v = boost::math::owens_t(h, a);
  284. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  285. }
  286. }
  287. BOOST_AUTO_TEST_CASE_TEMPLATE(pow_hpp, T, all_float_types) {
  288. using test_constants = test_constants_t<T>;
  289. static constexpr auto m = test_constants::order;
  290. for (auto i : boost::irange(10)) {
  291. BOOST_CHECK_CLOSE(
  292. boost::math::pow<0>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  293. boost::math::pow<0>(static_cast<T>(i)), test_constants::pct_epsilon());
  294. BOOST_CHECK_CLOSE(
  295. boost::math::pow<1>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  296. boost::math::pow<1>(static_cast<T>(i)), test_constants::pct_epsilon());
  297. BOOST_CHECK_CLOSE(
  298. boost::math::pow<2>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  299. boost::math::pow<2>(static_cast<T>(i)), test_constants::pct_epsilon());
  300. BOOST_CHECK_CLOSE(
  301. boost::math::pow<3>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  302. boost::math::pow<3>(static_cast<T>(i)), test_constants::pct_epsilon());
  303. BOOST_CHECK_CLOSE(
  304. boost::math::pow<4>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  305. boost::math::pow<4>(static_cast<T>(i)), test_constants::pct_epsilon());
  306. BOOST_CHECK_CLOSE(
  307. boost::math::pow<5>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  308. boost::math::pow<5>(static_cast<T>(i)), test_constants::pct_epsilon());
  309. BOOST_CHECK_CLOSE(
  310. boost::math::pow<6>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  311. boost::math::pow<6>(static_cast<T>(i)), test_constants::pct_epsilon());
  312. BOOST_CHECK_CLOSE(
  313. boost::math::pow<7>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  314. boost::math::pow<7>(static_cast<T>(i)), test_constants::pct_epsilon());
  315. BOOST_CHECK_CLOSE(
  316. boost::math::pow<8>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  317. boost::math::pow<8>(static_cast<T>(i)), test_constants::pct_epsilon());
  318. BOOST_CHECK_CLOSE(
  319. boost::math::pow<9>(make_fvar<T, m>(static_cast<T>(i))).derivative(0u),
  320. boost::math::pow<9>(static_cast<T>(i)), test_constants::pct_epsilon());
  321. }
  322. }
  323. BOOST_AUTO_TEST_CASE_TEMPLATE(polygamma_hpp, T, all_float_types) {
  324. using test_constants = test_constants_t<T>;
  325. static constexpr auto m = test_constants::order;
  326. test_detail::RandomSample<T> x_sampler{0, 2000};
  327. for (auto i : boost::irange(test_constants::n_samples)) {
  328. auto x = x_sampler.next();
  329. try {
  330. auto autodiff_v = boost::math::polygamma(i, make_fvar<T, m>(x));
  331. auto anchor_v = boost::math::polygamma(i, x);
  332. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  333. } catch (const std::overflow_error &) {
  334. std::cout << "Overflow Error thrown with inputs i: " << i << " x: " << x
  335. << std::endl;
  336. BOOST_CHECK_THROW(boost::math::polygamma(i, make_fvar<T, m>(x)),
  337. boost::wrapexcept<std::overflow_error>);
  338. BOOST_CHECK_THROW(boost::math::polygamma(i, x),
  339. boost::wrapexcept<std::overflow_error>);
  340. }
  341. }
  342. }
  343. BOOST_AUTO_TEST_CASE_TEMPLATE(powm1_hpp, T, all_float_types) {
  344. using boost::math::tools::max;
  345. using boost::multiprecision::max;
  346. using std::max;
  347. using boost::multiprecision::log;
  348. using detail::log;
  349. using std::log;
  350. using boost::multiprecision::min;
  351. using std::min;
  352. using boost::multiprecision::sqrt;
  353. using detail::sqrt;
  354. using std::sqrt;
  355. using boost::math::nextafter;
  356. using boost::multiprecision::nextafter;
  357. using test_constants = test_constants_t<T>;
  358. static constexpr auto m = test_constants::order;
  359. test_detail::RandomSample<T> x_sampler{0, 2000};
  360. for (auto i : boost::irange(test_constants::n_samples)) {
  361. std::ignore = i;
  362. auto x = ((max))(x_sampler.next(),
  363. boost::math::nextafter(static_cast<T>(0),
  364. ((std::numeric_limits<T>::max))()));
  365. auto y =
  366. ((min))(x_sampler.next(),
  367. log(sqrt(((std::numeric_limits<T>::max))()) + 1) / log(x + 1));
  368. auto autodiff_v =
  369. boost::math::powm1(make_fvar<T, m>(x), make_fvar<T, m>(y));
  370. auto anchor_v = boost::math::powm1(x, y);
  371. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  372. }
  373. }
  374. BOOST_AUTO_TEST_CASE_TEMPLATE(sin_pi_hpp, T, all_float_types) {
  375. using test_constants = test_constants_t<T>;
  376. static constexpr auto m = test_constants::order;
  377. test_detail::RandomSample<T> x_sampler{-2000, 2000};
  378. for (auto i : boost::irange(test_constants::n_samples)) {
  379. std::ignore = i;
  380. auto x = x_sampler.next();
  381. BOOST_CHECK(
  382. isNearZero(boost::math::sin_pi(make_fvar<T, m>(x)).derivative(0u) -
  383. boost::math::sin_pi(x)));
  384. }
  385. }
  386. BOOST_AUTO_TEST_CASE_TEMPLATE(sinhc_hpp, T, all_float_types) {
  387. using test_constants = test_constants_t<T>;
  388. static constexpr auto m = test_constants::order;
  389. test_detail::RandomSample<T> x_sampler{ -80, 80 };
  390. for (auto i : boost::irange(test_constants::n_samples)) {
  391. std::ignore = i;
  392. auto x = x_sampler.next();
  393. if (x != 0) {
  394. auto autodiff_v = boost::math::sinhc_pi(make_fvar<T, m>(x));
  395. auto anchor_v = boost::math::sinhc_pi(x);
  396. BOOST_CHECK_CLOSE(autodiff_v.derivative(0u), anchor_v,
  397. 50 * test_constants::pct_epsilon());
  398. }
  399. }
  400. }
  401. BOOST_AUTO_TEST_CASE_TEMPLATE(spherical_harmonic_hpp, T, all_float_types) {
  402. using test_constants = test_constants_t<T>;
  403. static constexpr auto m = test_constants::order;
  404. test_detail::RandomSample<T> theta_sampler{0,
  405. boost::math::constants::pi<T>()};
  406. test_detail::RandomSample<T> phi_sampler{0,
  407. boost::math::constants::two_pi<T>()};
  408. test_detail::RandomSample<int> r_sampler{0, test_constants::n_samples};
  409. for (auto n : boost::irange(
  410. 1u, static_cast<unsigned>(test_constants::n_samples) + 1u)) {
  411. auto theta = theta_sampler.next();
  412. auto phi = phi_sampler.next();
  413. auto r = (std::min)(static_cast<int>(n) - 1, r_sampler.next());
  414. {
  415. auto autodiff_v = boost::math::spherical_harmonic(
  416. n, r, make_fvar<T, m>(theta), make_fvar<T, m>(phi));
  417. auto anchor_v = boost::math::spherical_harmonic(n, r, theta, phi);
  418. BOOST_CHECK(
  419. isNearZero(autodiff_v.real().derivative(0u) - anchor_v.real()));
  420. BOOST_CHECK(
  421. isNearZero(autodiff_v.imag().derivative(0u) - anchor_v.imag()));
  422. }
  423. {
  424. auto autodiff_v = boost::math::spherical_harmonic_r(
  425. n, r, make_fvar<T, m>(theta), make_fvar<T, m>(phi));
  426. auto anchor_v = boost::math::spherical_harmonic_r(n, r, theta, phi);
  427. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  428. }
  429. {
  430. auto autodiff_v = boost::math::spherical_harmonic_i(
  431. n, r, make_fvar<T, m>(theta), make_fvar<T, m>(phi));
  432. auto anchor_v = boost::math::spherical_harmonic_i(n, r, theta, phi);
  433. BOOST_CHECK(isNearZero(autodiff_v.derivative(0u) - anchor_v));
  434. }
  435. }
  436. }
  437. BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt1pm1_hpp, T, all_float_types) {
  438. using test_constants = test_constants_t<T>;
  439. static constexpr auto m = test_constants::order;
  440. test_detail::RandomSample<T> x_sampler{-1, 2000};
  441. for (auto i : boost::irange(test_constants::n_samples)) {
  442. std::ignore = i;
  443. auto x = x_sampler.next();
  444. BOOST_CHECK(
  445. isNearZero(boost::math::sqrt1pm1(make_fvar<T, m>(x)).derivative(0u) -
  446. boost::math::sqrt1pm1(x)));
  447. }
  448. }
  449. BOOST_AUTO_TEST_CASE_TEMPLATE(trigamma_hpp, T, all_float_types) {
  450. using test_constants = test_constants_t<T>;
  451. static constexpr auto m = test_constants::order;
  452. test_detail::RandomSample<T> x_sampler{0, 2000};
  453. for (auto i : boost::irange(test_constants::n_samples)) {
  454. std::ignore = i;
  455. auto x = x_sampler.next();
  456. BOOST_CHECK(
  457. isNearZero(boost::math::trigamma(make_fvar<T, m>(x)).derivative(0u) -
  458. boost::math::trigamma(x)));
  459. }
  460. }
  461. BOOST_AUTO_TEST_SUITE_END()