dist_graphs.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /*! \file dist_graphs.cpp
  2. \brief Produces Scalable Vector Graphic (.svg) files for all distributions.
  3. \details These files can be viewed using most browsers,
  4. though MS Internet Explorer requires a plugin from Adobe.
  5. These file can be converted to .png using Inkscape
  6. (see www.inkscape.org) Export Bit option which by default produces
  7. a Portable Network Graphic file with that same filename but .png suffix instead of .svg.
  8. Using Python, generate.sh does this conversion automatically for all .svg files in a folder.
  9. \author John Maddock and Paul A. Bristow
  10. */
  11. // Copyright John Maddock 2008.
  12. // Copyright Paul A. Bristow 2008, 2009, 2012, 2016
  13. // Use, modification and distribution are subject to the
  14. // Boost Software License, Version 1.0. (See accompanying file
  15. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  16. #ifdef _MSC_VER
  17. # pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
  18. # pragma warning (disable : 4503) // decorated name length exceeded, name was truncated
  19. # pragma warning (disable : 4512) // assignment operator could not be generated
  20. # pragma warning (disable : 4224) // nonstandard extension used : formal parameter 'function_ptr' was previously defined as a type
  21. # pragma warning (disable : 4127) // conditional expression is constant
  22. #endif
  23. #define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
  24. #include <boost/math/distributions.hpp>
  25. #include <boost/math/tools/roots.hpp>
  26. #include <boost/svg_plot/svg_2d_plot.hpp>
  27. #include <list>
  28. #include <map>
  29. #include <string>
  30. template <class Dist>
  31. struct is_discrete_distribution
  32. : public boost::mpl::false_{}; // Default is continuous distribution.
  33. // Some discrete distributions.
  34. template<class T, class P>
  35. struct is_discrete_distribution<boost::math::bernoulli_distribution<T,P> >
  36. : public boost::mpl::true_{};
  37. template<class T, class P>
  38. struct is_discrete_distribution<boost::math::binomial_distribution<T,P> >
  39. : public boost::mpl::true_{};
  40. template<class T, class P>
  41. struct is_discrete_distribution<boost::math::negative_binomial_distribution<T,P> >
  42. : public boost::mpl::true_{};
  43. template<class T, class P>
  44. struct is_discrete_distribution<boost::math::poisson_distribution<T,P> >
  45. : public boost::mpl::true_{};
  46. template<class T, class P>
  47. struct is_discrete_distribution<boost::math::hypergeometric_distribution<T,P> >
  48. : public boost::mpl::true_{};
  49. template <class Dist>
  50. struct value_finder
  51. {
  52. value_finder(Dist const& d, typename Dist::value_type v)
  53. : m_dist(d), m_value(v) {}
  54. inline typename Dist::value_type operator()(const typename Dist::value_type& x)
  55. {
  56. return pdf(m_dist, x) - m_value;
  57. }
  58. private:
  59. Dist m_dist;
  60. typename Dist::value_type m_value;
  61. }; // value_finder
  62. template <class Dist>
  63. class distribution_plotter
  64. {
  65. public:
  66. distribution_plotter() : m_pdf(true), m_min_x(0), m_max_x(0), m_min_y(0), m_max_y(0) {}
  67. distribution_plotter(bool pdf) : m_pdf(pdf), m_min_x(0), m_max_x(0), m_min_y(0), m_max_y(0) {}
  68. void add(const Dist& d, const std::string& name)
  69. {
  70. // Add name of distribution to our list for later:
  71. m_distributions.push_back(std::make_pair(name, d));
  72. //
  73. // Get the extent of the distribution from the support:
  74. double a, b;
  75. std::tr1::tie(a, b) = support(d);
  76. //
  77. // PDF maximimum is at the mode (probably):
  78. double mod;
  79. try
  80. {
  81. mod = mode(d);
  82. }
  83. catch(const std::domain_error& )
  84. { // but if not use the lower limit of support.
  85. mod = a;
  86. }
  87. if((mod <= a) && !is_discrete_distribution<Dist>::value)
  88. { // Continuous distribution at or below lower limit of support.
  89. double margin = 1e-2; // Margin of 1% (say) to get lowest off the 'end stop'.
  90. if((a != 0) && (fabs(a) > margin))
  91. {
  92. mod = a * (1 + ((a > 0) ? margin : -margin));
  93. }
  94. else
  95. { // Case of mod near zero?
  96. mod = margin;
  97. }
  98. }
  99. double peek_y = pdf(d, mod);
  100. double min_y = peek_y / 20;
  101. //
  102. // If the extent is "infinite" then find out how large it
  103. // has to be for the PDF to decay to min_y:
  104. //
  105. if(a <= -(std::numeric_limits<double>::max)())
  106. {
  107. boost::uintmax_t max_iter = 500;
  108. double guess = mod;
  109. if((pdf(d, 0) > min_y) || (guess == 0))
  110. guess = -1e-3;
  111. a = boost::math::tools::bracket_and_solve_root(
  112. value_finder<Dist>(d, min_y),
  113. guess,
  114. 8.0,
  115. true,
  116. boost::math::tools::eps_tolerance<double>(10),
  117. max_iter).first;
  118. }
  119. if(b >= (std::numeric_limits<double>::max)())
  120. {
  121. boost::uintmax_t max_iter = 500;
  122. double guess = mod;
  123. if(a <= 0)
  124. if((pdf(d, 0) > min_y) || (guess == 0))
  125. guess = 1e-3;
  126. b = boost::math::tools::bracket_and_solve_root(
  127. value_finder<Dist>(d, min_y),
  128. guess,
  129. 8.0,
  130. false,
  131. boost::math::tools::eps_tolerance<double>(10),
  132. max_iter).first;
  133. }
  134. //
  135. // Recalculate peek_y and location of mod so that
  136. // it's not too close to one end of the graph:
  137. // otherwise we may be shooting off to infinity.
  138. //
  139. if(!is_discrete_distribution<Dist>::value)
  140. {
  141. if(mod <= a + (b-a)/50)
  142. {
  143. mod = a + (b-a)/50;
  144. }
  145. if(mod >= b - (b-a)/50)
  146. {
  147. mod = b - (b-a)/50;
  148. }
  149. peek_y = pdf(d, mod);
  150. }
  151. //
  152. // Now set our limits:
  153. //
  154. if(peek_y > m_max_y)
  155. m_max_y = peek_y;
  156. if(m_max_x == m_min_x)
  157. {
  158. m_max_x = b;
  159. m_min_x = a;
  160. }
  161. else
  162. {
  163. if(a < m_min_x)
  164. m_min_x = a;
  165. if(b > m_max_x)
  166. m_max_x = b;
  167. }
  168. } // add
  169. void plot(const std::string& title, const std::string& file)
  170. {
  171. using namespace boost::svg;
  172. static const svg_color colors[5] =
  173. {
  174. darkblue,
  175. darkred,
  176. darkgreen,
  177. darkorange,
  178. chartreuse
  179. };
  180. if(m_pdf == false)
  181. {
  182. m_min_y = 0;
  183. m_max_y = 1;
  184. }
  185. std::cout << "Plotting " << title << " to " << file << std::endl;
  186. svg_2d_plot plot;
  187. plot.image_x_size(750);
  188. plot.image_y_size(400);
  189. plot.copyright_holder("John Maddock").copyright_date("2008").boost_license_on(true);
  190. plot.coord_precision(4); // Avoids any visible steps.
  191. plot.title_font_size(20);
  192. plot.legend_title_font_size(15);
  193. plot.title(title);
  194. if((m_distributions.size() == 1) && (m_distributions.begin()->first == ""))
  195. plot.legend_on(false);
  196. else
  197. plot.legend_on(true);
  198. plot.title_on(true);
  199. //plot.x_major_labels_on(true).y_major_labels_on(true);
  200. //double x_delta = (m_max_x - m_min_x) / 10;
  201. double y_delta = (m_max_y - m_min_y) / 10;
  202. if(is_discrete_distribution<Dist>::value)
  203. plot.x_range(m_min_x - 0.5, m_max_x + 0.5)
  204. .y_range(m_min_y, m_max_y + y_delta);
  205. else
  206. plot.x_range(m_min_x, m_max_x)
  207. .y_range(m_min_y, m_max_y + y_delta);
  208. plot.x_label_on(true).x_label("Random Variable");
  209. plot.y_label_on(true).y_label("Probability");
  210. plot.plot_border_color(lightslategray)
  211. .background_border_color(lightslategray)
  212. .legend_border_color(lightslategray)
  213. .legend_background_color(white);
  214. //
  215. // Work out axis tick intervals:
  216. //
  217. double l = std::floor(std::log10((m_max_x - m_min_x) / 10) + 0.5);
  218. double interval = std::pow(10.0, (int)l);
  219. if(((m_max_x - m_min_x) / interval) > 10)
  220. interval *= 5;
  221. if(is_discrete_distribution<Dist>::value)
  222. {
  223. interval = interval > 1 ? std::floor(interval) : 1;
  224. plot.x_num_minor_ticks(0);
  225. }
  226. plot.x_major_interval(interval);
  227. l = std::floor(std::log10((m_max_y - m_min_y) / 10) + 0.5);
  228. interval = std::pow(10.0, (int)l);
  229. if(((m_max_y - m_min_y) / interval) > 10)
  230. interval *= 5;
  231. plot.y_major_interval(interval);
  232. int color_index = 0;
  233. if(!is_discrete_distribution<Dist>::value)
  234. {
  235. // Continuous distribution:
  236. for(std::list<std::pair<std::string, Dist> >::const_iterator i = m_distributions.begin();
  237. i != m_distributions.end(); ++i)
  238. {
  239. double x = m_min_x;
  240. double continuous_interval = (m_max_x - m_min_x) / 200;
  241. std::map<double, double> data;
  242. while(x <= m_max_x)
  243. {
  244. data[x] = m_pdf ? pdf(i->second, x) : cdf(i->second, x);
  245. x += continuous_interval;
  246. }
  247. plot.plot(data, i->first)
  248. .line_on(true)
  249. .line_color(colors[color_index])
  250. .line_width(1.)
  251. .shape(none);
  252. //.bezier_on(true) // Bezier can't cope with badly behaved like uniform & triangular.
  253. ++color_index;
  254. color_index = color_index % (sizeof(colors)/sizeof(colors[0]));
  255. }
  256. }
  257. else
  258. {
  259. // Discrete distribution:
  260. double x_width = 0.75 / m_distributions.size();
  261. double x_off = -0.5 * 0.75;
  262. for(std::list<std::pair<std::string, Dist> >::const_iterator i = m_distributions.begin();
  263. i != m_distributions.end(); ++i)
  264. {
  265. double x = ceil(m_min_x);
  266. double discrete_interval = 1;
  267. std::map<double, double> data;
  268. while(x <= m_max_x)
  269. {
  270. double p;
  271. try{
  272. p = m_pdf ? pdf(i->second, x) : cdf(i->second, x);
  273. }
  274. catch(const std::domain_error&)
  275. {
  276. p = 0;
  277. }
  278. data[x + x_off] = 0;
  279. data[x + x_off + 0.00001] = p;
  280. data[x + x_off + x_width] = p;
  281. data[x + x_off + x_width + 0.00001] = 0;
  282. x += discrete_interval;
  283. }
  284. x_off += x_width;
  285. svg_2d_plot_series& s = plot.plot(data, i->first);
  286. s.line_on(true)
  287. .line_color(colors[color_index])
  288. .line_width(1.)
  289. .shape(none)
  290. .area_fill(colors[color_index]);
  291. ++color_index;
  292. color_index = color_index % (sizeof(colors)/sizeof(colors[0]));
  293. }
  294. } // descrete
  295. plot.write(file);
  296. } // void plot(const std::string& title, const std::string& file)
  297. private:
  298. bool m_pdf;
  299. std::list<std::pair<std::string, Dist> > m_distributions;
  300. double m_min_x, m_max_x, m_min_y, m_max_y;
  301. };
  302. int main()
  303. {
  304. try
  305. {
  306. std::cout << "Distribution Graphs" << std::endl;
  307. distribution_plotter<boost::math::gamma_distribution<> >
  308. gamma_plotter;
  309. gamma_plotter.add(boost::math::gamma_distribution<>(0.75), "shape = 0.75");
  310. gamma_plotter.add(boost::math::gamma_distribution<>(1), "shape = 1");
  311. gamma_plotter.add(boost::math::gamma_distribution<>(3), "shape = 3");
  312. gamma_plotter.plot("Gamma Distribution PDF With Scale = 1", "gamma1_pdf.svg");
  313. distribution_plotter<boost::math::gamma_distribution<> >
  314. gamma_plotter2;
  315. gamma_plotter2.add(boost::math::gamma_distribution<>(2, 0.5), "scale = 0.5");
  316. gamma_plotter2.add(boost::math::gamma_distribution<>(2, 1), "scale = 1");
  317. gamma_plotter2.add(boost::math::gamma_distribution<>(2, 2), "scale = 2");
  318. gamma_plotter2.plot("Gamma Distribution PDF With Shape = 2", "gamma2_pdf.svg");
  319. distribution_plotter<boost::math::normal>
  320. normal_plotter;
  321. normal_plotter.add(boost::math::normal(0, 1), "&#x3BC; = 0, &#x3C3; = 1");
  322. normal_plotter.add(boost::math::normal(0, 0.5), "&#x3BC; = 0, &#x3C3; = 0.5");
  323. normal_plotter.add(boost::math::normal(0, 2), "&#x3BC; = 0, &#x3C3; = 2");
  324. normal_plotter.add(boost::math::normal(-1, 1), "&#x3BC; = -1, &#x3C3; = 1");
  325. normal_plotter.add(boost::math::normal(1, 1), "&#x3BC; = 1, &#x3C3; = 1");
  326. normal_plotter.plot("Normal Distribution PDF", "normal_pdf.svg");
  327. distribution_plotter<boost::math::laplace>
  328. laplace_plotter;
  329. laplace_plotter.add(boost::math::laplace(0, 1), "&#x3BC; = 0, &#x3C3; = 1");
  330. laplace_plotter.add(boost::math::laplace(0, 0.5), "&#x3BC; = 0, &#x3C3; = 0.5");
  331. laplace_plotter.add(boost::math::laplace(0, 2), "&#x3BC; = 0, &#x3C3; = 2");
  332. laplace_plotter.add(boost::math::laplace(-1, 1), "&#x3BC; = -1, &#x3C3; = 1");
  333. laplace_plotter.add(boost::math::laplace(1, 1), "&#x3BC; = 1, &#x3C3; = 1");
  334. laplace_plotter.plot("Laplace Distribution PDF", "laplace_pdf.svg");
  335. distribution_plotter<boost::math::non_central_chi_squared>
  336. nc_cs_plotter;
  337. nc_cs_plotter.add(boost::math::non_central_chi_squared(20, 0), "v=20, &#x3BB;=0");
  338. nc_cs_plotter.add(boost::math::non_central_chi_squared(20, 1), "v=20, &#x3BB;=1");
  339. nc_cs_plotter.add(boost::math::non_central_chi_squared(20, 5), "v=20, &#x3BB;=5");
  340. nc_cs_plotter.add(boost::math::non_central_chi_squared(20, 10), "v=20, &#x3BB;=10");
  341. nc_cs_plotter.add(boost::math::non_central_chi_squared(20, 20), "v=20, &#x3BB;=20");
  342. nc_cs_plotter.add(boost::math::non_central_chi_squared(20, 100), "v=20, &#x3BB;=100");
  343. nc_cs_plotter.plot("Non Central Chi Squared PDF", "nccs_pdf.svg");
  344. distribution_plotter<boost::math::non_central_beta>
  345. nc_beta_plotter;
  346. nc_beta_plotter.add(boost::math::non_central_beta(10, 15, 0), "&#x3B1;=10, &#x3B2;=15, &#x3B4;=0");
  347. nc_beta_plotter.add(boost::math::non_central_beta(10, 15, 1), "&#x3B1;=10, &#x3B2;=15, &#x3B4;=1");
  348. nc_beta_plotter.add(boost::math::non_central_beta(10, 15, 5), "&#x3B1;=10, &#x3B2;=15, &#x3B4;=5");
  349. nc_beta_plotter.add(boost::math::non_central_beta(10, 15, 10), "&#x3B1;=10, &#x3B2;=15, &#x3B4;=10");
  350. nc_beta_plotter.add(boost::math::non_central_beta(10, 15, 40), "&#x3B1;=10, &#x3B2;=15, &#x3B4;=40");
  351. nc_beta_plotter.add(boost::math::non_central_beta(10, 15, 100), "&#x3B1;=10, &#x3B2;=15, &#x3B4;=100");
  352. nc_beta_plotter.plot("Non Central Beta PDF", "nc_beta_pdf.svg");
  353. distribution_plotter<boost::math::non_central_f>
  354. nc_f_plotter;
  355. nc_f_plotter.add(boost::math::non_central_f(10, 20, 0), "v1=10, v2=20, &#x3BB;=0");
  356. nc_f_plotter.add(boost::math::non_central_f(10, 20, 1), "v1=10, v2=20, &#x3BB;=1");
  357. nc_f_plotter.add(boost::math::non_central_f(10, 20, 5), "v1=10, v2=20, &#x3BB;=5");
  358. nc_f_plotter.add(boost::math::non_central_f(10, 20, 10), "v1=10, v2=20, &#x3BB;=10");
  359. nc_f_plotter.add(boost::math::non_central_f(10, 20, 40), "v1=10, v2=20, &#x3BB;=40");
  360. nc_f_plotter.add(boost::math::non_central_f(10, 20, 100), "v1=10, v2=20, &#x3BB;=100");
  361. nc_f_plotter.plot("Non Central F PDF", "nc_f_pdf.svg");
  362. distribution_plotter<boost::math::non_central_t>
  363. nc_t_plotter;
  364. nc_t_plotter.add(boost::math::non_central_t(10, -10), "v=10, &#x3B4;=-10");
  365. nc_t_plotter.add(boost::math::non_central_t(10, -5), "v=10, &#x3B4;=-5");
  366. nc_t_plotter.add(boost::math::non_central_t(10, 0), "v=10, &#x3B4;=0");
  367. nc_t_plotter.add(boost::math::non_central_t(10, 5), "v=10, &#x3B4;=5");
  368. nc_t_plotter.add(boost::math::non_central_t(10, 10), "v=10, &#x3B4;=10");
  369. nc_t_plotter.add(boost::math::non_central_t(std::numeric_limits<double>::infinity(), 15), "v=inf, &#x3B4;=15");
  370. nc_t_plotter.plot("Non Central T PDF", "nc_t_pdf.svg");
  371. distribution_plotter<boost::math::non_central_t>
  372. nc_t_CDF_plotter(false);
  373. nc_t_CDF_plotter.add(boost::math::non_central_t(10, -10), "v=10, &#x3B4;=-10");
  374. nc_t_CDF_plotter.add(boost::math::non_central_t(10, -5), "v=10, &#x3B4;=-5");
  375. nc_t_CDF_plotter.add(boost::math::non_central_t(10, 0), "v=10, &#x3B4;=0");
  376. nc_t_CDF_plotter.add(boost::math::non_central_t(10, 5), "v=10, &#x3B4;=5");
  377. nc_t_CDF_plotter.add(boost::math::non_central_t(10, 10), "v=10, &#x3B4;=10");
  378. nc_t_CDF_plotter.add(boost::math::non_central_t(std::numeric_limits<double>::infinity(), 15), "v=inf, &#x3B4;=15");
  379. nc_t_CDF_plotter.plot("Non Central T CDF", "nc_t_cdf.svg");
  380. distribution_plotter<boost::math::beta_distribution<> >
  381. beta_plotter;
  382. beta_plotter.add(boost::math::beta_distribution<>(0.5, 0.5), "alpha=0.5, beta=0.5");
  383. beta_plotter.add(boost::math::beta_distribution<>(5, 1), "alpha=5, beta=1");
  384. beta_plotter.add(boost::math::beta_distribution<>(1, 3), "alpha=1, beta=3");
  385. beta_plotter.add(boost::math::beta_distribution<>(2, 2), "alpha=2, beta=2");
  386. beta_plotter.add(boost::math::beta_distribution<>(2, 5), "alpha=2, beta=5");
  387. beta_plotter.plot("Beta Distribution PDF", "beta_pdf.svg");
  388. distribution_plotter<boost::math::cauchy_distribution<> >
  389. cauchy_plotter;
  390. cauchy_plotter.add(boost::math::cauchy_distribution<>(-5, 1), "location = -5");
  391. cauchy_plotter.add(boost::math::cauchy_distribution<>(0, 1), "location = 0");
  392. cauchy_plotter.add(boost::math::cauchy_distribution<>(5, 1), "location = 5");
  393. cauchy_plotter.plot("Cauchy Distribution PDF (scale = 1)", "cauchy_pdf1.svg");
  394. distribution_plotter<boost::math::cauchy_distribution<> >
  395. cauchy_plotter2;
  396. cauchy_plotter2.add(boost::math::cauchy_distribution<>(0, 0.5), "scale = 0.5");
  397. cauchy_plotter2.add(boost::math::cauchy_distribution<>(0, 1), "scale = 1");
  398. cauchy_plotter2.add(boost::math::cauchy_distribution<>(0, 2), "scale = 2");
  399. cauchy_plotter2.plot("Cauchy Distribution PDF (location = 0)", "cauchy_pdf2.svg");
  400. distribution_plotter<boost::math::chi_squared_distribution<> >
  401. chi_squared_plotter;
  402. //chi_squared_plotter.add(boost::math::chi_squared_distribution<>(1), "v=1");
  403. chi_squared_plotter.add(boost::math::chi_squared_distribution<>(2), "v=2");
  404. chi_squared_plotter.add(boost::math::chi_squared_distribution<>(5), "v=5");
  405. chi_squared_plotter.add(boost::math::chi_squared_distribution<>(10), "v=10");
  406. chi_squared_plotter.plot("Chi Squared Distribution PDF", "chi_squared_pdf.svg");
  407. distribution_plotter<boost::math::exponential_distribution<> >
  408. exponential_plotter;
  409. exponential_plotter.add(boost::math::exponential_distribution<>(0.5), "&#x3BB;=0.5");
  410. exponential_plotter.add(boost::math::exponential_distribution<>(1), "&#x3BB;=1");
  411. exponential_plotter.add(boost::math::exponential_distribution<>(2), "&#x3BB;=2");
  412. exponential_plotter.plot("Exponential Distribution PDF", "exponential_pdf.svg");
  413. distribution_plotter<boost::math::extreme_value_distribution<> >
  414. extreme_value_plotter;
  415. extreme_value_plotter.add(boost::math::extreme_value_distribution<>(-5), "location=-5");
  416. extreme_value_plotter.add(boost::math::extreme_value_distribution<>(0), "location=0");
  417. extreme_value_plotter.add(boost::math::extreme_value_distribution<>(5), "location=5");
  418. extreme_value_plotter.plot("Extreme Value Distribution PDF (shape=1)", "extreme_value_pdf1.svg");
  419. distribution_plotter<boost::math::extreme_value_distribution<> >
  420. extreme_value_plotter2;
  421. extreme_value_plotter2.add(boost::math::extreme_value_distribution<>(0, 0.5), "shape=0.5");
  422. extreme_value_plotter2.add(boost::math::extreme_value_distribution<>(0, 1), "shape=1");
  423. extreme_value_plotter2.add(boost::math::extreme_value_distribution<>(0, 2), "shape=2");
  424. extreme_value_plotter2.plot("Extreme Value Distribution PDF (location=0)", "extreme_value_pdf2.svg");
  425. distribution_plotter<boost::math::fisher_f_distribution<> >
  426. fisher_f_plotter;
  427. fisher_f_plotter.add(boost::math::fisher_f_distribution<>(4, 4), "n=4, m=4");
  428. fisher_f_plotter.add(boost::math::fisher_f_distribution<>(10, 4), "n=10, m=4");
  429. fisher_f_plotter.add(boost::math::fisher_f_distribution<>(10, 10), "n=10, m=10");
  430. fisher_f_plotter.add(boost::math::fisher_f_distribution<>(4, 10), "n=4, m=10");
  431. fisher_f_plotter.plot("F Distribution PDF", "fisher_f_pdf.svg");
  432. distribution_plotter<boost::math::lognormal_distribution<> >
  433. lognormal_plotter;
  434. lognormal_plotter.add(boost::math::lognormal_distribution<>(-1), "location=-1");
  435. lognormal_plotter.add(boost::math::lognormal_distribution<>(0), "location=0");
  436. lognormal_plotter.add(boost::math::lognormal_distribution<>(1), "location=1");
  437. lognormal_plotter.plot("Lognormal Distribution PDF (scale=1)", "lognormal_pdf1.svg");
  438. distribution_plotter<boost::math::lognormal_distribution<> >
  439. lognormal_plotter2;
  440. lognormal_plotter2.add(boost::math::lognormal_distribution<>(0, 0.5), "scale=0.5");
  441. lognormal_plotter2.add(boost::math::lognormal_distribution<>(0, 1), "scale=1");
  442. lognormal_plotter2.add(boost::math::lognormal_distribution<>(0, 2), "scale=2");
  443. lognormal_plotter2.plot("Lognormal Distribution PDF (location=0)", "lognormal_pdf2.svg");
  444. distribution_plotter<boost::math::pareto_distribution<> >
  445. pareto_plotter; // Rely on 2nd parameter shape = 1 default.
  446. pareto_plotter.add(boost::math::pareto_distribution<>(1), "scale=1");
  447. pareto_plotter.add(boost::math::pareto_distribution<>(2), "scale=2");
  448. pareto_plotter.add(boost::math::pareto_distribution<>(3), "scale=3");
  449. pareto_plotter.plot("Pareto Distribution PDF (shape=1)", "pareto_pdf1.svg");
  450. distribution_plotter<boost::math::pareto_distribution<> >
  451. pareto_plotter2;
  452. pareto_plotter2.add(boost::math::pareto_distribution<>(1, 0.5), "shape=0.5");
  453. pareto_plotter2.add(boost::math::pareto_distribution<>(1, 1), "shape=1");
  454. pareto_plotter2.add(boost::math::pareto_distribution<>(1, 2), "shape=2");
  455. pareto_plotter2.plot("Pareto Distribution PDF (scale=1)", "pareto_pdf2.svg");
  456. distribution_plotter<boost::math::rayleigh_distribution<> >
  457. rayleigh_plotter;
  458. rayleigh_plotter.add(boost::math::rayleigh_distribution<>(0.5), "&#x3C3;=0.5");
  459. rayleigh_plotter.add(boost::math::rayleigh_distribution<>(1), "&#x3C3;=1");
  460. rayleigh_plotter.add(boost::math::rayleigh_distribution<>(2), "&#x3C3;=2");
  461. rayleigh_plotter.add(boost::math::rayleigh_distribution<>(4), "&#x3C3;=4");
  462. rayleigh_plotter.add(boost::math::rayleigh_distribution<>(10), "&#x3C3;=10");
  463. rayleigh_plotter.plot("Rayleigh Distribution PDF", "rayleigh_pdf.svg");
  464. distribution_plotter<boost::math::rayleigh_distribution<> >
  465. rayleigh_cdf_plotter(false);
  466. rayleigh_cdf_plotter.add(boost::math::rayleigh_distribution<>(0.5), "&#x3C3;=0.5");
  467. rayleigh_cdf_plotter.add(boost::math::rayleigh_distribution<>(1), "&#x3C3;=1");
  468. rayleigh_cdf_plotter.add(boost::math::rayleigh_distribution<>(2), "&#x3C3;=2");
  469. rayleigh_cdf_plotter.add(boost::math::rayleigh_distribution<>(4), "&#x3C3;=4");
  470. rayleigh_cdf_plotter.add(boost::math::rayleigh_distribution<>(10), "&#x3C3;=10");
  471. rayleigh_cdf_plotter.plot("Rayleigh Distribution CDF", "rayleigh_cdf.svg");
  472. distribution_plotter<boost::math::skew_normal_distribution<> >
  473. skew_normal_plotter;
  474. skew_normal_plotter.add(boost::math::skew_normal_distribution<>(0,1,0), "{0,1,0}");
  475. skew_normal_plotter.add(boost::math::skew_normal_distribution<>(0,1,1), "{0,1,1}");
  476. skew_normal_plotter.add(boost::math::skew_normal_distribution<>(0,1,4), "{0,1,4}");
  477. skew_normal_plotter.add(boost::math::skew_normal_distribution<>(0,1,20), "{0,1,20}");
  478. skew_normal_plotter.add(boost::math::skew_normal_distribution<>(0,1,-2), "{0,1,-2}");
  479. skew_normal_plotter.add(boost::math::skew_normal_distribution<>(-2,0.5,-1), "{-2,0.5,-1}");
  480. skew_normal_plotter.plot("Skew Normal Distribution PDF", "skew_normal_pdf.svg");
  481. distribution_plotter<boost::math::skew_normal_distribution<> >
  482. skew_normal_cdf_plotter(false);
  483. skew_normal_cdf_plotter.add(boost::math::skew_normal_distribution<>(0,1,0), "{0,1,0}");
  484. skew_normal_cdf_plotter.add(boost::math::skew_normal_distribution<>(0,1,1), "{0,1,1}");
  485. skew_normal_cdf_plotter.add(boost::math::skew_normal_distribution<>(0,1,4), "{0,1,4}");
  486. skew_normal_cdf_plotter.add(boost::math::skew_normal_distribution<>(0,1,20), "{0,1,20}");
  487. skew_normal_cdf_plotter.add(boost::math::skew_normal_distribution<>(0,1,-2), "{0,1,-2}");
  488. skew_normal_cdf_plotter.add(boost::math::skew_normal_distribution<>(-2,0.5,-1), "{-2,0.5,-1}");
  489. skew_normal_cdf_plotter.plot("Skew Normal Distribution CDF", "skew_normal_cdf.svg");
  490. distribution_plotter<boost::math::triangular_distribution<> >
  491. triangular_plotter;
  492. triangular_plotter.add(boost::math::triangular_distribution<>(-1,0,1), "{-1,0,1}");
  493. triangular_plotter.add(boost::math::triangular_distribution<>(0,1,1), "{0,1,1}");
  494. triangular_plotter.add(boost::math::triangular_distribution<>(0,1,3), "{0,1,3}");
  495. triangular_plotter.add(boost::math::triangular_distribution<>(0,0.5,1), "{0,0.5,1}");
  496. triangular_plotter.add(boost::math::triangular_distribution<>(-2,0,3), "{-2,0,3}");
  497. triangular_plotter.plot("Triangular Distribution PDF", "triangular_pdf.svg");
  498. distribution_plotter<boost::math::triangular_distribution<> >
  499. triangular_cdf_plotter(false);
  500. triangular_cdf_plotter.add(boost::math::triangular_distribution<>(-1,0,1), "{-1,0,1}");
  501. triangular_cdf_plotter.add(boost::math::triangular_distribution<>(0,1,1), "{0,1,1}");
  502. triangular_cdf_plotter.add(boost::math::triangular_distribution<>(0,1,3), "{0,1,3}");
  503. triangular_cdf_plotter.add(boost::math::triangular_distribution<>(0,0.5,1), "{0,0.5,1}");
  504. triangular_cdf_plotter.add(boost::math::triangular_distribution<>(-2,0,3), "{-2,0,3}");
  505. triangular_cdf_plotter.plot("Triangular Distribution CDF", "triangular_cdf.svg");
  506. distribution_plotter<boost::math::students_t_distribution<> >
  507. students_t_plotter;
  508. students_t_plotter.add(boost::math::students_t_distribution<>(1), "v=1");
  509. students_t_plotter.add(boost::math::students_t_distribution<>(5), "v=5");
  510. students_t_plotter.add(boost::math::students_t_distribution<>(30), "v=30");
  511. students_t_plotter.plot("Students T Distribution PDF", "students_t_pdf.svg");
  512. distribution_plotter<boost::math::weibull_distribution<> >
  513. weibull_plotter;
  514. weibull_plotter.add(boost::math::weibull_distribution<>(0.75), "shape=0.75");
  515. weibull_plotter.add(boost::math::weibull_distribution<>(1), "shape=1");
  516. weibull_plotter.add(boost::math::weibull_distribution<>(5), "shape=5");
  517. weibull_plotter.add(boost::math::weibull_distribution<>(10), "shape=10");
  518. weibull_plotter.plot("Weibull Distribution PDF (scale=1)", "weibull_pdf1.svg");
  519. distribution_plotter<boost::math::weibull_distribution<> >
  520. weibull_plotter2;
  521. weibull_plotter2.add(boost::math::weibull_distribution<>(3, 0.5), "scale=0.5");
  522. weibull_plotter2.add(boost::math::weibull_distribution<>(3, 1), "scale=1");
  523. weibull_plotter2.add(boost::math::weibull_distribution<>(3, 2), "scale=2");
  524. weibull_plotter2.plot("Weibull Distribution PDF (shape=3)", "weibull_pdf2.svg");
  525. distribution_plotter<boost::math::uniform_distribution<> >
  526. uniform_plotter;
  527. uniform_plotter.add(boost::math::uniform_distribution<>(0, 1), "{0,1}");
  528. uniform_plotter.add(boost::math::uniform_distribution<>(0, 3), "{0,3}");
  529. uniform_plotter.add(boost::math::uniform_distribution<>(-2, 3), "{-2,3}");
  530. uniform_plotter.add(boost::math::uniform_distribution<>(-1, 1), "{-1,1}");
  531. uniform_plotter.plot("Uniform Distribution PDF", "uniform_pdf.svg");
  532. distribution_plotter<boost::math::uniform_distribution<> >
  533. uniform_cdf_plotter(false);
  534. uniform_cdf_plotter.add(boost::math::uniform_distribution<>(0, 1), "{0,1}");
  535. uniform_cdf_plotter.add(boost::math::uniform_distribution<>(0, 3), "{0,3}");
  536. uniform_cdf_plotter.add(boost::math::uniform_distribution<>(-2, 3), "{-2,3}");
  537. uniform_cdf_plotter.add(boost::math::uniform_distribution<>(-1, 1), "{-1,1}");
  538. uniform_cdf_plotter.plot("Uniform Distribution CDF", "uniform_cdf.svg");
  539. distribution_plotter<boost::math::bernoulli_distribution<> >
  540. bernoulli_plotter;
  541. bernoulli_plotter.add(boost::math::bernoulli_distribution<>(0.25), "p=0.25");
  542. bernoulli_plotter.add(boost::math::bernoulli_distribution<>(0.5), "p=0.5");
  543. bernoulli_plotter.add(boost::math::bernoulli_distribution<>(0.75), "p=0.75");
  544. bernoulli_plotter.plot("Bernoulli Distribution PDF", "bernoulli_pdf.svg");
  545. distribution_plotter<boost::math::bernoulli_distribution<> >
  546. bernoulli_cdf_plotter(false);
  547. bernoulli_cdf_plotter.add(boost::math::bernoulli_distribution<>(0.25), "p=0.25");
  548. bernoulli_cdf_plotter.add(boost::math::bernoulli_distribution<>(0.5), "p=0.5");
  549. bernoulli_cdf_plotter.add(boost::math::bernoulli_distribution<>(0.75), "p=0.75");
  550. bernoulli_cdf_plotter.plot("Bernoulli Distribution CDF", "bernoulli_cdf.svg");
  551. distribution_plotter<boost::math::binomial_distribution<> >
  552. binomial_plotter;
  553. binomial_plotter.add(boost::math::binomial_distribution<>(5, 0.5), "n=5 p=0.5");
  554. binomial_plotter.add(boost::math::binomial_distribution<>(20, 0.5), "n=20 p=0.5");
  555. binomial_plotter.add(boost::math::binomial_distribution<>(50, 0.5), "n=50 p=0.5");
  556. binomial_plotter.plot("Binomial Distribution PDF", "binomial_pdf_1.svg");
  557. distribution_plotter<boost::math::binomial_distribution<> >
  558. binomial_plotter2;
  559. binomial_plotter2.add(boost::math::binomial_distribution<>(20, 0.1), "n=20 p=0.1");
  560. binomial_plotter2.add(boost::math::binomial_distribution<>(20, 0.5), "n=20 p=0.5");
  561. binomial_plotter2.add(boost::math::binomial_distribution<>(20, 0.9), "n=20 p=0.9");
  562. binomial_plotter2.plot("Binomial Distribution PDF", "binomial_pdf_2.svg");
  563. distribution_plotter<boost::math::negative_binomial_distribution<> >
  564. negative_binomial_plotter;
  565. negative_binomial_plotter.add(boost::math::negative_binomial_distribution<>(20, 0.25), "n=20 p=0.25");
  566. negative_binomial_plotter.add(boost::math::negative_binomial_distribution<>(20, 0.5), "n=20 p=0.5");
  567. negative_binomial_plotter.add(boost::math::negative_binomial_distribution<>(20, 0.75), "n=20 p=0.75");
  568. negative_binomial_plotter.plot("Negative Binomial Distribution PDF", "negative_binomial_pdf_1.svg");
  569. distribution_plotter<boost::math::negative_binomial_distribution<> >
  570. negative_binomial_plotter2;
  571. negative_binomial_plotter2.add(boost::math::negative_binomial_distribution<>(10, 0.5), "n=10 p=0.5");
  572. negative_binomial_plotter2.add(boost::math::negative_binomial_distribution<>(20, 0.5), "n=20 p=0.5");
  573. negative_binomial_plotter2.add(boost::math::negative_binomial_distribution<>(70, 0.5), "n=70 p=0.5");
  574. negative_binomial_plotter2.plot("Negative Binomial Distribution PDF", "negative_binomial_pdf_2.svg");
  575. distribution_plotter<boost::math::poisson_distribution<> >
  576. poisson_plotter;
  577. poisson_plotter.add(boost::math::poisson_distribution<>(5), "&#x3BB;=5");
  578. poisson_plotter.add(boost::math::poisson_distribution<>(10), "&#x3BB;=10");
  579. poisson_plotter.add(boost::math::poisson_distribution<>(20), "&#x3BB;=20");
  580. poisson_plotter.plot("Poisson Distribution PDF", "poisson_pdf_1.svg");
  581. distribution_plotter<boost::math::hypergeometric_distribution<> >
  582. hypergeometric_plotter;
  583. hypergeometric_plotter.add(boost::math::hypergeometric_distribution<>(30, 50, 500), "N=500, r=50, n=30");
  584. hypergeometric_plotter.add(boost::math::hypergeometric_distribution<>(30, 100, 500), "N=500, r=100, n=30");
  585. hypergeometric_plotter.add(boost::math::hypergeometric_distribution<>(30, 250, 500), "N=500, r=250, n=30");
  586. hypergeometric_plotter.add(boost::math::hypergeometric_distribution<>(30, 400, 500), "N=500, r=400, n=30");
  587. hypergeometric_plotter.add(boost::math::hypergeometric_distribution<>(30, 450, 500), "N=500, r=450, n=30");
  588. hypergeometric_plotter.plot("Hypergeometric Distribution PDF", "hypergeometric_pdf_1.svg");
  589. distribution_plotter<boost::math::hypergeometric_distribution<> >
  590. hypergeometric_plotter2;
  591. hypergeometric_plotter2.add(boost::math::hypergeometric_distribution<>(50, 50, 500), "N=500, r=50, n=50");
  592. hypergeometric_plotter2.add(boost::math::hypergeometric_distribution<>(100, 50, 500), "N=500, r=50, n=100");
  593. hypergeometric_plotter2.add(boost::math::hypergeometric_distribution<>(250, 50, 500), "N=500, r=50, n=250");
  594. hypergeometric_plotter2.add(boost::math::hypergeometric_distribution<>(400, 50, 500), "N=500, r=50, n=400");
  595. hypergeometric_plotter2.add(boost::math::hypergeometric_distribution<>(450, 50, 500), "N=500, r=50, n=450");
  596. hypergeometric_plotter2.plot("Hypergeometric Distribution PDF", "hypergeometric_pdf_2.svg");
  597. }
  598. catch (std::exception ex)
  599. {
  600. std::cout << ex.what() << std::endl;
  601. }
  602. /* these graphs for hyperexponential distribution not used.
  603. distribution_plotter<boost::math::hyperexponential_distribution<> >
  604. hyperexponential_plotter;
  605. {
  606. const double probs1_1[] = {1.0};
  607. const double rates1_1[] = {1.0};
  608. hyperexponential_plotter.add(boost::math::hyperexponential_distribution<>(probs1_1,rates1_1), "&#x3B1=(1.0), &#x3BB=(1.0)");
  609. const double probs2_1[] = {0.1,0.9};
  610. const double rates2_1[] = {0.5,1.5};
  611. hyperexponential_plotter.add(boost::math::hyperexponential_distribution<>(probs2_1,rates2_1), "&#x3B1=(0.1,0.9), &#x3BB=(0.5,1.5)");
  612. const double probs2_2[] = {0.9,0.1};
  613. const double rates2_2[] = {0.5,1.5};
  614. hyperexponential_plotter.add(boost::math::hyperexponential_distribution<>(probs2_2,rates2_2), "&#x3B1=(0.9,0.1), &#x3BB=(0.5,1.5)");
  615. const double probs3_1[] = {0.2,0.3,0.5};
  616. const double rates3_1[] = {0.5,1.0,1.5};
  617. hyperexponential_plotter.add(boost::math::hyperexponential_distribution<>(probs3_1,rates3_1), "&#x3B1=(0.2,0.3,0.5), &#x3BB=(0.5,1.0,1.5)");
  618. const double probs3_2[] = {0.5,0.3,0.2};
  619. const double rates3_2[] = {0.5,1.0,1.5};
  620. hyperexponential_plotter.add(boost::math::hyperexponential_distribution<>(probs3_1,rates3_1), "&#x3B1=(0.5,0.3,0.2), &#x3BB=(0.5,1.0,1.5)");
  621. }
  622. hyperexponential_plotter.plot("Hyperexponential Distribution PDF", "hyperexponential_pdf.svg");
  623. distribution_plotter<boost::math::hyperexponential_distribution<> >
  624. hyperexponential_plotter2;
  625. {
  626. const double rates[] = {0.5,1.5};
  627. const double probs1[] = {0.1,0.9};
  628. hyperexponential_plotter2.add(boost::math::hyperexponential_distribution<>(probs1,rates), "&#x3B1=(0.1,0.9), &#x3BB=(0.5,1.5)");
  629. const double probs2[] = {0.6,0.4};
  630. hyperexponential_plotter2.add(boost::math::hyperexponential_distribution<>(probs2,rates), "&#x3B1=(0.6,0.4), &#x3BB=(0.5,1.5)");
  631. const double probs3[] = {0.9,0.1};
  632. hyperexponential_plotter2.add(boost::math::hyperexponential_distribution<>(probs3,rates), "&#x3B1=(0.9,0.1), &#x3BB=(0.5,1.5)");
  633. }
  634. hyperexponential_plotter2.plot("Hyperexponential Distribution PDF (Different Probabilities, Same Rates)", "hyperexponential_pdf_samerate.svg");
  635. distribution_plotter<boost::math::hyperexponential_distribution<> >
  636. hyperexponential_plotter3;
  637. {
  638. const double probs1[] = {1.0};
  639. const double rates1[] = {2.0};
  640. hyperexponential_plotter3.add(boost::math::hyperexponential_distribution<>(probs1,rates1), "&#x3B1=(1.0), &#x3BB=(2.0)");
  641. const double probs2[] = {0.5,0.5};
  642. const double rates2[] = {0.3,1.5};
  643. hyperexponential_plotter3.add(boost::math::hyperexponential_distribution<>(probs2,rates2), "&#x3B1=(0.5,0.5), &#x3BB=(0.3,1.5)");
  644. const double probs3[] = {1.0/3.0,1.0/3.0,1.0/3.0};
  645. const double rates3[] = {0.2,1.5,3.0};
  646. hyperexponential_plotter3.add(boost::math::hyperexponential_distribution<>(probs2,rates2), "&#x3B1=(1.0/3.0,1.0/3.0,1.0/3.0), &#x3BB=(0.2,1.5,3.0)");
  647. }
  648. hyperexponential_plotter3.plot("Hyperexponential Distribution PDF (Different Number of Phases, Same Mean)", "hyperexponential_pdf_samemean.svg");
  649. */
  650. } // int main()