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