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