• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
output_value(size_t index,RealType value)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 
output_lambert_w0(size_t index,RealType value)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 
main()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 
238