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"
8 BOOST_AUTO_TEST_SUITE(test_autodiff_4
)
10 BOOST_AUTO_TEST_CASE_TEMPLATE(lround_llround_lltrunc_truncl
, T
,
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
;
24 constexpr std::size_t m
= 3;
25 const auto &cx
= static_cast<T
>(3.25);
26 auto x
= make_fvar
<T
, m
>(cx
);
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
));
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
));
41 BOOST_AUTO_TEST_CASE_TEMPLATE(equality
, T
, all_float_types
) {
43 using boost::math::epsilon_difference
;
44 using boost::math::fpclassify
;
45 using boost::math::ulp
;
46 using std::fpclassify
;
48 constexpr std::size_t m
= 3;
51 auto x
= make_fvar
<T
, m
>(0.0);
53 BOOST_CHECK_EQUAL(x
.derivative(0u), y
);
57 #if defined(BOOST_AUTODIFF_TESTING_INCLUDE_MULTIPRECISION)
58 BOOST_AUTO_TEST_CASE_TEMPLATE(multiprecision
, T
, multiprecision_float_types
) {
59 using boost::multiprecision::fabs
;
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);
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
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
);
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
;
91 test_detail::RandomSample
<T
> x_sampler
{1, 100};
92 for (auto i
: boost::irange(test_constants::n_samples
)) {
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());
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
;
107 test_detail::RandomSample
<T
> x_sampler
{-100, 100};
108 for (auto i
: boost::irange(test_constants::n_samples
)) {
110 auto x
= x_sampler
.next();
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());
119 BOOST_AUTO_TEST_CASE_TEMPLATE(atanh_hpp
, T
, all_float_types
) {
120 using boost::math::nextafter
;
121 using std::nextafter
;
123 using boost::math::atanh
;
124 using test_constants
= test_constants_t
<T
>;
125 static constexpr auto m
= test_constants::order
;
127 test_detail::RandomSample
<T
> x_sampler
{-1, 1};
128 for (auto i
: boost::irange(test_constants::n_samples
)) {
130 auto x
= nextafter(x_sampler
.next(), T(0));
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());
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
;
152 using test_constants
= test_constants_t
<T
>;
153 static constexpr auto m
= test_constants::order
;
155 test_detail::RandomSample
<T
> x_sampler
{-1, 1};
156 for (auto i
: boost::irange(test_constants::n_samples
)) {
159 while (fpclassify(T(fabs(x
) - 1)) == FP_ZERO
) {
160 x
= x_sampler
.next();
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());
170 BOOST_AUTO_TEST_CASE_TEMPLATE(bernoulli_hpp
, T
, all_float_types
) {
172 using boost::multiprecision::min
;
174 using test_constants
= test_constants_t
<T
>;
175 static constexpr auto m
= test_constants::order
;
177 for (auto i
: boost::irange(test_constants::n_samples
)) {
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());
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());
194 BOOST_AUTO_TEST_SUITE_END()