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)
6 #include "test_autodiff.hpp"
7 #include <boost/math/tools/test_value.hpp>
9 BOOST_AUTO_TEST_SUITE(test_autodiff_4
)
11 BOOST_AUTO_TEST_CASE_TEMPLATE(lround_llround_lltrunc_truncl
, T
,
13 using boost::math::llround
;
14 using boost::math::lltrunc
;
15 using boost::math::lround
;
16 using boost::multiprecision::llround
;
17 using boost::multiprecision::lltrunc
;
18 using boost::multiprecision::lround
;
19 using detail::llround
;
20 using detail::lltrunc
;
25 constexpr std::size_t m
= 3;
26 const auto &cx
= static_cast<T
>(3.25);
27 auto x
= make_fvar
<T
, m
>(cx
);
29 BOOST_CHECK_EQUAL(yl
, lround(cx
));
30 auto yll
= llround(x
);
31 BOOST_CHECK_EQUAL(yll
, llround(cx
));
32 BOOST_CHECK_EQUAL(lltrunc(cx
), lltrunc(x
));
34 #ifndef BOOST_NO_CXX17_IF_CONSTEXPR
35 if constexpr (!bmp::is_number
<T
>::value
&&
36 !bmp::is_number_expression
<T
>::value
) {
37 BOOST_CHECK_EQUAL(truncl(x
), truncl(cx
));
42 BOOST_AUTO_TEST_CASE_TEMPLATE(equality
, T
, all_float_types
) {
44 using boost::math::epsilon_difference
;
45 using boost::math::fpclassify
;
46 using boost::math::ulp
;
47 using std::fpclassify
;
49 constexpr std::size_t m
= 3;
52 auto x
= make_fvar
<T
, m
>(0.0);
54 BOOST_CHECK_EQUAL(x
.derivative(0u), y
);
58 #if defined(BOOST_AUTODIFF_TESTING_INCLUDE_MULTIPRECISION)
59 BOOST_AUTO_TEST_CASE_TEMPLATE(multiprecision
, T
, multiprecision_float_types
) {
60 using boost::multiprecision::fabs
;
64 const T eps
= 3000 * std::numeric_limits
<T
>::epsilon();
65 constexpr std::size_t Nw
= 3;
66 constexpr std::size_t Nx
= 2;
67 constexpr std::size_t Ny
= 4;
68 constexpr std::size_t Nz
= 3;
69 const auto w
= make_fvar
<T
, Nw
>(11);
70 const auto x
= make_fvar
<T
, 0, Nx
>(12);
71 const auto y
= make_fvar
<T
, 0, 0, Ny
>(13);
72 const auto z
= make_fvar
<T
, 0, 0, 0, Nz
>(14);
74 mixed_partials_f(w
, x
, y
, z
); // auto = autodiff_fvar<T,Nw,Nx,Ny,Nz>
75 // Calculated from Mathematica symbolic differentiation.
76 const T answer
= BOOST_MATH_TEST_VALUE(T
, 1976.31960074779771777988187529041872090812118921875499076582535951111845769110560421820940516423255314);
77 // BOOST_CHECK_CLOSE(v.derivative(Nw,Nx,Ny,Nz), answer, eps); // Doesn't work
79 const T relative_error
=
80 static_cast<T
>(fabs(v
.derivative(Nw
, Nx
, Ny
, Nz
) / answer
- 1));
81 BOOST_CHECK_LT(relative_error
, eps
);
85 BOOST_AUTO_TEST_CASE_TEMPLATE(acosh_hpp
, T
, all_float_types
) {
86 using boost::math::acosh
;
87 using test_constants
= test_constants_t
<T
>;
88 static constexpr auto m
= test_constants::order
;
90 test_detail::RandomSample
<T
> x_sampler
{1, 100};
91 for (auto i
: boost::irange(test_constants::n_samples
)) {
93 auto x
= x_sampler
.next();
94 auto autodiff_v
= acosh(make_fvar
<T
, m
>(x
));
95 auto anchor_v
= acosh(x
);
96 BOOST_CHECK_CLOSE(autodiff_v
.derivative(0u), anchor_v
,
97 1e3
* test_constants::pct_epsilon());
101 BOOST_AUTO_TEST_CASE_TEMPLATE(asinh_hpp
, T
, all_float_types
) {
102 using boost::math::asinh
;
103 using test_constants
= test_constants_t
<T
>;
104 static constexpr auto m
= test_constants::order
;
106 test_detail::RandomSample
<T
> x_sampler
{-100, 100};
107 for (auto i
: boost::irange(test_constants::n_samples
)) {
109 auto x
= x_sampler
.next();
111 auto autodiff_v
= asinh(make_fvar
<T
, m
>(x
));
112 auto anchor_v
= asinh(x
);
113 BOOST_CHECK_CLOSE(autodiff_v
.derivative(0u), anchor_v
,
114 1e3
* test_constants::pct_epsilon());
118 BOOST_AUTO_TEST_CASE_TEMPLATE(atanh_hpp
, T
, all_float_types
) {
119 using boost::math::nextafter
;
120 using std::nextafter
;
122 using boost::math::atanh
;
123 using test_constants
= test_constants_t
<T
>;
124 static constexpr auto m
= test_constants::order
;
126 test_detail::RandomSample
<T
> x_sampler
{-1, 1};
127 for (auto i
: boost::irange(test_constants::n_samples
)) {
129 auto x
= nextafter(x_sampler
.next(), T(0));
131 auto autodiff_v
= atanh(make_fvar
<T
, m
>(x
));
132 auto anchor_v
= atanh(x
);
133 BOOST_CHECK_CLOSE(autodiff_v
.derivative(0u), anchor_v
,
134 1e3
* test_constants::pct_epsilon());
138 BOOST_AUTO_TEST_CASE_TEMPLATE(atan_hpp
, T
, all_float_types
) {
139 using boost::math::float_prior
;
140 using boost::math::fpclassify
;
141 using boost::math::signbit
;
142 using boost::math::differentiation::detail::atan
;
143 using boost::multiprecision::atan
;
144 using boost::multiprecision::fabs
;
145 using boost::multiprecision::fpclassify
;
146 using boost::multiprecision::signbit
;
151 using test_constants
= test_constants_t
<T
>;
152 static constexpr auto m
= test_constants::order
;
154 test_detail::RandomSample
<T
> x_sampler
{-1, 1};
155 for (auto i
: boost::irange(test_constants::n_samples
)) {
158 while (fpclassify(T(fabs(x
) - 1)) == FP_ZERO
) {
159 x
= x_sampler
.next();
162 auto autodiff_v
= atan(make_fvar
<T
, m
>(x
));
163 auto anchor_v
= atan(x
);
164 BOOST_CHECK_CLOSE(autodiff_v
.derivative(0u), anchor_v
,
165 1e3
* test_constants::pct_epsilon());
169 BOOST_AUTO_TEST_CASE_TEMPLATE(bernoulli_hpp
, T
, all_float_types
) {
171 using boost::multiprecision::min
;
173 using test_constants
= test_constants_t
<T
>;
174 static constexpr auto m
= test_constants::order
;
176 for (auto i
: boost::irange(test_constants::n_samples
)) {
178 auto autodiff_v
= boost::math::bernoulli_b2n
<autodiff_fvar
<T
, m
>>(i
);
179 auto anchor_v
= boost::math::bernoulli_b2n
<T
>(i
);
180 BOOST_CHECK_CLOSE(autodiff_v
.derivative(0u), anchor_v
,
181 50 * test_constants::pct_epsilon());
184 auto i_
= (min
)(19, i
);
185 auto autodiff_v
= boost::math::tangent_t2n
<autodiff_fvar
<T
, m
>>(i_
);
186 auto anchor_v
= boost::math::tangent_t2n
<T
>(i_
);
187 BOOST_CHECK_CLOSE(autodiff_v
.derivative(0u), anchor_v
,
188 50 * test_constants::pct_epsilon());
193 BOOST_AUTO_TEST_SUITE_END()