main.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // main.hpp
  3. //
  4. // Copyright 2005 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #include <iostream>
  8. #include <fstream> // needed for de/serialization example (4)
  9. #include <algorithm>
  10. #include <boost/ref.hpp>
  11. #include <boost/bind.hpp>
  12. #include <boost/array.hpp>
  13. #include <boost/foreach.hpp>
  14. #include <boost/accumulators/accumulators.hpp>
  15. #include <boost/accumulators/statistics.hpp>
  16. // needed for de/serialization example (4)
  17. #include <boost/archive/text_oarchive.hpp>
  18. #include <boost/archive/text_iarchive.hpp>
  19. using namespace boost;
  20. using namespace boost::accumulators;
  21. // Helper that uses BOOST_FOREACH to display a range of doubles
  22. template<typename Range>
  23. void output_range(Range const &rng)
  24. {
  25. bool first = true;
  26. BOOST_FOREACH(double d, rng)
  27. {
  28. if(!first) std::cout << ", ";
  29. std::cout << d;
  30. first = false;
  31. }
  32. std::cout << '\n';
  33. }
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // example1
  36. //
  37. // Calculate some useful stats using accumulator_set<> and std::for_each()
  38. //
  39. void example1()
  40. {
  41. accumulator_set<
  42. double
  43. , stats<tag::min, tag::mean(immediate), tag::sum, tag::moment<2> >
  44. > acc;
  45. boost::array<double, 4> data = {0., 1., -1., 3.14159};
  46. // std::for_each pushes each sample into the accumulator one at a
  47. // time, and returns a copy of the accumulator.
  48. acc = std::for_each(data.begin(), data.end(), acc);
  49. // The following would be equivalent, and could be more efficient
  50. // because it doesn't pass and return the entire accumulator set
  51. // by value.
  52. //std::for_each(data.begin(), data.end(), bind<void>(ref(acc), _1));
  53. std::cout << " min""(acc) = " << (min)(acc) << std::endl; // Extra quotes are to prevent complaints from Boost inspect tool
  54. std::cout << " mean(acc) = " << mean(acc) << std::endl;
  55. // since mean depends on count and sum, we can get their results, too.
  56. std::cout << " count(acc) = " << count(acc) << std::endl;
  57. std::cout << " sum(acc) = " << sum(acc) << std::endl;
  58. std::cout << " moment<2>(acc) = " << accumulators::moment<2>(acc) << std::endl;
  59. }
  60. ///////////////////////////////////////////////////////////////////////////////
  61. // example2
  62. //
  63. // Calculate some tail statistics. This demonstrates how to specify
  64. // constructor and accumulator parameters. Note that the tail statistics
  65. // return multiple values, which are returned in an iterator_range.
  66. //
  67. // It pushes data in and displays the intermediate results to demonstrate
  68. // how the tail statistics are updated.
  69. void example2()
  70. {
  71. // An accumulator which tracks the right tail (largest N items) and
  72. // some data that are covariate with them. N == 4.
  73. accumulator_set<
  74. double
  75. , stats<tag::tail_variate<double, tag::covariate1, right> >
  76. > acc(tag::tail<right>::cache_size = 4);
  77. acc(2.1, covariate1 = .21);
  78. acc(1.1, covariate1 = .11);
  79. acc(2.1, covariate1 = .21);
  80. acc(1.1, covariate1 = .11);
  81. std::cout << " tail = "; output_range(tail(acc));
  82. std::cout << " tail_variate = "; output_range(tail_variate(acc));
  83. std::cout << std::endl;
  84. acc(21.1, covariate1 = 2.11);
  85. acc(11.1, covariate1 = 1.11);
  86. acc(21.1, covariate1 = 2.11);
  87. acc(11.1, covariate1 = 1.11);
  88. std::cout << " tail = "; output_range(tail(acc));
  89. std::cout << " tail_variate = "; output_range(tail_variate(acc));
  90. std::cout << std::endl;
  91. acc(42.1, covariate1 = 4.21);
  92. acc(41.1, covariate1 = 4.11);
  93. acc(42.1, covariate1 = 4.21);
  94. acc(41.1, covariate1 = 4.11);
  95. std::cout << " tail = "; output_range(tail(acc));
  96. std::cout << " tail_variate = "; output_range(tail_variate(acc));
  97. std::cout << std::endl;
  98. acc(32.1, covariate1 = 3.21);
  99. acc(31.1, covariate1 = 3.11);
  100. acc(32.1, covariate1 = 3.21);
  101. acc(31.1, covariate1 = 3.11);
  102. std::cout << " tail = "; output_range(tail(acc));
  103. std::cout << " tail_variate = "; output_range(tail_variate(acc));
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////
  106. // example3
  107. //
  108. // Demonstrate how to calculate weighted statistics. This example demonstrates
  109. // both a simple weighted statistical calculation, and a more complicated
  110. // calculation where the weight statistics are calculated and stored in an
  111. // external weight accumulator.
  112. void example3()
  113. {
  114. // weight == double
  115. double w = 1.;
  116. // Simple weighted calculation
  117. {
  118. // stats that depend on the weight are made external
  119. accumulator_set<double, stats<tag::mean>, double> acc;
  120. acc(0., weight = w);
  121. acc(1., weight = w);
  122. acc(-1., weight = w);
  123. acc(3.14159, weight = w);
  124. std::cout << " mean(acc) = " << mean(acc) << std::endl;
  125. }
  126. // Weighted calculation with an external weight accumulator
  127. {
  128. // stats that depend on the weight are made external
  129. accumulator_set<double, stats<tag::mean>, external<double> > acc;
  130. // Here's an external weight accumulator
  131. accumulator_set<void, stats<tag::sum_of_weights>, double> weight_acc;
  132. weight_acc(weight = w); acc(0., weight = w);
  133. weight_acc(weight = w); acc(1., weight = w);
  134. weight_acc(weight = w); acc(-1., weight = w);
  135. weight_acc(weight = w); acc(3.14159, weight = w);
  136. std::cout << " mean(acc) = " << mean(acc, weights = weight_acc) << std::endl;
  137. }
  138. }
  139. ///////////////////////////////////////////////////////////////////////////////
  140. // example4
  141. //
  142. // Show how accumulators could be persisted into a file, and then continued
  143. // from where they were left of
  144. //
  145. void example4()
  146. {
  147. accumulator_set<
  148. double
  149. , stats<tag::min, tag::mean(immediate), tag::sum, tag::moment<2>, tag::p_square_quantile, tag::kurtosis >
  150. > acc(quantile_probability = 0.9);
  151. {
  152. // accumulate values from array
  153. boost::array<double, 10> data = {-10., -8., -7., -6., -5., -4., -3., -2., -1., 0.};
  154. acc = std::for_each(data.begin(), data.end(), acc);
  155. }
  156. std::cout << " min = " << (min)(acc) << std::endl;
  157. std::cout << " mean = " << mean(acc) << std::endl;
  158. std::cout << " count = " << count(acc) << std::endl;
  159. std::cout << " sum = " << sum(acc) << std::endl;
  160. std::cout << " moment<2> = " << accumulators::moment<2>(acc) << std::endl;
  161. std::cout << " p_square_quantile = " << accumulators::p_square_quantile(acc) << std::endl;
  162. std::cout << " kurtosis = " << accumulators::kurtosis(acc) << std::endl;
  163. // save accumulator list into a file called "saved-stats"
  164. const unsigned ACC_VER = 0;
  165. const char* file_name = "saved-stats";
  166. {
  167. std::ofstream ofs(file_name);
  168. boost::archive::text_oarchive oa(ofs);
  169. acc.serialize(oa, ACC_VER);
  170. }
  171. // create a new accumulator set and initialize from data saved into the file
  172. accumulator_set<
  173. double
  174. , stats<tag::min, tag::mean(immediate), tag::sum, tag::moment<2>, tag::p_square_quantile, tag::kurtosis >
  175. > restored_acc(quantile_probability = 0.9);
  176. {
  177. std::ifstream ifs(file_name);
  178. boost::archive::text_iarchive ia(ifs);
  179. restored_acc.serialize(ia, ACC_VER);
  180. }
  181. // continue accumulating into both sets
  182. {
  183. // accumulate values from array
  184. boost::array<double, 10> data = {10., 8., 7., 6., 5., 4., 3., 2., 1., 0.};
  185. acc = std::for_each(data.begin(), data.end(), acc);
  186. restored_acc = std::for_each(data.begin(), data.end(), restored_acc);
  187. }
  188. // validate that both return th same values
  189. std::cout << std::endl << "Values in original set:" << std::endl;
  190. std::cout << " min""(acc) = " << (min)(acc) << std::endl;
  191. std::cout << " mean(acc) = " << mean(acc) << std::endl;
  192. std::cout << " count(acc) = " << count(acc) << std::endl;
  193. std::cout << " sum(acc) = " << sum(acc) << std::endl;
  194. std::cout << " moment<2>(acc) = " << accumulators::moment<2>(acc) << std::endl;
  195. std::cout << " p_square_quantile(acc) = " << accumulators::p_square_quantile(acc) << std::endl;
  196. std::cout << " kurtosis(acc) = " << accumulators::kurtosis(acc) << std::endl;
  197. std::cout << std::endl << "Values in restored set:" << std::endl;
  198. std::cout << " min""(acc) = " << (min)(restored_acc) << std::endl;
  199. std::cout << " mean(acc) = " << mean(restored_acc) << std::endl;
  200. std::cout << " count(acc) = " << count(restored_acc) << std::endl;
  201. std::cout << " sum(acc) = " << sum(restored_acc) << std::endl;
  202. std::cout << " moment<2>(acc) = " << accumulators::moment<2>(restored_acc) << std::endl;
  203. std::cout << " p_square_quantile(acc) = " << accumulators::p_square_quantile(restored_acc) << std::endl;
  204. std::cout << " kurtosis(acc) = " << accumulators::kurtosis(restored_acc) << std::endl;
  205. }
  206. ///////////////////////////////////////////////////////////////////////////////
  207. // main
  208. int main()
  209. {
  210. std::cout << "Example 1:\n";
  211. example1();
  212. std::cout << "\nExample 2:\n";
  213. example2();
  214. std::cout << "\nExample 3:\n";
  215. example3();
  216. std::cout << "\nExample 4:\n";
  217. example4();
  218. return 0;
  219. }