• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 #ifdef BOOST_MATH_TEST_FLOAT128
13 #include <boost/cstdfloat.hpp> // For float_64_t, float128_t. Must be first include!
14 #endif // #ifdef #ifdef BOOST_MATH_TEST_FLOAT128
15 // Needs gnu++17 for BOOST_HAS_FLOAT128
16 #include <boost/config.hpp>   // for BOOST_MSVC definition etc.
17 #include <boost/version.hpp>   // for BOOST_MSVC versions.
18 
19 // Boost macros
20 #define BOOST_TEST_MAIN
21 #define BOOST_LIB_DIAGNOSTIC "on" // Report library file details.
22 #include <boost/test/included/unit_test.hpp> // Boost.Test
23 // #include <boost/test/unit_test.hpp> // Boost.Test
24 #include <boost/test/tools/floating_point_comparison.hpp>
25 
26 #include <boost/array.hpp>
27 #include <boost/lexical_cast.hpp>
28 #include <boost/type_traits/is_constructible.hpp>
29 
30 #ifdef BOOST_MATH_TEST_MULTIPRECISION
31 #include <boost/multiprecision/cpp_dec_float.hpp> // boost::multiprecision::cpp_dec_float_50
32 using boost::multiprecision::cpp_dec_float_50;
33 
34 #include <boost/multiprecision/cpp_bin_float.hpp>
35 using boost::multiprecision::cpp_bin_float_quad;
36 
37 #ifdef BOOST_MATH_TEST_FLOAT128
38 
39 #ifdef BOOST_HAS_FLOAT128
40 // Including this header below without float128 triggers:
41 // fatal error C1189: #error:  "Sorry compiler is neither GCC, not Intel, don't know how to configure this header."
42 #include <boost/multiprecision/float128.hpp>
43 using boost::multiprecision::float128;
44 #endif // ifdef BOOST_HAS_FLOAT128
45 #endif // #ifdef #ifdef BOOST_MATH_TEST_FLOAT128
46 
47 #endif //   #ifdef BOOST_MATH_TEST_MULTIPRECISION
48 
49 //#include <boost/fixed_point/fixed_point.hpp> // If available.
50 
51 #include <boost/math/concepts/real_concept.hpp> // for real_concept tests.
52 #include <boost/math/special_functions/fpclassify.hpp> // isnan, isfinite.
53 #include <boost/math/special_functions/next.hpp> // float_next, float_prior
54 using boost::math::float_next;
55 using boost::math::float_prior;
56 #include <boost/math/special_functions/ulp.hpp>  // ulp
57 
58 #include <boost/math/tools/test_value.hpp>  // for create_test_value and macro BOOST_MATH_TEST_VALUE.
59 #include <boost/math/policies/policy.hpp>
60 using boost::math::policies::digits2;
61 using boost::math::policies::digits10;
62 #include <boost/math/special_functions/lambert_w.hpp> // For Lambert W lambert_w function.
63 using boost::math::lambert_wm1;
64 using boost::math::lambert_w0;
65 
66 #include <limits>
67 #include <cmath>
68 #include <typeinfo>
69 #include <iostream>
70 #include <exception>
71 
72 std::string show_versions(void);
73 
BOOST_AUTO_TEST_CASE(Derivatives_of_lambert_w)74 BOOST_AUTO_TEST_CASE( Derivatives_of_lambert_w )
75 {
76   std::cout << "Macro BOOST_MATH_LAMBERT_W_DERIVATIVES to test 1st derivatives is defined." << std::endl;
77   BOOST_TEST_MESSAGE("\nTest Lambert W function 1st differentials.");
78 
79   using boost::math::constants::exp_minus_one;
80   using boost::math::lambert_w0_prime;
81   using boost::math::lambert_wm1_prime;
82 
83   // Derivatives
84   // https://www.wolframalpha.com/input/?i=derivative+of+productlog(0,+x)
85   //  d/dx(W_0(x)) = W(x)/(x W(x) + x)
86   // https://www.wolframalpha.com/input/?i=derivative+of+productlog(-1,+x)
87   // d/dx(W_(-1)(x)) = (W_(-1)(x))/(x W_(-1)(x) + x)
88 
89   // 55 decimal digit values added to allow future testing using multiprecision.
90 
91   typedef double RealType;
92 
93   int epsilons = 1;
94   RealType tolerance = boost::math::tools::epsilon<RealType>() * epsilons; // 2 eps as a fraction.
95 
96   // derivative of productlog(-1, x)   at x = -0.1 == -13.8803
97   // (derivative of productlog(-1, x) ) at x = N[-0.1, 55] - but the result disappears!
98   // (derivative of N[productlog(-1, x), 55] ) at x = N[-0.1, 55]
99 
100   // W0 branch
101   BOOST_CHECK_CLOSE_FRACTION(lambert_w0_prime(BOOST_MATH_TEST_VALUE(RealType, -0.2)),
102    // BOOST_MATH_TEST_VALUE(RealType, 1.7491967609218355),
103     BOOST_MATH_TEST_VALUE(RealType, 1.7491967609218358355273514903396335693828167746571404),
104     tolerance); //                  1.7491967609218358355273514903396335693828167746571404
105 
106     BOOST_CHECK_CLOSE_FRACTION(lambert_w0_prime(BOOST_MATH_TEST_VALUE(RealType, 10.)),
107     BOOST_MATH_TEST_VALUE(RealType, 0.063577133469345105142021311010780887641928338458371618),
108     tolerance);
109 
110 // W-1 branch
111   BOOST_CHECK_CLOSE_FRACTION(lambert_wm1_prime(BOOST_MATH_TEST_VALUE(RealType, -0.1)),
112     BOOST_MATH_TEST_VALUE(RealType, -13.880252213229780748699361486619519025203815492277715),
113     tolerance);
114   // Lambert W_prime -13.880252213229780748699361486619519025203815492277715, double -13.880252213229781
115 
116   BOOST_CHECK_CLOSE_FRACTION(lambert_wm1_prime(BOOST_MATH_TEST_VALUE(RealType, -0.2)),
117     BOOST_MATH_TEST_VALUE(RealType, -8.2411940564179044961885598641955579728547896392013239),
118     tolerance);
119   // Lambert W_prime -8.2411940564179044961885598641955579728547896392013239, double -8.2411940564179051
120 
121   // Lambert W_prime 0.063577133469345105142021311010780887641928338458371618, double 0.063577133469345098
122 }; // BOOST_AUTO_TEST_CASE("Derivatives of lambert_w")
123 
124 
125