1 // \modular-boost\libs\math\test\lambert_w_high_reference_values.cpp
3 // Copyright Paul A. Bristow 2017.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
8 // Write a C++ file \lambert_w_mp_hi_values.ipp
9 // containing arrays of z arguments and 100 decimal digit precision lambert_w0(z) reference values.
10 // These can be used in tests of precision of less-precise types like
11 // built-in float, double, long double and quad and cpp_dec_float_50.
13 // These cover the range from 0.5 to (std::numeric_limits<>::max)();
14 // The Fukushima algorithm changes from a series function for all z > 0.5.
16 // Multiprecision types:
17 //#include <boost/multiprecision/cpp_bin_float.hpp>
18 #include <boost/multiprecision/cpp_dec_float.hpp> // boost::multiprecision::cpp_dec_float_100
19 using boost::multiprecision::cpp_dec_float_100
;
21 #include <boost/math/special_functions/lambert_w.hpp> //
22 using boost::math::lambert_w0
;
23 using boost::math::lambert_wm1
;
26 // using std::cout; using std::std::endl; using std::ios; using std::std::cerr;
28 using std::setprecision
;
33 #include <cfloat> // for DBL_EPS etc
34 #include <limits> // for numeric limits.
38 const long double eps
= std::numeric_limits
<long double>::epsilon();
40 // Creates if no file exists, & uses default overwrite/ ios::replace.
41 const char filename
[] = "lambert_w_high_reference_values.ipp"; //
42 std::ofstream
fout(filename
, std::ios::out
);
44 typedef cpp_dec_float_100 RealType
; // 100 decimal digits for the value fed to macro BOOST_MATH_TEST_VALUE.
45 // Could also use cpp_dec_float_50 or cpp_bin_float types.
47 const int no_of_tests
= 450; // 500 overflows float.
49 static const float min_z
= 0.5F
; // for element[0]
52 { // Make C++ file containing Lambert W test values.
53 std::cout
<< filename
<< " ";
54 std::cout
<< std::endl
;
55 std::cout
<< "Lambert W0 decimal digit precision values for high z argument values." << std::endl
;
58 { // File failed to open OK.
59 std::cerr
<< "Open file " << filename
<< " failed!" << std::endl
;
60 std::cerr
<< "errno " << errno
<< std::endl
;
65 int output_precision
= std::numeric_limits
<RealType
>::digits10
;
66 // cpp_dec_float_100 is ample precision and
67 // has several extra bits internally so max_digits10 are not needed.
68 fout
.precision(output_precision
);
69 fout
<< std::showpoint
<< std::endl
; // Do show trailing zeros.
71 // Intro for RealType values.
72 std::cout
<< "Lambert W test values written to file " << filename
<< std::endl
;
75 "// A collection of big Lambert W test values computed using "
76 << output_precision
<< " decimal digits precision.\n"
77 "// C++ floating-point type is " << "RealType." "\n"
79 "// Written by " << __FILE__
<< " " << __TIMESTAMP__
<< "\n"
82 "// Copyright Paul A. Bristow 2017." "\n"
83 "// Distributed under the Boost Software License, Version 1.0." "\n"
84 "// (See accompanying file LICENSE_1_0.txt" "\n"
85 "// or copy at http://www.boost.org/LICENSE_1_0.txt)" "\n"
88 fout
<< "// Size of arrays of arguments z and Lambert W" << std::endl
;
89 fout
<< "static const unsigned int noof_tests = " << no_of_tests
<< ";" << std::endl
;
91 // Declare arrays of z and Lambert W.
92 fout
<< "\n// Declare arrays of arguments z and Lambert W(z)" << std::endl
;
95 "template <typename RealType>""\n"
96 "static RealType zs[" << no_of_tests
<< "];"
101 "template <typename RealType>""\n"
102 "static RealType ws[" << no_of_tests
<< "];"
105 fout
<< "// The values are defined using the macro BOOST_MATH_TEST_VALUE to ensure\n"
106 "// that both built-in and multiprecision types are correctly initialiased with full precision.\n"
107 "// built-in types like float, double require a floating-point literal like 3.14,\n"
108 "// but multiprecision types require a decimal digit string like \"3.14\".\n"
109 "// Numerical values are chosen to avoid exactly representable values."
112 static const RealType min_z
= 0.6; // for element[0]
114 const RealType max_z
= (std::numeric_limits
<float>::max
)() / 10; // (std::numeric_limits<float>::max)() to make sure is OK for all floating-point types.
115 // Less a bit as lambert_w0(max) may be inaccurate.
116 const RealType step_size
= 0.5F
; // Increment step size.
117 const RealType step_factor
= 2.f
; // Multiple factor, typically 2, 5 or 10.
118 const int step_modulo
= 5;
122 // Output function to initialize array of arguments z and Lambert W.
125 << "template <typename RealType>\n"
129 for (size_t index
= 0; (index
!= no_of_tests
); index
++)
132 << " zs<RealType>[" << index
<< "] = BOOST_MATH_TEST_VALUE(RealType, "
133 << z
// Since start with converting a float may get lots of usefully random digits.
138 << " ws<RealType>[" << index
<< "] = BOOST_MATH_TEST_VALUE(RealType, "
143 if ((index
% step_modulo
) == 0)
149 { // Don't go over max for float.
150 std::cout
<< "too big z" << std::endl
;
154 fout
<< "};" << std::endl
;
156 fout
<< "// End of lambert_w_mp_high_values.ipp " << std::endl
;
158 catch (std::exception
& ex
)
160 std::cout
<< "Exception " << ex
.what() << std::endl
;
165 std::cout
<< no_of_tests
<< " Lambert_w0 values written to files " << __TIMESTAMP__
<< std::endl
;
171 A few spot checks again Wolfram:
173 zs<RealType>[1] = BOOST_MATH_TEST_VALUE(RealType, 1.6999999999999999555910790149937383830547332763671875);
174 ws<RealType>[1] = BOOST_MATH_TEST_VALUE(RealType, 0.7796011225311008662356536916883580556792500749037209859530390902424444585607630246126725241921761054);
175 Wolfram 0.7796011225311008662356536916883580556792500749037209859530390902424444585607630246126725241921761054
177 zs<RealType>[99] = BOOST_MATH_TEST_VALUE(RealType, 3250582.599999999976716935634613037109375);
178 ws<RealType>[99] = BOOST_MATH_TEST_VALUE(RealType, 12.47094339016839065212822905567651460418204106065566910956134121802725695306834966790193342511971825);
179 Wolfram 12.47094339016839065212822905567651460418204106065566910956134121802725695306834966790193342511971825