]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright Paul A. Bristow 2017 |
2 | // Copyright John Z. Maddock 2017 | |
3 | ||
4 | // Distributed under the Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt or | |
6 | // copy at http ://www.boost.org/LICENSE_1_0.txt). | |
7 | ||
8 | /*! \brief Graph showing use of Lambert W function. | |
9 | ||
10 | \details | |
11 | ||
12 | Both Lambert W0 and W-1 branches can be shown on one graph. | |
13 | But useful to have another graph for larger values of argument z. | |
14 | Need two separate graphs for Lambert W0 and -1 prime because | |
15 | the sensible ranges and axes are too different. | |
16 | ||
17 | One would get too small LambertW0 in top right and W-1 in bottom left. | |
18 | ||
19 | */ | |
20 | ||
21 | #include <boost/math/special_functions/lambert_w.hpp> | |
22 | using boost::math::lambert_w0; | |
23 | using boost::math::lambert_wm1; | |
24 | using boost::math::lambert_w0_prime; | |
25 | using boost::math::lambert_wm1_prime; | |
26 | ||
27 | #include <boost/math/special_functions.hpp> | |
28 | using boost::math::isfinite; | |
29 | #include <boost/svg_plot/svg_2d_plot.hpp> | |
30 | using namespace boost::svg; | |
31 | #include <boost/svg_plot/show_2d_settings.hpp> | |
32 | using boost::svg::show_2d_plot_settings; | |
33 | ||
34 | #include <iostream> | |
35 | // using std::cout; | |
36 | // using std::endl; | |
37 | #include <exception> | |
38 | #include <stdexcept> | |
39 | #include <string> | |
40 | #include <array> | |
41 | #include <vector> | |
42 | #include <utility> | |
43 | using std::pair; | |
44 | #include <map> | |
45 | using std::map; | |
46 | #include <set> | |
47 | using std::multiset; | |
48 | #include <limits> | |
49 | using std::numeric_limits; | |
50 | #include <cmath> // | |
51 | ||
52 | /*! | |
53 | */ | |
54 | int main() | |
55 | { | |
56 | try | |
57 | { | |
58 | std::cout << "Lambert W graph example." << std::endl; | |
59 | ||
60 | //[lambert_w_graph_1 | |
61 | //] [/lambert_w_graph_1] | |
62 | { | |
63 | std::map<const double, double> wm1s; // Lambert W-1 branch values. | |
64 | std::map<const double, double> w0s; // Lambert W0 branch values. | |
65 | ||
66 | std::cout.precision(std::numeric_limits<double>::max_digits10); | |
67 | ||
68 | int count = 0; | |
69 | for (double z = -0.36787944117144232159552377016146086744581113103176804; z < 2.8; z += 0.001) | |
70 | { | |
71 | double w0 = lambert_w0(z); | |
72 | w0s[z] = w0; | |
73 | // std::cout << "z " << z << ", w = " << w0 << std::endl; | |
74 | count++; | |
75 | } | |
76 | std::cout << "points " << count << std::endl; | |
77 | ||
78 | count = 0; | |
79 | for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001) | |
80 | { | |
81 | double wm1 = lambert_wm1(z); | |
82 | wm1s[z] = wm1; | |
83 | count++; | |
84 | } | |
85 | std::cout << "points " << count << std::endl; | |
86 | ||
87 | svg_2d_plot data_plot; | |
88 | data_plot.title("Lambert W function.") | |
89 | .x_size(400) | |
90 | .y_size(300) | |
91 | .legend_on(true) | |
92 | .legend_lines(true) | |
93 | .x_label("z") | |
94 | .y_label("W") | |
95 | .x_range(-1, 3.) | |
96 | .y_range(-4., +1.) | |
97 | .x_major_interval(1.) | |
98 | .y_major_interval(1.) | |
99 | .x_major_grid_on(true) | |
100 | .y_major_grid_on(true) | |
101 | //.x_values_on(true) | |
102 | //.y_values_on(true) | |
103 | .y_values_rotation(horizontal) | |
104 | //.plot_window_on(true) | |
105 | .x_values_precision(3) | |
106 | .y_values_precision(3) | |
107 | .coord_precision(4) // Needed to avoid stepping on curves. | |
108 | .copyright_holder("Paul A. Bristow") | |
109 | .copyright_date("2018") | |
110 | //.background_border_color(black); | |
111 | ; | |
112 | data_plot.plot(w0s, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1); | |
113 | data_plot.plot(wm1s, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1); | |
114 | data_plot.write("./lambert_w_graph"); | |
115 | ||
116 | show_2d_plot_settings(data_plot); // For plot diagnosis only. | |
117 | ||
118 | } // small z Lambert W | |
119 | ||
120 | { // bigger argument z Lambert W | |
121 | ||
122 | std::map<const double, double> w0s_big; // Lambert W0 branch values for large z and W. | |
123 | std::map<const double, double> wm1s_big; // Lambert W-1 branch values for small z and large -W. | |
124 | int count = 0; | |
125 | for (double z = -0.3678794411714423215955237701614608727; z < 10000.; z += 50.) | |
126 | { | |
127 | double w0 = lambert_w0(z); | |
128 | w0s_big[z] = w0; | |
129 | count++; | |
130 | } | |
131 | std::cout << "points " << count << std::endl; | |
132 | ||
133 | count = 0; | |
134 | for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001) | |
135 | { | |
136 | double wm1 = lambert_wm1(z); | |
137 | wm1s_big[z] = wm1; | |
138 | count++; | |
139 | } | |
140 | std::cout << "Lambert W0 large z argument points = " << count << std::endl; | |
141 | ||
142 | svg_2d_plot data_plot2; | |
143 | data_plot2.title("Lambert W0 function for larger z.") | |
144 | .x_size(400) | |
145 | .y_size(300) | |
146 | .legend_on(false) | |
147 | .x_label("z") | |
148 | .y_label("W") | |
149 | //.x_label_on(true) | |
150 | //.y_label_on(true) | |
151 | //.xy_values_on(false) | |
152 | .x_range(-1, 10000.) | |
153 | .y_range(-1., +8.) | |
154 | .x_major_interval(2000.) | |
155 | .y_major_interval(1.) | |
156 | .x_major_grid_on(true) | |
157 | .y_major_grid_on(true) | |
158 | //.x_values_on(true) | |
159 | //.y_values_on(true) | |
160 | .y_values_rotation(horizontal) | |
161 | //.plot_window_on(true) | |
162 | .x_values_precision(3) | |
163 | .y_values_precision(3) | |
164 | .coord_precision(4) // Needed to avoid stepping on curves. | |
165 | .copyright_holder("Paul A. Bristow") | |
166 | .copyright_date("2018") | |
167 | //.background_border_color(black); | |
168 | ; | |
169 | ||
170 | data_plot2.plot(w0s_big, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1); | |
171 | // data_plot2.plot(wm1s_big, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1); | |
172 | // This wouldn't show anything useful. | |
173 | data_plot2.write("./lambert_w_graph_big_w"); | |
174 | } // Big argument z Lambert W | |
175 | ||
176 | { // Lambert W0 Derivative plots | |
177 | ||
178 | // std::map<const double, double> wm1ps; // Lambert W-1 prime branch values. | |
179 | std::map<const double, double> w0ps; // Lambert W0 prime branch values. | |
180 | ||
181 | std::cout.precision(std::numeric_limits<double>::max_digits10); | |
182 | ||
183 | int count = 0; | |
184 | for (double z = -0.36; z < 3.; z += 0.001) | |
185 | { | |
186 | double w0p = lambert_w0_prime(z); | |
187 | w0ps[z] = w0p; | |
188 | // std::cout << "z " << z << ", w0 = " << w0 << std::endl; | |
189 | count++; | |
190 | } | |
191 | std::cout << "points " << count << std::endl; | |
192 | ||
193 | //count = 0; | |
194 | //for (double z = -0.36; z < -0.1; z += 0.001) | |
195 | //{ | |
196 | // double wm1p = lambert_wm1_prime(z); | |
197 | // std::cout << "z " << z << ", w-1 = " << wm1p << std::endl; | |
198 | // wm1ps[z] = wm1p; | |
199 | // count++; | |
200 | //} | |
201 | //std::cout << "points " << count << std::endl; | |
202 | ||
203 | svg_2d_plot data_plotp; | |
204 | data_plotp.title("Lambert W0 prime function.") | |
205 | .x_size(400) | |
206 | .y_size(300) | |
207 | .legend_on(false) | |
208 | .x_label("z") | |
209 | .y_label("W0'") | |
210 | .x_range(-0.3, +1.) | |
211 | .y_range(0., +5.) | |
212 | .x_major_interval(0.2) | |
213 | .y_major_interval(2.) | |
214 | .x_major_grid_on(true) | |
215 | .y_major_grid_on(true) | |
216 | .y_values_rotation(horizontal) | |
217 | .x_values_precision(3) | |
218 | .y_values_precision(3) | |
219 | .coord_precision(4) // Needed to avoid stepping on curves. | |
220 | .copyright_holder("Paul A. Bristow") | |
221 | .copyright_date("2018") | |
222 | ; | |
223 | ||
224 | // derivative of N[productlog(0, x), 55] at x=0 to 10 | |
225 | // Plot[D[N[ProductLog[0, x], 55], x], {x, 0, 10}] | |
226 | // Plot[ProductLog[x]/(x + x ProductLog[x]), {x, 0, 10}] | |
227 | data_plotp.plot(w0ps, "W0 prime branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1); | |
228 | data_plotp.write("./lambert_w0_prime_graph"); | |
229 | } // Lambert W0 Derivative plots | |
230 | ||
231 | { // Lambert Wm1 Derivative plots | |
232 | ||
233 | std::map<const double, double> wm1ps; // Lambert W-1 prime branch values. | |
234 | ||
235 | std::cout.precision(std::numeric_limits<double>::max_digits10); | |
236 | ||
237 | int count = 0; | |
238 | for (double z = -0.3678; z < -0.00001; z += 0.001) | |
239 | { | |
240 | double wm1p = lambert_wm1_prime(z); | |
241 | // std::cout << "z " << z << ", w-1 = " << wm1p << std::endl; | |
242 | wm1ps[z] = wm1p; | |
243 | count++; | |
244 | } | |
245 | std::cout << "Lambert W-1 prime points = " << count << std::endl; | |
246 | ||
247 | svg_2d_plot data_plotp; | |
248 | data_plotp.title("Lambert W-1 prime function.") | |
249 | .x_size(400) | |
250 | .y_size(300) | |
251 | .legend_on(false) | |
252 | .x_label("z") | |
253 | .y_label("W-1'") | |
254 | .x_range(-0.4, +0.01) | |
255 | .x_major_interval(0.1) | |
256 | .y_range(-20., -5.) | |
257 | .y_major_interval(5.) | |
258 | .x_major_grid_on(true) | |
259 | .y_major_grid_on(true) | |
260 | .y_values_rotation(horizontal) | |
261 | .x_values_precision(3) | |
262 | .y_values_precision(3) | |
263 | .coord_precision(4) // Needed to avoid stepping on curves. | |
264 | .copyright_holder("Paul A. Bristow") | |
265 | .copyright_date("2018") | |
266 | ; | |
267 | ||
268 | // derivative of N[productlog(0, x), 55] at x=0 to 10 | |
269 | // Plot[D[N[ProductLog[0, x], 55], x], {x, 0, 10}] | |
270 | // Plot[ProductLog[x]/(x + x ProductLog[x]), {x, 0, 10}] | |
271 | data_plotp.plot(wm1ps, "W-1 prime branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1); | |
272 | data_plotp.write("./lambert_wm1_prime_graph"); | |
273 | } // Lambert W-1 prime graph | |
274 | } // try | |
275 | catch (std::exception& ex) | |
276 | { | |
277 | std::cout << ex.what() << std::endl; | |
278 | } | |
279 | } // int main() | |
280 | ||
281 | /* | |
282 | ||
283 | //[lambert_w_graph_1_output | |
284 | ||
285 | //] [/lambert_w_graph_1_output] | |
286 | */ |