]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright Paul A. Bristow 2016, 2017, 2018. |
2 | // Copyright John Maddock 2016. | |
3 | ||
4 | // Use, modification and distribution are subject to the | |
5 | // Boost Software License, Version 1.0. | |
6 | // (See accompanying file LICENSE_1_0.txt | |
7 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | // test_lambert_w.cpp | |
10 | //! \brief Basic sanity tests for Lambert W derivative. | |
11 | ||
1e59de90 TL |
12 | #include <climits> |
13 | #include <cfloat> | |
14 | #if defined(BOOST_MATH_TEST_FLOAT128) && (LDBL_MANT_DIG > 100) | |
15 | // | |
16 | // Mixing __float128 and long double results in: | |
17 | // error: __float128 and long double cannot be used in the same expression | |
18 | // whenever long double is a [possibly quasi-] quad precision type. | |
19 | // | |
20 | #undef BOOST_MATH_TEST_FLOAT128 | |
21 | #endif | |
22 | ||
92f5a8d4 TL |
23 | #ifdef BOOST_MATH_TEST_FLOAT128 |
24 | #include <boost/cstdfloat.hpp> // For float_64_t, float128_t. Must be first include! | |
25 | #endif // #ifdef #ifdef BOOST_MATH_TEST_FLOAT128 | |
26 | // Needs gnu++17 for BOOST_HAS_FLOAT128 | |
27 | #include <boost/config.hpp> // for BOOST_MSVC definition etc. | |
28 | #include <boost/version.hpp> // for BOOST_MSVC versions. | |
29 | ||
30 | // Boost macros | |
31 | #define BOOST_TEST_MAIN | |
32 | #define BOOST_LIB_DIAGNOSTIC "on" // Report library file details. | |
33 | #include <boost/test/included/unit_test.hpp> // Boost.Test | |
34 | // #include <boost/test/unit_test.hpp> // Boost.Test | |
35 | #include <boost/test/tools/floating_point_comparison.hpp> | |
36 | ||
37 | #include <boost/array.hpp> | |
92f5a8d4 TL |
38 | #include <boost/type_traits/is_constructible.hpp> |
39 | ||
40 | #ifdef BOOST_MATH_TEST_MULTIPRECISION | |
41 | #include <boost/multiprecision/cpp_dec_float.hpp> // boost::multiprecision::cpp_dec_float_50 | |
42 | using boost::multiprecision::cpp_dec_float_50; | |
43 | ||
44 | #include <boost/multiprecision/cpp_bin_float.hpp> | |
45 | using boost::multiprecision::cpp_bin_float_quad; | |
46 | ||
47 | #ifdef BOOST_MATH_TEST_FLOAT128 | |
48 | ||
49 | #ifdef BOOST_HAS_FLOAT128 | |
50 | // Including this header below without float128 triggers: | |
51 | // fatal error C1189: #error: "Sorry compiler is neither GCC, not Intel, don't know how to configure this header." | |
52 | #include <boost/multiprecision/float128.hpp> | |
53 | using boost::multiprecision::float128; | |
54 | #endif // ifdef BOOST_HAS_FLOAT128 | |
55 | #endif // #ifdef #ifdef BOOST_MATH_TEST_FLOAT128 | |
56 | ||
57 | #endif // #ifdef BOOST_MATH_TEST_MULTIPRECISION | |
58 | ||
59 | //#include <boost/fixed_point/fixed_point.hpp> // If available. | |
60 | ||
61 | #include <boost/math/concepts/real_concept.hpp> // for real_concept tests. | |
f67539c2 | 62 | #include <boost/math/special_functions/fpclassify.hpp> // isnan, isfinite. |
92f5a8d4 TL |
63 | #include <boost/math/special_functions/next.hpp> // float_next, float_prior |
64 | using boost::math::float_next; | |
65 | using boost::math::float_prior; | |
66 | #include <boost/math/special_functions/ulp.hpp> // ulp | |
67 | ||
68 | #include <boost/math/tools/test_value.hpp> // for create_test_value and macro BOOST_MATH_TEST_VALUE. | |
69 | #include <boost/math/policies/policy.hpp> | |
70 | using boost::math::policies::digits2; | |
71 | using boost::math::policies::digits10; | |
72 | #include <boost/math/special_functions/lambert_w.hpp> // For Lambert W lambert_w function. | |
73 | using boost::math::lambert_wm1; | |
74 | using boost::math::lambert_w0; | |
75 | ||
76 | #include <limits> | |
77 | #include <cmath> | |
78 | #include <typeinfo> | |
79 | #include <iostream> | |
80 | #include <exception> | |
81 | ||
82 | std::string show_versions(void); | |
83 | ||
84 | BOOST_AUTO_TEST_CASE( Derivatives_of_lambert_w ) | |
85 | { | |
86 | std::cout << "Macro BOOST_MATH_LAMBERT_W_DERIVATIVES to test 1st derivatives is defined." << std::endl; | |
87 | BOOST_TEST_MESSAGE("\nTest Lambert W function 1st differentials."); | |
88 | ||
89 | using boost::math::constants::exp_minus_one; | |
90 | using boost::math::lambert_w0_prime; | |
91 | using boost::math::lambert_wm1_prime; | |
92 | ||
93 | // Derivatives | |
94 | // https://www.wolframalpha.com/input/?i=derivative+of+productlog(0,+x) | |
95 | // d/dx(W_0(x)) = W(x)/(x W(x) + x) | |
96 | // https://www.wolframalpha.com/input/?i=derivative+of+productlog(-1,+x) | |
97 | // d/dx(W_(-1)(x)) = (W_(-1)(x))/(x W_(-1)(x) + x) | |
98 | ||
99 | // 55 decimal digit values added to allow future testing using multiprecision. | |
100 | ||
101 | typedef double RealType; | |
102 | ||
103 | int epsilons = 1; | |
104 | RealType tolerance = boost::math::tools::epsilon<RealType>() * epsilons; // 2 eps as a fraction. | |
105 | ||
106 | // derivative of productlog(-1, x) at x = -0.1 == -13.8803 | |
107 | // (derivative of productlog(-1, x) ) at x = N[-0.1, 55] - but the result disappears! | |
108 | // (derivative of N[productlog(-1, x), 55] ) at x = N[-0.1, 55] | |
109 | ||
110 | // W0 branch | |
111 | BOOST_CHECK_CLOSE_FRACTION(lambert_w0_prime(BOOST_MATH_TEST_VALUE(RealType, -0.2)), | |
112 | // BOOST_MATH_TEST_VALUE(RealType, 1.7491967609218355), | |
113 | BOOST_MATH_TEST_VALUE(RealType, 1.7491967609218358355273514903396335693828167746571404), | |
114 | tolerance); // 1.7491967609218358355273514903396335693828167746571404 | |
115 | ||
116 | BOOST_CHECK_CLOSE_FRACTION(lambert_w0_prime(BOOST_MATH_TEST_VALUE(RealType, 10.)), | |
117 | BOOST_MATH_TEST_VALUE(RealType, 0.063577133469345105142021311010780887641928338458371618), | |
118 | tolerance); | |
119 | ||
120 | // W-1 branch | |
121 | BOOST_CHECK_CLOSE_FRACTION(lambert_wm1_prime(BOOST_MATH_TEST_VALUE(RealType, -0.1)), | |
122 | BOOST_MATH_TEST_VALUE(RealType, -13.880252213229780748699361486619519025203815492277715), | |
123 | tolerance); | |
124 | // Lambert W_prime -13.880252213229780748699361486619519025203815492277715, double -13.880252213229781 | |
125 | ||
126 | BOOST_CHECK_CLOSE_FRACTION(lambert_wm1_prime(BOOST_MATH_TEST_VALUE(RealType, -0.2)), | |
127 | BOOST_MATH_TEST_VALUE(RealType, -8.2411940564179044961885598641955579728547896392013239), | |
128 | tolerance); | |
129 | // Lambert W_prime -8.2411940564179044961885598641955579728547896392013239, double -8.2411940564179051 | |
130 | ||
131 | // Lambert W_prime 0.063577133469345105142021311010780887641928338458371618, double 0.063577133469345098 | |
132 | }; // BOOST_AUTO_TEST_CASE("Derivatives of lambert_w") | |
133 | ||
134 |