123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- // Copyright Matthew Pulver 2018 - 2019.
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // https://www.boost.org/LICENSE_1_0.txt)
- #include "test_autodiff.hpp"
- BOOST_AUTO_TEST_SUITE(test_autodiff_6)
- /*********************************************************************************************************************
- * special functions tests
- *********************************************************************************************************************/
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_1_hpp, T, all_float_types) {
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> k_sampler{T{-1}, T{1}};
- test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
- boost::math::constants::two_pi<T>()};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto k = k_sampler.next();
- auto phi = phi_sampler.next();
- BOOST_CHECK_CLOSE(boost::math::ellint_1(make_fvar<T, m>(k)).derivative(0u),
- boost::math::ellint_1(k),
- 2.5e3 * test_constants::pct_epsilon());
- BOOST_CHECK_CLOSE(
- boost::math::ellint_1(make_fvar<T, m>(k), make_fvar<T, m>(phi))
- .derivative(0u),
- boost::math::ellint_1(k, phi), 1e4 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_2_hpp, T, all_float_types) {
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> k_sampler{-1, 1};
- test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
- boost::math::constants::two_pi<T>()};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto k = k_sampler.next();
- auto phi = phi_sampler.next();
- BOOST_CHECK_CLOSE(boost::math::ellint_2(make_fvar<T, m>(k)).derivative(0u),
- boost::math::ellint_2(k),
- 2.5e3 * test_constants::pct_epsilon());
- BOOST_CHECK_CLOSE(
- boost::math::ellint_2(make_fvar<T, m>(k), make_fvar<T, m>(phi))
- .derivative(0u),
- boost::math::ellint_2(k, phi), 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_3_hpp, T, all_float_types) {
- using boost::math::nextafter;
- using boost::multiprecision::nextafter;
- using boost::math::differentiation::detail::sin;
- using boost::multiprecision::min;
- using std::min;
- using std::sin;
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> k_sampler{-1, 1};
- test_detail::RandomSample<T> n_sampler{-2000, 2000};
- test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
- boost::math::constants::two_pi<T>()};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto k = k_sampler.next();
- auto phi = phi_sampler.next();
- auto n = (min)((min)(n_sampler.next(), T(1) / (sin(phi) * sin(phi))),
- nextafter(T(1), T(0)));
- BOOST_CHECK_CLOSE(boost::math::ellint_3(make_fvar<T, m>(k),
- make_fvar<T, m>(n),
- make_fvar<T, m>(phi))
- .derivative(0u),
- boost::math::ellint_3(k, n, phi),
- 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_d_hpp, T, all_float_types) {
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> k_sampler{-1, 1};
- test_detail::RandomSample<T> phi_sampler{-boost::math::constants::two_pi<T>(),
- boost::math::constants::two_pi<T>()};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto k = k_sampler.next();
- auto phi = phi_sampler.next();
- BOOST_CHECK_CLOSE(boost::math::ellint_d(make_fvar<T, m>(k)).derivative(0u),
- boost::math::ellint_d(k),
- 2.5e3 * test_constants::pct_epsilon());
- BOOST_CHECK_CLOSE(
- boost::math::ellint_d(make_fvar<T, m>(k), make_fvar<T, m>(phi))
- .derivative(0u),
- boost::math::ellint_d(k, phi), 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rf_hpp, T, all_float_types) {
- using boost::math::tools::max;
- using std::max;
- using boost::math::nextafter;
- using std::nextafter;
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{0, 2000};
- test_detail::RandomSample<T> y_sampler{0, 2000};
- test_detail::RandomSample<T> z_sampler{0, 2000};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto x = nextafter(x_sampler.next(), ((std::numeric_limits<T>::max))());
- auto y = nextafter(y_sampler.next(), ((std::numeric_limits<T>::max))());
- auto z = nextafter(z_sampler.next(), ((std::numeric_limits<T>::max))());
- BOOST_CHECK_CLOSE(
- boost::math::ellint_rf(make_fvar<T, m>(x), make_fvar<T, m>(y),
- make_fvar<T, m>(z))
- .derivative(0u),
- boost::math::ellint_rf(x, y, z), 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rc_hpp, T, all_float_types) {
- using boost::math::fpclassify;
- using boost::math::nextafter;
- using boost::math::signbit;
- using boost::math::tools::max;
- using boost::multiprecision::fpclassify;
- using boost::multiprecision::signbit;
- using std::max;
- using std::nextafter;
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{0, 2000};
- test_detail::RandomSample<T> y_sampler{0, 2000};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto x = x_sampler.next();
- auto y = T(0);
- while (fpclassify(T(y)) == FP_ZERO) {
- y = (max)(y_sampler.next(),
- nextafter(T(0), T(signbit(y) ? -1 : 1) *
- ((std::numeric_limits<T>::max))()));
- }
- BOOST_CHECK_CLOSE(
- boost::math::ellint_rc(make_fvar<T, m>(x), make_fvar<T, m>(y))
- .derivative(0u),
- boost::math::ellint_rc(x, y), 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rj_hpp, T, all_float_types) {
- using boost::math::fpclassify;
- using boost::math::nextafter;
- using boost::math::signbit;
- using boost::math::tools::max;
- using boost::multiprecision::fpclassify;
- using boost::multiprecision::signbit;
- using std::max;
- using std::nextafter;
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{0, 2000};
- test_detail::RandomSample<T> y_sampler{0, 2000};
- test_detail::RandomSample<T> z_sampler{0, 2000};
- test_detail::RandomSample<T> p_sampler{-2000, 2000};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto x = x_sampler.next();
- auto y = (x != 0 ? 1 : 0) + y_sampler.next();
- auto z = ((x == 0 || y == 0) ? 1 : 0) + z_sampler.next();
- auto p = T(0);
- while (fpclassify(T(p)) == FP_ZERO) {
- p = (max)(p_sampler.next(),
- nextafter(T(0), T(signbit(p) ? -1 : 1) *
- ((std::numeric_limits<T>::max))()));
- }
- BOOST_CHECK_CLOSE(
- boost::math::ellint_rj(make_fvar<T, m>(x), make_fvar<T, m>(y),
- make_fvar<T, m>(z), make_fvar<T, m>(p))
- .derivative(0u),
- boost::math::ellint_rj(x, y, z, p),
- 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rd_hpp, T, all_float_types) {
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{0, 2000};
- test_detail::RandomSample<T> y_sampler{0, 2000};
- test_detail::RandomSample<T> z_sampler{0, 2000};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto x = x_sampler.next();
- auto y = (x == 0 ? 1 : 0) + y_sampler.next();
- auto z = z_sampler.next();
- BOOST_CHECK_CLOSE(
- boost::math::ellint_rd(make_fvar<T, m>(x), make_fvar<T, m>(y),
- make_fvar<T, m>(z))
- .derivative(0u),
- boost::math::ellint_rd(x, y, z), 2.5e3 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(ellint_rg_hpp, T, all_float_types) {
- using boost::math::nextafter;
- using std::nextafter;
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{0, 2000};
- test_detail::RandomSample<T> y_sampler{0, 2000};
- test_detail::RandomSample<T> z_sampler{0, 2000};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto x = nextafter(x_sampler.next(), ((std::numeric_limits<T>::max))());
- auto y = nextafter(y_sampler.next(), ((std::numeric_limits<T>::max))());
- auto z = z_sampler.next();
- BOOST_CHECK_CLOSE(
- boost::math::ellint_rg(make_fvar<T, m>(x), make_fvar<T, m>(y),
- make_fvar<T, m>(z))
- .derivative(0u),
- boost::math::ellint_rg(x, y, z), 50 * test_constants::pct_epsilon());
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(erf_hpp, T, all_float_types) {
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{-2000, 2000};
- for (auto i : boost::irange(test_constants::n_samples)) {
- std::ignore = i;
- auto x = x_sampler.next();
- BOOST_CHECK(isNearZero(erf(make_fvar<T, m>(x)).derivative(0u) -
- boost::math::erf(x)));
- BOOST_CHECK(isNearZero(erfc(make_fvar<T, m>(x)).derivative(0u) -
- boost::math::erfc(x)));
- }
- }
- BOOST_AUTO_TEST_CASE_TEMPLATE(expint_hpp, T, all_float_types) {
- using test_constants = test_constants_t<T>;
- static constexpr auto m = test_constants::order;
- test_detail::RandomSample<T> x_sampler{1, 83};
- for (auto n :
- boost::irange(1u, static_cast<unsigned>(test_constants::n_samples))) {
- auto x = x_sampler.next();
- BOOST_CHECK_CLOSE(boost::math::expint(n, make_fvar<T, m>(x)).derivative(0u),
- boost::math::expint(n, x),
- 200 * test_constants::pct_epsilon());
- for (auto y : {-1, 1}) {
- BOOST_CHECK_CLOSE(
- boost::math::expint(make_fvar<T, m>(x * y)).derivative(0u),
- boost::math::expint(x * y), 200 * test_constants::pct_epsilon());
- }
- }
- }
- BOOST_AUTO_TEST_SUITE_END()
|