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