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