]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // lambert_w_test_values.cpp |
2 | ||
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) | |
7 | ||
8 | // Write a C++ file J:\Cpp\Misc\lambert_w_1000_test_values\lambert_w_mp_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. | |
12 | ||
13 | // Multiprecision types: | |
14 | //#include <boost/multiprecision/cpp_bin_float.hpp> | |
15 | #include <boost/multiprecision/cpp_dec_float.hpp> // boost::multiprecision::cpp_dec_float_100 | |
16 | using boost::multiprecision::cpp_dec_float_100; | |
17 | ||
18 | #include <boost/math/special_functions/lambert_w.hpp> // | |
19 | using boost::math::lambert_w0; | |
20 | ||
21 | #include <iostream> | |
22 | // using std::cout; using std::std::endl; using std::ios; using std::std::cerr; | |
23 | #include <iomanip> | |
24 | using std::setprecision; | |
25 | using std::showpoint; | |
26 | #include <fstream> | |
27 | using std::ofstream; | |
28 | #include <cassert> | |
29 | #include <cfloat> // for DBL_EPS etc | |
30 | #include <limits> // for numeric limits. | |
31 | //#include <ctype> | |
32 | #include <string> | |
33 | #include <algorithm> | |
34 | using std::transform; | |
35 | ||
36 | const char* prefix = "static "; // "static const" or "static constexpr" or just "const "" or "" even? | |
37 | // But problems with VS2017 and GCC not accepting same format mean only static at present. | |
38 | ||
39 | const long double eps = std::numeric_limits<long double>::epsilon(); | |
40 | ||
41 | /* | |
42 | ||
43 | // Sample test values from Wolfram. | |
44 | template <typename RealType> | |
45 | static RealType zs[noof_tests]; | |
46 | ||
47 | template <typename RealType> | |
48 | void init_zs() | |
49 | { | |
50 | zs<RealType>[0] = BOOST_MATH_TEST_VALUE(RealType, -0.35); | |
51 | zs<RealType>[1] = BOOST_MATH_TEST_VALUE(RealType, -0.3); | |
52 | zs<RealType>[2] = BOOST_MATH_TEST_VALUE(RealType, -0.01); | |
53 | zs<RealType>[3] = BOOST_MATH_TEST_VALUE(RealType, +0.01); | |
54 | zs<RealType>[4] = BOOST_MATH_TEST_VALUE(RealType, 0.1); | |
55 | zs<RealType>[5] = BOOST_MATH_TEST_VALUE(RealType, 0.5); | |
56 | zs<RealType>[6] = BOOST_MATH_TEST_VALUE(RealType, 1.); | |
57 | zs<RealType>[7] = BOOST_MATH_TEST_VALUE(RealType, 2.); | |
58 | zs<RealType>[8] = BOOST_MATH_TEST_VALUE(RealType, 5.); | |
59 | zs<RealType>[9] = BOOST_MATH_TEST_VALUE(RealType, 10.); | |
60 | zs<RealType>[10] = BOOST_MATH_TEST_VALUE(RealType, 100.); | |
61 | zs<RealType>[11] = BOOST_MATH_TEST_VALUE(RealType, 1e+6); | |
62 | }; | |
63 | ||
64 | // 'Known good' Lambert w values using N[productlog(-0.3), 50] | |
65 | // evaluated to full precision of RealType (up to 50 decimal digits). | |
66 | template <typename RealType> | |
67 | static RealType ws[noof_tests]; | |
68 | ||
69 | template <typename RealType> | |
70 | void init_ws() | |
71 | { | |
72 | ws<RealType>[0] = BOOST_MATH_TEST_VALUE(RealType, -0.7166388164560738505881698000038650406110575701385055261614344530078353170171071547711151137001759321); | |
73 | ws<RealType>[1] = BOOST_MATH_TEST_VALUE(RealType, -0.4894022271802149690362312519962933689234100060163590345114659679736814083816206187318524147462752111); | |
74 | ws<RealType>[2] = BOOST_MATH_TEST_VALUE(RealType, -0.01010152719853875327292018767138623973670903993475235877290726369225412969738704722202330440072213641); | |
75 | ws<RealType>[3] = BOOST_MATH_TEST_VALUE(RealType, 0.009901473843595011885336326816570107953627746494917415482611387085655068978243229360100010886171970918); | |
76 | ws<RealType>[4] = BOOST_MATH_TEST_VALUE(RealType, 0.09127652716086226429989572142317956865311922405147203264830839460717224625441755165020664592995606710); | |
77 | ws<RealType>[5] = BOOST_MATH_TEST_VALUE(RealType, 0.3517337112491958260249093009299510651714642155171118040466438461099606107203387108968323038321915693); | |
78 | ws<RealType>[6] = BOOST_MATH_TEST_VALUE(RealType, 0.5671432904097838729999686622103555497538157871865125081351310792230457930866845666932194469617522946); // Output from https://www.wolframalpha.com/input/?i=lambert_w0(1) | |
79 | ws<RealType>[7] = BOOST_MATH_TEST_VALUE(RealType, 0.8526055020137254913464724146953174668984533001514035087721073946525150656742630448965773783502494847); | |
80 | ws<RealType>[8] = BOOST_MATH_TEST_VALUE(RealType, 1.326724665242200223635099297758079660128793554638047479789290393025342679920536226774469916608426789); // https://www.wolframalpha.com/input/?i=N%5Bproductlog(5),+100%5D | |
81 | ws<RealType>[9] = BOOST_MATH_TEST_VALUE(RealType, 1.745528002740699383074301264875389911535288129080941331322206048555557259941551704989523510778883075); | |
82 | ws<RealType>[10] = BOOST_MATH_TEST_VALUE(RealType, 3.385630140290050184888244364529726867491694170157806680386174654885206544913039277686735236213650781); | |
83 | ws<RealType>[11] = BOOST_MATH_TEST_VALUE(RealType, 11.38335808614005262200015678158500428903377470601886512143238610626898610768018867797709315493717650); | |
84 | ////W(1e35) = 76.256377207295812974093508663841808129811690961764 too big for float. | |
85 | }; | |
86 | ||
87 | */ | |
88 | ||
89 | // Global so accessible from output_value. | |
90 | // Creates if no file exists, & uses default overwrite/ ios::replace. | |
91 | const char filename[] = "lambert_w_low_reference values.ipp"; // | |
92 | std::ofstream fout(filename, std::ios::out); ; // | |
93 | ||
94 | // 100 decimal digits for the value fed to macro BOOST_MATH_TEST_VALUE | |
95 | typedef cpp_dec_float_100 RealType; | |
96 | ||
97 | void output_value(size_t index, RealType value) | |
98 | { | |
99 | fout | |
100 | << " zs<RealType>[" << index << "] = BOOST_MATH_TEST_VALUE(RealType, " | |
101 | << value | |
102 | << ");" | |
103 | << std::endl; | |
104 | return; | |
105 | } | |
106 | ||
107 | void output_lambert_w0(size_t index, RealType value) | |
108 | { | |
109 | fout | |
110 | << " ws<RealType>[" << index << "] = BOOST_MATH_TEST_VALUE(RealType, " | |
111 | << lambert_w0(value) | |
112 | << ");" | |
113 | << std::endl; | |
114 | return; | |
115 | } | |
116 | ||
117 | int main() | |
118 | { // Make C++ file containing Lambert W test values. | |
119 | std::cout << filename << " "; | |
120 | #ifdef __TIMESTAMP__ | |
121 | std::cout << __TIMESTAMP__; | |
122 | #endif | |
123 | std::cout << std::endl; | |
124 | std::cout << "Lambert W0 decimal digit precision values." << std::endl; | |
125 | ||
126 | // Note __FILE__ & __TIMESTAMP__ are ANSI standard C & thus Std C++? | |
127 | ||
128 | if (!fout.is_open()) | |
129 | { // File failed to open OK. | |
130 | std::cerr << "Open file " << filename << " failed!" << std::endl; | |
131 | std::cerr << "errno " << errno << std::endl; | |
132 | return -1; | |
133 | } | |
134 | ||
135 | int output_precision = std::numeric_limits<cpp_dec_float_100>::digits10; | |
136 | // cpp_dec_float_100 is ample precision and | |
137 | // has several extra bits internally so max_digits10 are not needed. | |
138 | fout.precision(output_precision); | |
139 | ||
140 | int no_of_tests = 100; | |
141 | ||
142 | // Intro for RealType values. | |
143 | std::cout << "Lambert W test values written to file " << filename << std::endl; | |
144 | fout << | |
145 | "\n" | |
146 | "// A collection of Lambert W test values computed using " | |
147 | << output_precision << " decimal digits precision.\n" | |
148 | "// C++ floating-point type is " << "RealType." "\n" | |
149 | "\n" | |
150 | "// Written by " << __FILE__ << " " << __TIMESTAMP__ << "\n" | |
151 | ||
152 | "\n" | |
153 | "// Copyright Paul A. Bristow 2017." "\n" | |
154 | "// Distributed under the Boost Software License, Version 1.0." "\n" | |
155 | "// (See accompanying file LICENSE_1_0.txt" "\n" | |
156 | "// or copy at http://www.boost.org/LICENSE_1_0.txt)" "\n" | |
157 | << std::endl; | |
158 | ||
159 | fout << "// Size of arrays of arguments z and Lambert W" << std::endl; | |
160 | fout << "static const unsigned int noof_tests = " << no_of_tests << ";" << std::endl; | |
161 | ||
162 | // Declare arrays of z and Lambert W. | |
163 | ||
164 | fout << "// Declare arrays of arguments z and Lambert W(z)" << std::endl; | |
165 | fout << "// The values are defined using the macro BOOST_MATH_TEST_VALUE to ensure\n" | |
166 | "// that both built-in and multiprecision types are correctly initialiased with full precision.\n" | |
167 | "// built-in types like double require a floating-point literal like 3.14,\n" | |
168 | "// but multiprecision types require a decimal digit string like \"3.14\".\n" | |
169 | << std::endl; | |
170 | fout << | |
171 | "\n" | |
172 | "template <typename RealType>""\n" | |
173 | "static RealType zs[" << no_of_tests << "];" | |
174 | << std::endl; | |
175 | ||
176 | fout << | |
177 | "\n" | |
178 | "template <typename RealType>""\n" | |
179 | "static RealType ws[" << no_of_tests << "];" | |
180 | << std::endl; | |
181 | ||
182 | RealType max_z("10"); | |
183 | RealType min_z("-0.35"); | |
184 | RealType step_size("0.01"); | |
185 | size_t step_count = no_of_tests; | |
186 | ||
187 | // Output to initialize array of arguments z for Lambert W. | |
188 | fout << | |
189 | "\n" | |
190 | << "template <typename RealType>\n" | |
191 | "void init_zs()\n" | |
192 | "{\n"; | |
193 | ||
194 | RealType z = min_z; | |
195 | for (size_t i = 0; (i < no_of_tests); i++) | |
196 | { | |
197 | output_value(i, z); | |
198 | z += step_size; | |
199 | } | |
200 | fout << "};" << std::endl; | |
201 | ||
202 | // Output array of Lambert W values. | |
203 | fout << | |
204 | "\n" | |
205 | << "template <typename RealType>\n" | |
206 | "void init_ws()\n" | |
207 | "{\n"; | |
208 | ||
209 | z = min_z; | |
210 | for (size_t i = 0; (i < step_count); i++) | |
211 | { | |
212 | output_lambert_w0(i, z); | |
213 | z += step_size; | |
214 | } | |
215 | fout << "};" << std::endl; | |
216 | ||
217 | fout << "// End of lambert_w_mp_values.ipp " << std::endl; | |
218 | fout.close(); | |
219 | ||
220 | std::cout << "Lambert_w0 values written to files " << __TIMESTAMP__ << std::endl; | |
221 | return 0; | |
222 | } // main | |
223 | ||
224 | ||
225 | /* | |
226 | ||
227 | start and finish checks again Wolfram Alpha: | |
228 | ws<RealType>[0] = BOOST_MATH_TEST_VALUE(RealType, -0.7166388164560738505881698000038650406110575701385055261614344530078353170171071547711151137001759321); | |
229 | Wolfram N[productlog(-0.35), 100] -0.7166388164560738505881698000038650406110575701385055261614344530078353170171071547711151137001759321 | |
230 | ||
231 | ||
232 | ws<RealType>[19] = BOOST_MATH_TEST_VALUE(RealType, 0.7397278549447991214587608743391115983469848985053641692586810406118264600667862543570373167046626221); | |
233 | Wolfram N[productlog(1.55), 100] 0.7397278549447991214587608743391115983469848985053641692586810406118264600667862543570373167046626221 | |
234 | ||
235 | ||
236 | */ | |
237 |