]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | [library Boost.Accumulators | |
3 | [quickbook 1.3] | |
4 | [authors [Niebler, Eric]] | |
5 | [copyright 2005 2006 Eric Niebler] | |
6 | [category math] | |
7 | [id accumulators] | |
8 | [dirname accumulators] | |
9 | [purpose | |
10 | Incremental accumulation framework and statistical accumulator library. | |
11 | ] | |
12 | [license | |
13 | Distributed under the Boost Software License, Version 1.0. | |
14 | (See accompanying file LICENSE_1_0.txt or copy at | |
15 | [@http://www.boost.org/LICENSE_1_0.txt]) | |
16 | ] | |
17 | ] | |
18 | ||
19 | [/ Images ] | |
20 | ||
21 | [def _note_ [$images/note.png]] | |
22 | [def _alert_ [$images/caution.png]] | |
23 | [def _detail_ [$images/note.png]] | |
24 | [def _tip_ [$images/tip.png]] | |
25 | ||
26 | [/ Links ] | |
27 | ||
28 | [def _sample_type_ '''<replaceable>sample-type</replaceable>'''] | |
29 | [def _weight_type_ '''<replaceable>weight-type</replaceable>'''] | |
30 | [def _variate_type_ '''<replaceable>variate-type</replaceable>'''] | |
31 | [def _variate_tag_ '''<replaceable>variate-tag</replaceable>'''] | |
32 | [def _left_or_right_ '''<replaceable>left-or-right</replaceable>'''] | |
33 | [def _implementation_defined_ '''<replaceable>implementation-defined</replaceable>'''] | |
34 | [def _boost_ [@http://www.boost.org Boost]] | |
35 | [def _mpl_ [@../../libs/mpl/index.html MPL]] | |
36 | [def _mpl_lambda_expression_ [@../../libs/mpl/doc/refmanual/lambda-expression.html MPL Lambda Expression]] | |
37 | [def _parameter_ [@../../libs/parameter/index.html Boost.Parameter]] | |
38 | [def _accumulator_set_ [classref boost::accumulators::accumulator_set `accumulator_set<>`]] | |
39 | [def _accumulator_base_ [classref boost::accumulators::accumulator_base `accumulator_base`]] | |
40 | [def _depends_on_ [classref boost::accumulators::depends_on `depends_on<>`]] | |
41 | [def _feature_of_ [classref boost::accumulators::feature_of `feature_of<>`]] | |
42 | [def _as_feature_ [classref boost::accumulators::as_feature `as_feature<>`]] | |
43 | [def _features_ [classref boost::accumulators::features `features<>`]] | |
44 | [def _external_ [classref boost::accumulators::external `external<>`]] | |
45 | [def _droppable_ [classref boost::accumulators::droppable `droppable<>`]] | |
46 | [def _droppable_accumulator_ [classref boost::accumulators::droppable_accumulator `droppable_accumulator<>`]] | |
47 | [def _extractor_ [classref boost::accumulators::tag::extractor `extractor<>`]] | |
48 | [def _tail_ [classref boost::accumulators::tag::tail `tail`]] | |
49 | [def _tail_variate_ [classref boost::accumulators::tag::tail_variate `tail_variate<>`]] | |
50 | [def _extract_result_ [funcref boost::accumulators::extract_result `extract_result()`]] | |
51 | [def _ZKB_ [@http://www.zkb.com Z'''ü'''rcher Kantonalbank]] | |
52 | ||
53 | [section Preface] | |
54 | ||
55 | [:["It is better to be approximately right than exactly wrong.]\n['-- Old adage]] | |
56 | ||
57 | [h2 Description] | |
58 | ||
59 | Boost.Accumulators is both a library for incremental statistical computation as | |
60 | well as an extensible framework for incremental calculation in general. The library | |
61 | deals primarily with the concept of an ['accumulator], which is a primitive | |
62 | computational entity that accepts data one sample at a time and maintains some | |
63 | internal state. These accumulators may offload some of their computations on other | |
64 | accumulators, on which they depend. Accumulators are grouped within an ['accumulator | |
65 | set]. Boost.Accumulators resolves the inter-dependencies between accumulators in a | |
66 | set and ensures that accumulators are processed in the proper order. | |
67 | ||
68 | [endsect] | |
69 | ||
70 | [section User's Guide] | |
71 | ||
72 | This section describes how to use the Boost.Accumulators framework to create new | |
73 | accumulators and how to use the existing statistical accumulators to perform incremental | |
74 | statistical computation. For detailed information regarding specific components in | |
75 | Boost.Accumulators, check the [link accumulators_framework_reference Reference] section. | |
76 | ||
77 | [h2 Hello, World!] | |
78 | ||
79 | Below is a complete example of how to use the Accumulators Framework and the | |
80 | Statistical Accumulators to perform an incremental statistical calculation. It | |
81 | calculates the mean and 2nd moment of a sequence of doubles. | |
82 | ||
83 | #include <iostream> | |
84 | #include <boost/accumulators/accumulators.hpp> | |
85 | #include <boost/accumulators/statistics/stats.hpp> | |
86 | #include <boost/accumulators/statistics/mean.hpp> | |
87 | #include <boost/accumulators/statistics/moment.hpp> | |
88 | using namespace boost::accumulators; | |
89 | ||
90 | int main() | |
91 | { | |
92 | // Define an accumulator set for calculating the mean and the | |
93 | // 2nd moment ... | |
94 | accumulator_set<double, stats<tag::mean, tag::moment<2> > > acc; | |
95 | ||
96 | // push in some data ... | |
97 | acc(1.2); | |
98 | acc(2.3); | |
99 | acc(3.4); | |
100 | acc(4.5); | |
101 | ||
102 | // Display the results ... | |
103 | std::cout << "Mean: " << mean(acc) << std::endl; | |
104 | std::cout << "Moment: " << accumulators::moment<2>(acc) << std::endl; | |
105 | ||
106 | return 0; | |
107 | } | |
108 | ||
109 | This program displays the following: | |
110 | ||
111 | [pre | |
112 | Mean: 2.85 | |
113 | Moment: 9.635 | |
114 | ] | |
115 | ||
116 | [section The Accumulators Framework] | |
117 | ||
118 | The Accumulators Framework is framework for performing incremental calculations. Usage | |
119 | of the framework follows the following pattern: | |
120 | ||
121 | * Users build a computational object, called an ['_accumulator_set_], by selecting | |
122 | the computations in which they are interested, or authoring their own computational | |
123 | primitives which fit within the framework. | |
124 | * Users push data into the _accumulator_set_ object one sample at a time. | |
125 | * The _accumulator_set_ computes the requested quantities in the most efficient method | |
126 | possible, resolving dependencies between requested calculations, possibly caching | |
127 | intermediate results. | |
128 | ||
129 | The Accumulators Framework defines the utilities needed for defining primitive | |
130 | computational elements, called ['accumulators]. It also provides the _accumulator_set_ | |
131 | type, described above. | |
132 | ||
133 | [h2 Terminology] | |
134 | ||
135 | The following terms are used in the rest of the documentation. | |
136 | ||
137 | [variablelist | |
138 | [[Sample] [[#sample_type] A datum that is pushed into an _accumulator_set_. | |
139 | The type of the sample is the ['sample type].]] | |
140 | [[Weight] [[#weight_type] An optional scalar value passed along with the | |
141 | sample specifying the weight of the sample. Conceptually, each | |
142 | sample is multiplied with its weight. The type of the weight is | |
143 | the ['weight type].]] | |
144 | [[Feature] [An abstract primitive computational entity. When defining an | |
145 | _accumulator_set_, users specify the features in which they are | |
146 | interested, and the _accumulator_set_ figures out which | |
147 | ['accumulators] would best provide those features. Features may | |
148 | depend on other features. If they do, the accumulator set figures | |
149 | out which accumulators to add to satisfy the dependencies.]] | |
150 | [[Accumulator] [A concrete primitive computational entity. An accumulator is a | |
151 | concrete implementation of a feature. It satisfies exactly one | |
152 | abstract feature. Several different accumulators may provide the | |
153 | same feature, but may represent different implementation strategies.]] | |
154 | [[Accumulator Set] [A collection of accumulators. An accumulator set is specified with | |
155 | a sample type and a list of features. The accumulator set uses this | |
156 | information to generate an ordered set of accumulators depending on | |
157 | the feature dependency graph. An accumulator set accepts samples one | |
158 | datum at a time, propagating them to each accumulator in order. At any | |
159 | point, results can be extracted from the accumulator set.]] | |
160 | [[Extractor] [A function or function object that can be used to extract a result | |
161 | from an _accumulator_set_.]] | |
162 | ] | |
163 | ||
164 | [h2 Overview] | |
165 | ||
166 | Here is a list of the important types and functions in the Accumulator Framework and | |
167 | a brief description of each. | |
168 | ||
169 | [table Accumulators Toolbox | |
170 | [[Tool] [Description]] | |
171 | [[_accumulator_set_] [This is the most important type in the Accumulators Framework. | |
172 | It is a collection of accumulators. A datum pushed into an | |
173 | _accumulator_set_ is forwarded to each accumulator, in an order | |
174 | determined by the dependency relationships between the | |
175 | accumulators. Computational results can be extracted from an | |
176 | accumulator at any time.]] | |
177 | [[_depends_on_ ] [Used to specify which other features a feature depends on.]] | |
178 | [[_feature_of_ ] [Trait used to tell the Accumulators Framework that, for the purpose | |
179 | of feature-based dependency resolution, one feature should be | |
180 | treated the same as another.]] | |
181 | [[_as_feature_ ] [Used to create an alias for a feature. For example, if there are | |
182 | two features, fast_X and accurate_X, they can be mapped to | |
183 | X(fast) and X(accurate) with _as_feature_. This is just syntactic | |
184 | sugar.]] | |
185 | [[_features_ ] [An _mpl_ sequence. We can use _features_ as the second template | |
186 | parameter when declaring an _accumulator_set_.]] | |
187 | [[_external_ ] [Used when declaring an _accumulator_set_. If the weight type is | |
188 | specified with _external_, then the weight accumulators are | |
189 | assumed to reside in a separate accumulator set which will be passed | |
190 | in with a named parameter.]] | |
191 | [[_extractor_ ] [A class template useful for creating an extractor function object. | |
192 | It is parameterized on a feature, and it has member functions for | |
193 | extracting from an _accumulator_set_ the result corresponding to | |
194 | that feature.]] | |
195 | ] | |
196 | ||
197 | [section Using [^accumulator_set<>]] | |
198 | ||
199 | Our tour of the _accumulator_set_ class template begins with the forward declaration: | |
200 | ||
201 | template< typename Sample, typename Features, typename Weight = void > | |
202 | struct accumulator_set; | |
203 | ||
204 | The template parameters have the following meaning: | |
205 | ||
206 | [variablelist | |
207 | [[`Sample`] [The type of the data that will be accumulated.]] | |
208 | [[`Features`] [An _mpl_ sequence of features to be calculated.]] | |
209 | [[`Weight`] [The type of the (optional) weight paramter.]] | |
210 | ] | |
211 | ||
212 | For example, the following line declares an _accumulator_set_ that will accept | |
213 | a sequence of doubles one at a time and calculate the min and mean: | |
214 | ||
215 | accumulator_set< double, features< tag::min, tag::mean > > acc; | |
216 | ||
217 | Notice that we use the _features_ template to specify a list of features to be calculated. | |
218 | _features_ is an MPL sequence of features. | |
219 | ||
220 | [note _features_ is a synonym of `mpl::vector<>`. In fact, we could use `mpl::vector<>` | |
221 | or any MPL sequence if we prefer, and the meaning would be the same.] | |
222 | ||
223 | Once we have defined an _accumulator_set_, we can then push data into it, | |
224 | and it will calculate the quantities you requested, as shown below. | |
225 | ||
226 | // push some data into the accumulator_set ... | |
227 | acc(1.2); | |
228 | acc(2.3); | |
229 | acc(3.4); | |
230 | ||
231 | Since _accumulator_set_ defines its accumulate function to be the function call operator, | |
232 | we might be tempted to use an _accumulator_set_ as a UnaryFunction to a standard | |
233 | algorithm such as `std::for_each`. That's fine as long as we keep in mind that the standard | |
234 | algorithms take UnaryFunction objects by value, which involves making a copy of the | |
235 | _accumulator_set_ object. Consider the following: | |
236 | ||
237 | // The data for which we wish to calculate statistical properties: | |
238 | std::vector< double > data( /* stuff */ ); | |
239 | ||
240 | // The accumulator set which will calculate the properties for us: | |
241 | accumulator_set< double, features< tag::min, tag::mean > > acc; | |
242 | ||
243 | // Use std::for_each to accumulate the statistical properties: | |
244 | acc = std::for_each( data.begin(), data.end(), acc ); | |
245 | ||
246 | Notice how we must assign the return value of `std::for_each` back to the _accumulator_set_. | |
247 | This works, but some accumulators are not cheap to copy. For | |
248 | example, the _tail_ and _tail_variate_ accumulators must store a `std::vector<>`, so copying | |
249 | these accumulators involves a dynamic allocation. We might be better off in this | |
250 | case passing the accumulator by reference, with the help of `boost::bind()` and | |
251 | `boost::ref()`. See below: | |
252 | ||
253 | // The data for which we wish to calculate statistical properties: | |
254 | std::vector< double > data( /* stuff */ ); | |
255 | ||
256 | // The accumulator set which will calculate the properties for us: | |
257 | accumulator_set< double, features< tag::tail<left> > > acc( | |
258 | tag::tail<left>::cache_size = 4 ); | |
259 | ||
260 | // Use std::for_each to accumulate the statistical properties: | |
261 | std::for_each( data.begin(), data.end(), bind<void>( ref(acc), _1 ) ); | |
262 | ||
263 | Notice now that we don't care about the return value of `std::for_each()` anymore because | |
264 | `std::for_each()` is modifying `acc` directly. | |
265 | ||
266 | [note To use `boost::bind()` and `boost::ref()`, you must `#include` [^<boost/bind.hpp>] | |
267 | and [^<boost/ref.hpp>]] | |
268 | ||
269 | [endsect] | |
270 | ||
271 | [section Extracting Results] | |
272 | ||
273 | Once we have declared an _accumulator_set_ and pushed data into it, we need to be able | |
274 | to extract results from it. For each feature we can add to an _accumulator_set_, there | |
275 | is a corresponding extractor for fetching its result. Usually, the extractor has the | |
276 | same name as the feature, but in a different namespace. For example, if we accumulate | |
277 | the `tag::min` and `tag::max` features, we can extract the results with the `min` and `max` | |
278 | extractors, as follows: | |
279 | ||
280 | // Calculate the minimum and maximum for a sequence of integers. | |
281 | accumulator_set< int, features< tag::min, tag::max > > acc; | |
282 | acc( 2 ); | |
283 | acc( -1 ); | |
284 | acc( 1 ); | |
285 | ||
286 | // This displays "(-1, 2)" | |
287 | std::cout << '(' << min( acc ) << ", " << max( acc ) << ")\n"; | |
288 | ||
289 | The extractors are all declared in the `boost::accumulators::extract` namespace, but they | |
290 | are brought into the `boost::accumulators` namespace with a `using` declaration. | |
291 | ||
292 | [tip On the Windows platform, `min` and `max` are preprocessor macros defined in [^WinDef.h]. | |
293 | To use the `min` and `max` extractors, you should either compile with `NOMINMAX` defined, or | |
294 | you should invoke the extractors like: `(min)( acc )` and `(max)( acc )`. The parentheses | |
295 | keep the macro from being invoked.] | |
296 | ||
297 | Another way to extract a result from an _accumulator_set_ is with the | |
298 | `extract_result()` function. This can be more convenient if there isn't an extractor | |
299 | object handy for a certain feature. The line above which displays results could | |
300 | equally be written as: | |
301 | ||
302 | // This displays "(-1, 2)" | |
303 | std::cout << '(' << extract_result< tag::min >( acc ) | |
304 | << ", " << extract_result< tag::max >( acc ) << ")\n"; | |
305 | ||
306 | Finally, we can define our own extractor using the _extractor_ class template. For | |
307 | instance, another way to avoid the `min` / `max` macro business would be to define | |
308 | extractors with names that don't conflict with the macros, like this: | |
309 | ||
310 | extractor< tag::min > min_; | |
311 | extractor< tag::min > max_; | |
312 | ||
313 | // This displays "(-1, 2)" | |
314 | std::cout << '(' << min_( acc ) << ", " << max_( acc ) << ")\n"; | |
315 | ||
316 | [endsect] | |
317 | ||
318 | [section Passing Optional Parameters] | |
319 | ||
320 | Some accumulators need initialization parameters. In addition, perhaps some auxiliary | |
321 | information needs to be passed into the _accumulator_set_ along with each sample. | |
322 | Boost.Accumulators handles these cases with named parameters from the _parameter_ | |
323 | library. | |
324 | ||
325 | For example, consider the _tail_ and _tail_variate_ features. _tail_ keeps | |
326 | an ordered list of the largest [^['N]] samples, where [^['N]] can be specified at | |
327 | construction time. Also, the _tail_variate_ feature, which depends on _tail_, keeps | |
328 | track of some data that is covariate with the [^['N]] samples tracked by _tail_. The | |
329 | code below shows how this all works, and is described in more detail below. | |
330 | ||
331 | // Define a feature for tracking covariate data | |
332 | typedef tag::tail_variate< int, tag::covariate1, left > my_tail_variate_tag; | |
333 | ||
334 | // This will calculate the left tail and my_tail_variate_tag for N == 2 | |
335 | // using the tag::tail<left>::cache_size named parameter | |
336 | accumulator_set< double, features< my_tail_variate_tag > > acc( | |
337 | tag::tail<left>::cache_size = 2 ); | |
338 | ||
339 | // push in some samples and some covariates by using | |
340 | // the covariate1 named parameter | |
341 | acc( 1.2, covariate1 = 12 ); | |
342 | acc( 2.3, covariate1 = -23 ); | |
343 | acc( 3.4, covariate1 = 34 ); | |
344 | acc( 4.5, covariate1 = -45 ); | |
345 | ||
346 | // Define an extractor for the my_tail_variate_tag feature | |
347 | extractor< my_tail_variate_tag > my_tail_variate; | |
348 | ||
349 | // Write the tail statistic to std::cout. This will print "4.5, 3.4, " | |
350 | std::ostream_iterator< double > dout( std::cout, ", " ); | |
351 | std::copy( tail( acc ).begin(), tail( acc ).end(), dout ); | |
352 | ||
353 | // Write the tail_variate statistic to std::cout. This will print "-45, 34, " | |
354 | std::ostream_iterator< int > iout( std::cout, ", " ); | |
355 | std::copy( my_tail_variate( acc ).begin(), my_tail_variate( acc ).end(), iout ); | |
356 | ||
357 | There are several things to note about the code above. First, notice that we didn't have | |
358 | to request that the _tail_ feature be calculated. That is implicit because the _tail_variate_ | |
359 | feature depends on the _tail_ feature. Next, notice how the `acc` object | |
360 | is initialized: `acc( tag::tail<left>::cache_size = 2 )`. Here, `cache_size` is a named parameter. | |
361 | It is used to tell the _tail_ and _tail_variate_ accumulators how many samples and | |
362 | covariates to store. Conceptually, every construction parameter is made available to | |
363 | every accumulator in an accumulator set. | |
364 | ||
365 | We also use a named parameter to pass covariate data into the accumulator set along with | |
366 | the samples. As with the constructor parameters, all parameters to the accumulate function | |
367 | are made available to all the accumulators in the set. In this case, only the accumulator | |
368 | for the `my_tail_variate` feature would be interested in the value of the `covariate1` named | |
369 | parameter. | |
370 | ||
371 | We can make one final observation about the example above. Since _tail_ and _tail_variate_ | |
372 | are multi-valued features, the result we extract for them is represented as an iterator | |
373 | range. That is why we can say `tail( acc ).begin()` and `tail( acc ).end()`. | |
374 | ||
375 | Even the extractors can accept named parameters. In a bit, we'll see a situation where that | |
376 | is useful. | |
377 | ||
378 | [endsect] | |
379 | ||
380 | [section Weighted Samples] | |
381 | ||
382 | Some accumulators, statistical accumulators in particular, deal with data that are | |
383 | ['weighted]. Each sample pushed into the accumulator has an associated weight, by which | |
384 | the sample is conceptually multiplied. The Statistical Accumulators Library provides an | |
385 | assortment of these weighted statistical accumulators. And many unweighted statistical | |
386 | accumulators have weighted variants. For instance, the weighted variant of the `sum` | |
387 | accumulator is called `weighted_sum`, and is calculated by accumulating all the | |
388 | samples multiplied by their weights. | |
389 | ||
390 | To declare an _accumulator_set_ that accepts weighted samples, you must specify the | |
391 | type of the weight parameter as the 3rd template parameter, as follows: | |
392 | ||
393 | // 3rd template parameter 'int' means this is a weighted | |
394 | // accumulator set where the weights have type 'int' | |
395 | accumulator_set< int, features< tag::sum >, int > acc; | |
396 | ||
397 | When you specify a weight, all the accumulators in the set are replaced with | |
398 | their weighted equivalents. For example, the above _accumulator_set_ declaration | |
399 | is equivalent to the following: | |
400 | ||
401 | // Since we specified a weight, tag::sum becomes tag::weighted_sum | |
402 | accumulator_set< int, features< tag::weighted_sum >, int > acc; | |
403 | ||
404 | When passing samples to the accumulator set, you must also specify the | |
405 | weight of each sample. You can do that with the `weight` named parameter, | |
406 | as follows: | |
407 | ||
408 | acc(1, weight = 2); // 1 * 2 | |
409 | acc(2, weight = 4); // 2 * 4 | |
410 | acc(3, weight = 6); // + 3 * 6 | |
411 | // ------- | |
412 | // = 28 | |
413 | ||
414 | You can then extract the result with the `sum()` extractor, as follows: | |
415 | ||
416 | // This prints "28" | |
417 | std::cout << sum(acc) << std::endl; | |
418 | ||
419 | [note When working with weighted statistical accumulators from the Statistical | |
420 | Accumulators Library, be sure to include the appropriate header. For instance, | |
421 | `weighted_sum` is defined in `<boost/accumulators/statistics/weighted_sum.hpp>`.] | |
422 | ||
423 | [endsect] | |
424 | ||
425 | [section Numeric Operators Sub-Library] | |
426 | ||
427 | This section describes the function objects in the `boost::numeric` namespace, which | |
428 | is a sub-library that provides function objects and meta-functions corresponding | |
429 | to the infix operators in C++. | |
430 | ||
431 | In the `boost::numeric::operators` namespace are additional operator overloads for | |
432 | some useful operations not provided by the standard library, such as multiplication | |
433 | of a `std::complex<>` with a scalar. | |
434 | ||
435 | In the `boost::numeric::functional` namespace are function object equivalents of | |
436 | the infix operators. These function object types are heterogeneous, and so are more | |
437 | general than the standard ones found in the [^<functional>] header. They use the | |
438 | Boost.Typeof library to deduce the return types of the infix expressions they | |
439 | evaluate. In addition, they look within the `boost::numeric::operators` namespace | |
440 | to consider any additional overloads that might be defined there. | |
441 | ||
442 | In the `boost::numeric` namespace are global polymorphic function objects | |
443 | corresponding to the function object types defined in the `boost::numeric::functional` | |
444 | namespace. For example, `boost::numeric::plus(a, b)` is equivalent to | |
445 | `boost::numeric::functional::plus<A, B>()(a, b)`, and both are equivalent to | |
446 | `using namespace boost::numeric::operators; a + b;`. | |
447 | ||
448 | The Numeric Operators Sub-Library also gives several ways to sub-class and | |
449 | a way to sub-class and specialize operations. One way uses tag dispatching on | |
450 | the types of the operands. The other way is based on the compile-time | |
451 | properties of the operands. | |
452 | ||
453 | [endsect] | |
454 | ||
455 | [section Extending the Accumulators Framework] | |
456 | ||
457 | This section describes how to extend the Accumulators Framework by defining new accumulators, | |
458 | features and extractors. Also covered are how to control the dependency resolution of | |
459 | features within an accumulator set. | |
460 | ||
461 | [section Defining a New Accumulator] | |
462 | ||
463 | All new accumulators must satisfy the [link | |
464 | accumulators.user_s_guide.the_accumulators_framework.concepts.accumulator_concept Accumulator | |
465 | Concept]. Below is a sample class that satisfies the accumulator concept, which simply sums | |
466 | the values of all samples passed into it. | |
467 | ||
468 | #include <boost/accumulators/framework/accumulator_base.hpp> | |
469 | #include <boost/accumulators/framework/parameters/sample.hpp> | |
470 | ||
471 | namespace boost { // Putting your accumulators in the | |
472 | namespace accumulators { // impl namespace has some | |
473 | namespace impl { // advantages. See below. | |
474 | ||
475 | template<typename Sample> | |
476 | struct sum_accumulator // All accumulators should inherit from | |
477 | : accumulator_base // accumulator_base. | |
478 | { | |
479 | typedef Sample result_type; // The type returned by result() below. | |
480 | ||
481 | template<typename Args> // The constructor takes an argument pack. | |
482 | sum_accumulator(Args const & args) | |
483 | : sum(args[sample | Sample()]) // Maybe there is an initial value in the | |
484 | { // argument pack. ('sample' is defined in | |
485 | } // sample.hpp, included above.) | |
486 | ||
487 | template<typename Args> // The accumulate function is the function | |
488 | void operator ()(Args const & args) // call operator, and it also accepts an | |
489 | { // argument pack. | |
490 | this->sum += args[sample]; | |
491 | } | |
492 | ||
493 | result_type result(dont_care) const // The result function will also be passed | |
494 | { // an argument pack, but we don't use it here, | |
495 | return this->sum; // so we use "dont_care" as the argument type. | |
496 | } | |
497 | private: | |
498 | Sample sum; | |
499 | }; | |
500 | ||
501 | }}} | |
502 | ||
503 | Much of the above should be pretty self-explanatory, except for the use of argument packs | |
504 | which may be confusing if you have never used the _parameter_ library before. An argument | |
505 | pack is a cluster of values, each of which can be accessed with a key. So `args[sample]` | |
506 | extracts from the pack the value associated with the `sample` key. And the cryptic | |
507 | `args[sample | Sample()]` evaluates to the value associated with the `sample` key if it | |
508 | exists, or a default-constructed `Sample` if it doesn't. | |
509 | ||
510 | The example above demonstrates the most common attributes of an accumulator. There are | |
511 | other optional member functions that have special meaning. In particular: | |
512 | ||
513 | [variablelist Optional Accumulator Member Functions | |
514 | [[[^on_drop(Args)]] [Defines an action to be taken when this accumulator is | |
515 | dropped. See the section on | |
516 | [link accumulators.user_s_guide.the_accumulators_framework.extending_the_accumulators_framework.defining_a_new_accumulator.droppable_accumulators | |
517 | Droppable Accumulators].]] | |
518 | ] | |
519 | ||
520 | [h3 Accessing Other Accumulators in the Set] | |
521 | ||
522 | Some accumulators depend on other accumulators within the same accumulator set. In those | |
523 | cases, it is necessary to be able to access those other accumulators. To make this possible, | |
524 | the _accumulator_set_ passes a reference to itself when invoking the member functions of | |
525 | its contained accumulators. It can be accessed by using the special `accumulator` key with | |
526 | the argument pack. Consider how we might implement `mean_accumulator`: | |
527 | ||
528 | // Mean == (Sum / Count) | |
529 | template<typename Sample> | |
530 | struct mean_accumulator : accumulator_base | |
531 | { | |
532 | typedef Sample result_type; | |
533 | mean_accumulator(dont_care) {} | |
534 | ||
535 | template<typename Args> | |
536 | result_type result(Args const &args) const | |
537 | { | |
538 | return sum(args[accumulator]) / count(args[accumulator]); | |
539 | } | |
540 | }; | |
541 | ||
542 | `mean` depends on the `sum` and `count` accumulators. (We'll see in the next section how | |
543 | to specify these dependencies.) The result of the mean accumulator is merely the result of | |
544 | the sum accumulator divided by the result of the count accumulator. Consider how we write | |
545 | that: `sum(args[accumulator]) / count(args[accumulator])`. The expression `args[accumulator]` | |
546 | evaluates to a reference to the _accumulator_set_ that contains this `mean_accumulator`. It | |
547 | also contains the `sum` and `count` accumulators, and we can access their results with the | |
548 | extractors defined for those features: `sum` and `count`. | |
549 | ||
550 | [note Accumulators that inherit from _accumulator_base_ get an empty `operator ()`, so | |
551 | accumulators like `mean_accumulator` above need not define one.] | |
552 | ||
553 | All the member functions that accept an argument pack have access to the enclosing | |
554 | _accumulator_set_ via the `accumulator` key, including the constructor. The | |
555 | accumulators within the set are constructed in an order determined by their interdependencies. | |
556 | As a result, it is safe for an accumulator to access one on which it depends during construction. | |
557 | ||
558 | [h3 Infix Notation and the Numeric Operators Sub-Library] | |
559 | ||
560 | Although not necessary, it can be a good idea to put your accumulator implementations in | |
561 | the `boost::accumulators::impl` namespace. This namespace pulls in any operators defined | |
562 | in the `boost::numeric::operators` namespace with a using directive. The Numeric Operators | |
563 | Sub-Library defines some additional overloads that will make your accumulators work with | |
564 | all sorts of data types. | |
565 | ||
566 | Consider `mean_accumulator` defined above. It divides the sum of the samples by the count. | |
567 | The type of the count is `std::size_t`. What if the sample type doesn't define division by | |
568 | `std::size_t`? That's the case for `std::complex<>`. You might think that if the sample type | |
569 | is `std::complex<>`, the code would not work, but in fact it does. That's because | |
570 | Numeric Operators Sub-Library defines an overloaded `operator/` for `std::complex<>` | |
571 | and `std::size_t`. This operator is defined in the `boost::numeric::operators` namespace and | |
572 | will be found within the `boost::accumulators::impl` namespace. That's why it's a good idea | |
573 | to put your accumulators there. | |
574 | ||
575 | [h3 Droppable Accumulators] | |
576 | ||
577 | The term "droppable" refers to an accumulator that can be removed from the _accumulator_set_. | |
578 | You can request that an accumulator be made droppable by using the _droppable_ class template. | |
579 | ||
580 | // calculate sum and count, make sum droppable: | |
581 | accumulator_set< double, features< tag::count, droppable<tag::sum> > > acc; | |
582 | ||
583 | // add some data | |
584 | acc(3.0); | |
585 | acc(2.0); | |
586 | ||
587 | // drop the sum (sum is 5 here) | |
588 | acc.drop<tag::sum>(); | |
589 | ||
590 | // add more data | |
591 | acc(1.0); | |
592 | ||
593 | // This will display "3" and "5" | |
594 | std::cout << count(acc) << ' ' << sum(acc); | |
595 | ||
596 | Any accumulators that get added to an accumulator set in order to satisfy | |
597 | dependencies on droppable accumulators are themselves droppable. Consider | |
598 | the following accumulator: | |
599 | ||
600 | // Sum is not droppable. Mean is droppable. Count, brought in to | |
601 | // satisfy mean's dependencies, is implicitly droppable, too. | |
602 | accumulator_set< double, features< tag::sum, droppable<tag::mean> > > acc; | |
603 | ||
604 | `mean` depends on `sum` and `count`. Since `mean` is droppable, so too is `count`. | |
605 | However, we have explicitly requested that `sum` be not droppable, so it isn't. Had | |
606 | we left `tag::sum` out of the above declaration, the `sum` accumulator would have | |
607 | been implicitly droppable. | |
608 | ||
609 | A droppable accumulator is reference counted, and is only really dropped after all the | |
610 | accumulators that depend on it have been dropped. This can lead to some surprising | |
611 | behavior in some situations. | |
612 | ||
613 | // calculate sum and mean, make mean droppable. | |
614 | accumulator_set< double, features< tag::sum, droppable<tag::mean> > > acc; | |
615 | ||
616 | // add some data | |
617 | acc(1.0); | |
618 | acc(2.0); | |
619 | ||
620 | // drop the mean. mean's reference count | |
621 | // drops to 0, so it's really dropped. So | |
622 | // too, count's reference count drops to 0 | |
623 | // and is really dropped. | |
624 | acc.drop<tag::mean>(); | |
625 | ||
626 | // add more data. Sum continues to accumulate! | |
627 | acc(3.0); | |
628 | ||
629 | // This will display "6 2 3" | |
630 | std::cout << sum(acc) << ' ' | |
631 | << count(acc) << ' ' | |
632 | << mean(acc); | |
633 | ||
634 | Note that at the point at which `mean` is dropped, `sum` is 3, `count` is 2, and | |
635 | therefore `mean` is 1.5. But since `sum` continues to accumulate even after `mean` | |
636 | has been dropped, the value of `mean` continues to change. If you want to remember | |
637 | the value of `mean` at the point it is dropped, you should save its value into | |
638 | a local variable. | |
639 | ||
640 | The following rules more precisely specify how droppable and non-droppable | |
641 | accumulators behave within an accumulator set. | |
642 | ||
643 | * There are two types of accumulators: droppable and non-droppable. | |
644 | The default is non-droppable. | |
645 | * For any feature `X`, both `X` and `droppable<X>` satisfy the `X` dependency. | |
646 | * If feature `X` depends on `Y` and `Z`, then `droppable<X>` depends on | |
647 | `droppable<Y>` and `droppable<Z>`. | |
648 | * All accumulators have `add_ref()` and `drop()` member functions. | |
649 | * For non-droppable accumulators, `drop()` is a no-op, and `add_ref()` | |
650 | invokes `add_ref()` on all accumulators corresponding to the features | |
651 | upon which the current accumulator depends. | |
652 | * Droppable accumulators have a reference count and define `add_ref()` | |
653 | and `drop()` to manipulate the reference count. | |
654 | * For droppable accumulators, `add_ref()` increments the accumulator's | |
655 | reference count, and also `add_ref()`'s the accumulators corresponding | |
656 | to the features upon which the current accumulator depends. | |
657 | * For droppable accumulators, `drop()` decrements the accumulator's | |
658 | reference count, and also `drop()`'s the accumulators corresponding to | |
659 | the features upon which the current accumulator depends. | |
660 | * The accumulator_set constructor walks the list of *user-specified* | |
661 | features and `add_ref()`'s the accumulator that corresponds to each of | |
662 | them. (Note: that means that an accumulator that is not user-specified | |
663 | but in the set merely to satisfy a dependency will be dropped as soon | |
664 | as all its dependencies have been dropped. Ones that have been user | |
665 | specified are not dropped until their dependencies have been | |
666 | dropped *and* the user has explicitly dropped the accumulator.) | |
667 | * Droppable accumulators check their reference count in their | |
668 | accumulate member function. If the reference count is 0, the function | |
669 | is a no-op. | |
670 | * Users are not allowed to drop a feature that is not user-specified and | |
671 | marked as droppable. | |
672 | ||
673 | And as an optimization: | |
674 | ||
675 | * If the user specifies the non-droppable feature `X`, which depends on `Y` | |
676 | and `Z`, then the accumulators for `Y` and `Z` can be safely made | |
677 | non-droppable, as well as any accumulators on which they depend. | |
678 | ||
679 | [endsect] | |
680 | ||
681 | [section Defining a New Feature] | |
682 | ||
683 | Once we have implemented an accumulator, we must define a feature for it so | |
684 | that users can specify the feature when declaring an _accumulator_set_. We | |
685 | typically put the features into a nested namespace, so that later we can | |
686 | define an extractor of the same name. All features must satisfy the | |
687 | [link accumulators.user_s_guide.the_accumulators_framework.concepts.feature_concept | |
688 | Feature Concept]. Using _depends_on_ makes satisfying the concept simple. | |
689 | Below is an example of a feature definition. | |
690 | ||
691 | namespace boost { namespace accumulators { namespace tag { | |
692 | ||
693 | struct mean // Features should inherit from | |
694 | : depends_on< count, sum > // depends_on<> to specify dependencies | |
695 | { | |
696 | // Define a nested typedef called 'impl' that specifies which | |
697 | // accumulator implements this feature. | |
698 | typedef accumulators::impl::mean_accumulator< mpl::_1 > impl; | |
699 | }; | |
700 | ||
701 | }}} | |
702 | ||
703 | The only two things we must do to define the `mean` feature is to specify the | |
704 | dependencies with _depends_on_ and define the nested `impl` typedef. Even features | |
705 | that have no dependencies should inherit from _depends_on_. The nested `impl` type | |
706 | must be an _mpl_lambda_expression_. The result of | |
707 | `mpl::apply< impl, _sample_type_, _weight_type_ >::type` must be | |
708 | be the type of the accumulator that implements this feature. The use of _mpl_ | |
709 | placeholders like `mpl::_1` make it especially easy to make a template such | |
710 | as `mean_accumulator<>` an _mpl_lambda_expression_. Here, `mpl::_1` will be | |
711 | replaced with the sample type. Had we used `mpl::_2`, it would have been replaced | |
712 | with the weight type. | |
713 | ||
714 | What about accumulator types that are not templates? If you have a `foo_accumulator` | |
715 | which is a plain struct and not a template, you could turn it into an | |
716 | _mpl_lambda_expression_ using `mpl::always<>`, like this: | |
717 | ||
718 | // An MPL lambda expression that always evaluates to | |
719 | // foo_accumulator: | |
720 | typedef mpl::always< foo_accumulator > impl; | |
721 | ||
722 | If you are ever unsure, or if you are not comfortable with MPL lambda expressions, | |
723 | you could always define `impl` explicitly: | |
724 | ||
725 | // Same as 'typedef mpl::always< foo_accumulator > impl;' | |
726 | struct impl | |
727 | { | |
728 | template< typename Sample, typename Weight > | |
729 | struct apply | |
730 | { | |
731 | typedef foo_accumulator type; | |
732 | }; | |
733 | }; | |
734 | ||
735 | Here, `impl` is a binary [@../../libs/mpl/doc/refmanual/metafunction-class.html | |
736 | MPL Metafunction Class], which is a kind of _mpl_lambda_expression_. The nested | |
737 | `apply<>` template is part of the metafunction class protocol and tells MPL how | |
738 | to build the accumulator type given the sample and weight types. | |
739 | ||
740 | All features must also provide a nested `is_weight_accumulator` typedef. It must | |
741 | be either `mpl::true_` or `mpl::false_`. _depends_on_ provides a default of | |
742 | `mpl::false_` for all features that inherit from it, but that can be overridden | |
743 | (or hidden, technically speaking) in the derived type. When the feature represents | |
744 | an accumulation of information about the weights instead of the samples, we | |
745 | can mark this feature as such with `typedef mpl::true_ is_weight_accumulator;`. | |
746 | The weight accumulators are made external if the weight type is specified using | |
747 | the _external_ template. | |
748 | ||
749 | [endsect] | |
750 | ||
751 | [section Defining a New Extractor] | |
752 | ||
753 | Now that we have an accumulator and a feature, the only thing lacking is a way | |
754 | to get results from the accumulator set. The Accumulators Framework provides the | |
755 | _extractor_ class template to make it simple to define an extractor for your | |
756 | feature. Here's an extractor for the `mean` feature we defined above: | |
757 | ||
758 | namespace boost { | |
759 | namespace accumulators { // By convention, we put extractors | |
760 | namespace extract { // in the 'extract' namespace | |
761 | ||
762 | extractor< tag::mean > const mean = {}; // Simply define our extractor with | |
763 | // our feature tag, like this. | |
764 | } | |
765 | using extract::mean; // Pull the extractor into the | |
766 | // enclosing namespace. | |
767 | }} | |
768 | ||
769 | Once defined, the `mean` extractor can be used to extract the result of the | |
770 | `tag::mean` feature from an _accumulator_set_. | |
771 | ||
772 | Parameterized features complicate this simple picture. Consider the `moment` | |
773 | feature, for calculating the [^['N]]-th moment, where [^['N]] is specified as | |
774 | a template parameter: | |
775 | ||
776 | // An accumulator set for calculating the N-th moment, for N == 2 ... | |
777 | accumulator_set< double, features< tag::moment<2> > > acc; | |
778 | ||
779 | // ... add some data ... | |
780 | ||
781 | // Display the 2nd moment ... | |
782 | std::cout << "2nd moment is " << accumulators::moment<2>(acc) << std::endl; | |
783 | ||
784 | In the expression `accumulators::moment<2>(acc)`, what is `moment`? It cannot be an object -- | |
785 | the syntax of C++ will not allow it. Clearly, if we want to provide this syntax, | |
786 | we must make `moment` a function template. Here's what the definition of the | |
787 | `moment` extractor looks like: | |
788 | ||
789 | namespace boost { | |
790 | namespace accumulators { // By convention, we put extractors | |
791 | namespace extract { // in the 'extract' namespace | |
792 | ||
793 | template<int N, typename AccumulatorSet> | |
794 | typename mpl::apply<AccumulatorSet, tag::moment<N> >::type::result_type | |
795 | moment(AccumulatorSet const &acc) | |
796 | { | |
797 | return extract_result<tag::moment<N> >(acc); | |
798 | } | |
799 | ||
800 | } | |
801 | using extract::moment; // Pull the extractor into the | |
802 | // enclosing namespace. | |
803 | }} | |
804 | ||
805 | The return type deserves some explanation. Every _accumulator_set_ type | |
806 | is actually a unary [@../../libs/mpl/doc/refmanual/metafunction-class.html | |
807 | MPL Metafunction Class]. When you `mpl::apply<>` an _accumulator_set_ and | |
808 | a feature, the result is the type of the accumulator within the set that | |
809 | implements that feature. And every accumulator provides a nested `result_type` | |
810 | typedef that tells what its return type is. The extractor simply delegates | |
811 | its work to the _extract_result_ function. | |
812 | ||
813 | [endsect] | |
814 | ||
815 | [section Controlling Dependencies] | |
816 | ||
817 | The feature-based dependency resolution of the Accumulators Framework is | |
818 | designed to allow multiple different implementation strategies for each | |
819 | feature. For instance, two different accumulators may calculate the same | |
820 | quantity with different rounding modes, or using different algorithms with | |
821 | different size/speed tradeoffs. Other accumulators that depend on that | |
822 | quantity shouldn't care how it's calculated. The Accumulators Framework | |
823 | handles this by allowing several different accumulators satisfy the same | |
824 | feature. | |
825 | ||
826 | [*Aliasing feature dependencies with [^feature_of<>]] | |
827 | ||
828 | Imagine that you would like to implement the hypothetical ['fubar] statistic, | |
829 | and that you know two ways to calculate fubar on a bunch of samples: an | |
830 | accurate but slow calculation and an approximate but fast calculation. You | |
831 | might opt to make the accurate calculation the default, so you implement | |
832 | two accumulators and call them `impl::fubar_impl` and `impl::fast_fubar_impl`. | |
833 | You would also define the `tag::fubar` and `tag::fast_fubar` features as described | |
834 | [link accumulators.user_s_guide.the_accumulators_framework.extending_the_accumulators_framework.defining_a_new_feature above]. | |
835 | Now, you would like to inform the Accumulators Framework that these two features | |
836 | are the same from the point of view of dependency resolution. You can do that | |
837 | with _feature_of_, as follows: | |
838 | ||
839 | namespace boost { namespace accumulators | |
840 | { | |
841 | // For the purposes of feature-based dependency resolution, | |
842 | // fast_fubar provides the same feature as fubar | |
843 | template<> | |
844 | struct feature_of<tag::fast_fubar> | |
845 | : feature_of<tag::fubar> | |
846 | { | |
847 | }; | |
848 | }} | |
849 | ||
850 | The above code instructs the Accumulators Framework that, if another accumulator | |
851 | in the set depends on the `tag::fubar` feature, the `tag::fast_fubar` feature | |
852 | is an acceptable substitute. | |
853 | ||
854 | [*Registering feature variants with [^as_feature<>]] | |
855 | ||
856 | You may have noticed that some feature variants in the Accumulators Framework can be | |
857 | specified with a nicer syntax. For instance, instead of `tag::mean` and `tag::immediate_mean` | |
858 | you can specify them with `tag::mean(lazy)` and `tag::mean(immediate)` respectively. | |
859 | These are merely aliases, but the syntax makes the relationship between the two clearer. | |
860 | You can create these feature aliases with the _as_feature_ trait. Given the fubar example | |
861 | above, you might decide to alias `tag::fubar(accurate)` with `tag::fubar` and | |
862 | `tag::fubar(fast)` with `tag::fast_fubar`. You would do that as follows: | |
863 | ||
864 | namespace boost { namespace accumulators | |
865 | { | |
866 | struct fast {}; // OK to leave these tags empty | |
867 | struct accurate {}; | |
868 | ||
869 | template<> | |
870 | struct as_feature<tag::fubar(accurate)> | |
871 | { | |
872 | typedef tag::fubar type; | |
873 | }; | |
874 | ||
875 | template<> | |
876 | struct as_feature<tag::fubar(fast)> | |
877 | { | |
878 | typedef tag::fast_fubar type; | |
879 | }; | |
880 | }} | |
881 | ||
882 | Once you have done this, users of your fubar accumulator can request the `tag::fubar(fast)` | |
883 | and `tag::fubar(accurate)` features when defining their `accumulator_set`s and get the correct | |
884 | accumulator. | |
885 | ||
886 | [endsect] | |
887 | ||
888 | [section:operators_ex Specializing Numeric Operators] | |
889 | ||
890 | This section describes how to adapt third-party numeric types to work with the Accumulator | |
891 | Framework. | |
892 | ||
893 | Rather than relying on the built-in operators, the Accumulators Framework relies on functions | |
894 | and operator overloads defined in the | |
895 | [link accumulators.user_s_guide.the_accumulators_framework.numeric_operators_sub_library | |
896 | Numeric Operators Sub-Library] for many of its numeric operations. This is so that it | |
897 | is possible to assign non-standard meanings to arithmetic operations. For instance, when | |
898 | calculating an average by dividing two integers, the standard integer division behavior | |
899 | would be mathematically incorrect for most statistical quantities. So rather than use `x / y`, | |
900 | the Accumulators Framework uses `numeric::fdiv(x, y)`, which does floating-point division | |
901 | even if both `x` and `y` are integers. | |
902 | ||
903 | Another example where the Numeric Operators Sub-Library is useful is when a type does not | |
904 | define the operator overloads required to use it for some statistical calculations. For instance, | |
905 | `std::vector<>` does not overload any arithmetic operators, yet it may be useful to use | |
906 | `std::vector<>` as a sample or variate type. The Numeric Operators Sub-Library | |
907 | defines the necessary operator overloads in the `boost::numeric::operators` namespace, | |
908 | which is brought into scope by the Accumulators Framework with a using directive. | |
909 | ||
910 | [*Numeric Function Objects and Tag Dispatching] | |
911 | ||
912 | How are the numeric function object defined by the Numeric Operators Sub-Library made | |
913 | to work with types such as `std::vector<>`? The free functions in the `boost::numeric` namespace | |
914 | are implemented in terms of the function objects in the `boost::numeric::functional` namespace, | |
915 | so to make `boost::numeric::fdiv()` do something sensible with a `std::vector<>`, for instance, | |
916 | we'll need to partially specialize the `boost::numeric::functional::fdiv<>` function object. | |
917 | ||
918 | The functional objects make use of a technique known as | |
919 | [@http://www.boost.org/community/generic_programming.html#tag_dispatching ['tag dispatching]] to | |
920 | select the proper implementation for the given operands. It works as follows: | |
921 | ||
922 | namespace boost { namespace numeric { namespace functional | |
923 | { | |
924 | // Metafunction for looking up the tag associated with | |
925 | // a given numeric type T. | |
926 | template<typename T> | |
927 | struct tag | |
928 | { | |
929 | // by default, all types have void as a tag type | |
930 | typedef void type; | |
931 | }; | |
932 | ||
933 | // Forward declaration looks up the tag types of each operand | |
934 | template< | |
935 | typename Left | |
936 | , typename Right | |
937 | , typename LeftTag = typename tag<Left>::type | |
938 | , typename RightTag = typename tag<Right>::type | |
939 | > | |
940 | struct fdiv; | |
941 | }}} | |
942 | ||
943 | If you have some user-defined type `MyDouble` for which you would like to customize the behavior | |
944 | of `numeric::fdiv()`, you would specialize `numeric::functional::fdiv<>` by | |
945 | first defining a tag type, as shown below: | |
946 | ||
947 | namespace boost { namespace numeric { namespace functional | |
948 | { | |
949 | // Tag type for MyDouble | |
950 | struct MyDoubleTag {}; | |
951 | ||
952 | // Specialize tag<> for MyDouble. | |
953 | // This only needs to be done once. | |
954 | template<> | |
955 | struct tag<MyDouble> | |
956 | { | |
957 | typedef MyDoubleTag type; | |
958 | }; | |
959 | ||
960 | // Specify how to divide a MyDouble by an integral count | |
961 | template<typename Left, typename Right> | |
962 | struct fdiv<Left, Right, MyDoubleTag, void> | |
963 | { | |
964 | // Define the type of the result | |
965 | typedef ... result_type; | |
966 | ||
967 | result_type operator()(Left & left, Right & right) const | |
968 | { | |
969 | return ...; | |
970 | } | |
971 | }; | |
972 | }}} | |
973 | ||
974 | Once you have done this, `numeric::fdiv()` will use your specialization | |
975 | of `numeric::functional::fdiv<>` when the first argument is a `MyDouble` | |
976 | object. All of the function objects in the Numeric Operators Sub-Library can | |
977 | be customized in a similar fashion. | |
978 | ||
979 | [endsect] | |
980 | ||
981 | [endsect] | |
982 | ||
983 | [section Concepts] | |
984 | ||
985 | [h2 Accumulator Concept] | |
986 | ||
987 | In the following table, `Acc` is the type of an accumulator, `acc` and `acc2` are objects of type | |
988 | `Acc`, and `args` is the name of an argument pack from the _parameter_ library. | |
989 | ||
990 | [table Accumulator Requirements | |
991 | [[[*Expression]] [[*Return type]] [[*Assertion / Note / | |
992 | Pre- / Post-condition]]] | |
993 | [[`Acc::result_type`] [['implementation | |
994 | defined]] [The type returned by `Acc::result()`.]] | |
995 | [[`Acc acc(args)`] [none] [Construct from an argument pack.]] | |
996 | [[`Acc acc(acc2)`] [none] [Post: `acc.result(args)` is equivalent | |
997 | to `acc2.result(args)`]] | |
998 | [[`acc(args)`] [['unspecified]] []] | |
999 | [[`acc.on_drop(args)`] [['unspecified]] []] | |
1000 | [[`acc.result(args)`] [`Acc::result_type`] []] | |
1001 | ] | |
1002 | ||
1003 | [h2 Feature Concept] | |
1004 | ||
1005 | In the following table, `F` is the type of a feature and `S` is some scalar type. | |
1006 | ||
1007 | [table Feature Requirements | |
1008 | [[[*Expression]] [[*Return type]] [[*Assertion / Note / | |
1009 | Pre- / Post-condition]]] | |
1010 | [[`F::dependencies`] [['unspecified]] [An MPL sequence of other features on | |
1011 | which `F` depends.]] | |
1012 | [[`F::is_weight_accumulator`] [`mpl::true_` or | |
1013 | `mpl::false_`] [`mpl::true_` if the accumulator for | |
1014 | this feature should be made external | |
1015 | when the weight type for the accumulator | |
1016 | set is `external<S>`, `mpl::false_` | |
1017 | otherwise.]] | |
1018 | [[`F::impl`] [['unspecified]] [An _mpl_lambda_expression_ that | |
1019 | returns the type of the accumulator that | |
1020 | implements this feature when passed a | |
1021 | sample type and a weight type.]] | |
1022 | ] | |
1023 | ||
1024 | [endsect] | |
1025 | ||
1026 | [endsect] | |
1027 | ||
1028 | [section The Statistical Accumulators Library] | |
1029 | ||
1030 | The Statistical Accumulators Library defines accumulators for incremental statistical | |
1031 | computations. It is built on top of [link accumulators.user_s_guide.the_accumulators_framework | |
1032 | The Accumulator Framework]. | |
1033 | ||
1034 | [section:count count] | |
1035 | ||
1036 | The `count` feature is a simple counter that tracks the | |
1037 | number of samples pushed into the accumulator set. | |
1038 | ||
1039 | [variablelist | |
1040 | [[Result Type] [`` | |
1041 | std::size_t | |
1042 | ``]] | |
1043 | [[Depends On] [['none]]] | |
1044 | [[Variants] [['none]]] | |
1045 | [[Initialization Parameters] [['none]]] | |
1046 | [[Accumulator Parameters] [['none]]] | |
1047 | [[Extractor Parameters] [['none]]] | |
1048 | [[Accumulator Complexity] [O(1)]] | |
1049 | [[Extractor Complexity] [O(1)]] | |
1050 | ] | |
1051 | ||
1052 | [*Header] | |
1053 | [def _COUNT_HPP_ [headerref boost/accumulators/statistics/count.hpp]] | |
1054 | ||
1055 | #include <_COUNT_HPP_> | |
1056 | ||
1057 | [*Example] | |
1058 | ||
1059 | accumulator_set<int, features<tag::count> > acc; | |
1060 | acc(0); | |
1061 | acc(0); | |
1062 | acc(0); | |
1063 | assert(3 == count(acc)); | |
1064 | ||
1065 | [*See also] | |
1066 | ||
1067 | * [classref boost::accumulators::impl::count_impl `count_impl`] | |
1068 | ||
1069 | [endsect] | |
1070 | ||
1071 | [section:covariance covariance] | |
1072 | ||
1073 | The `covariance` feature is an iterative Monte Carlo estimator for the covariance. | |
1074 | It is specified as `tag::covariance<_variate_type_, _variate_tag_>`. | |
1075 | ||
1076 | [variablelist | |
1077 | [[Result Type] [`` | |
1078 | numeric::functional::outer_product< | |
1079 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1080 | , numeric::functional::fdiv<_variate_type_, std::size_t>::result_type | |
1081 | >::result_type | |
1082 | ``]] | |
1083 | [[Depends On] [`count` \n `mean` \n `mean_of_variates<_variate_type_, _variate_tag_>`]] | |
1084 | [[Variants] [`abstract_covariance`]] | |
1085 | [[Initialization Parameters] [['none]]] | |
1086 | [[Accumulator Parameters] [[~variate-tag]]] | |
1087 | [[Extractor Parameters] [['none]]] | |
1088 | [[Accumulator Complexity] [TODO]] | |
1089 | [[Extractor Complexity] [O(1)]] | |
1090 | ] | |
1091 | ||
1092 | [*Headers] | |
1093 | [def _COVARIANCE_HPP_ [headerref boost/accumulators/statistics/covariance.hpp]] | |
1094 | [def _COVARIATE_HPP_ [headerref boost/accumulators/statistics/variates/covariate.hpp]] | |
1095 | ||
1096 | #include <_COVARIANCE_HPP_> | |
1097 | #include <_COVARIATE_HPP_> | |
1098 | ||
1099 | [*Example] | |
1100 | ||
1101 | accumulator_set<double, stats<tag::covariance<double, tag::covariate1> > > acc; | |
1102 | acc(1., covariate1 = 2.); | |
1103 | acc(1., covariate1 = 4.); | |
1104 | acc(2., covariate1 = 3.); | |
1105 | acc(6., covariate1 = 1.); | |
1106 | assert(covariance(acc) == -1.75); | |
1107 | ||
1108 | [*See also] | |
1109 | ||
1110 | * [classref boost::accumulators::impl::covariance_impl [^covariance_impl]] | |
1111 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1112 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.mean [^mean]] | |
1113 | ||
1114 | [endsect] | |
1115 | ||
1116 | [section:density density] | |
1117 | ||
1118 | The `tag::density` feature returns a histogram of the sample distribution. For more | |
1119 | implementation details, see [classref boost::accumulators::impl::density_impl [^density_impl]]. | |
1120 | ||
1121 | [variablelist | |
1122 | [[Result Type] [`` | |
1123 | iterator_range< | |
1124 | std::vector< | |
1125 | std::pair< | |
1126 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1127 | , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1128 | > | |
1129 | >::iterator | |
1130 | > | |
1131 | ``]] | |
1132 | [[Depends On] [`count` \n `min` \n `max`]] | |
1133 | [[Variants] [['none]]] | |
1134 | [[Initialization Parameters] [`density::cache_size` \n `density::num_bins`]] | |
1135 | [[Accumulator Parameters] [['none]]] | |
1136 | [[Extractor Parameters] [['none]]] | |
1137 | [[Accumulator Complexity] [TODO]] | |
1138 | [[Extractor Complexity] [O(N), when N is `density::num_bins`]] | |
1139 | ] | |
1140 | ||
1141 | [*Header] | |
1142 | [def _DENSITY_HPP_ [headerref boost/accumulators/statistics/density.hpp]] | |
1143 | ||
1144 | #include <_DENSITY_HPP_> | |
1145 | ||
1146 | [*Note] | |
1147 | ||
1148 | Results from the `density` accumulator can only be extracted after the number of | |
1149 | samples meets or exceeds the cache size. | |
1150 | ||
1151 | [/ TODO add example ] | |
1152 | ||
1153 | [*See also] | |
1154 | ||
1155 | * [classref boost::accumulators::impl::density_impl [^density_impl]] | |
1156 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1157 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.min [^min]] | |
1158 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.max [^max]] | |
1159 | ||
1160 | [endsect] | |
1161 | ||
1162 | [section:error_of_mean error_of<mean>] | |
1163 | ||
1164 | The `error_of<mean>` feature calculates the error of the mean feature. It is equal to | |
1165 | `sqrt(variance / (count - 1))`. | |
1166 | ||
1167 | [variablelist | |
1168 | [[Result Type] [`` | |
1169 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1170 | ``]] | |
1171 | [[Depends On] [`count` \n `variance`]] | |
1172 | [[Variants] [`error_of<immediate_mean>`]] | |
1173 | [[Initialization Parameters] [['none]]] | |
1174 | [[Accumulator Parameters] [['none]]] | |
1175 | [[Extractor Parameters] [['none]]] | |
1176 | [[Accumulator Complexity] [TODO]] | |
1177 | [[Extractor Complexity] [O(1)]] | |
1178 | ] | |
1179 | ||
1180 | [*Header] | |
1181 | [def _ERROR_OF_HPP_ [headerref boost/accumulators/statistics/error_of.hpp]] | |
1182 | [def _ERROR_OF_MEAN_HPP_ [headerref boost/accumulators/statistics/error_of_mean.hpp]] | |
1183 | ||
1184 | #include <_ERROR_OF_HPP_> | |
1185 | #include <_ERROR_OF_MEAN_HPP_> | |
1186 | ||
1187 | [*Example] | |
1188 | ||
1189 | accumulator_set<double, stats<tag::error_of<tag::mean> > > acc; | |
1190 | acc(1.1); | |
1191 | acc(1.2); | |
1192 | acc(1.3); | |
1193 | assert(0.057735 == error_of<tag::mean>(acc)); | |
1194 | ||
1195 | [*See also] | |
1196 | ||
1197 | * [classref boost::accumulators::impl::error_of_mean_impl [^error_of_mean_impl]] | |
1198 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1199 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.variance [^variance]] | |
1200 | ||
1201 | [endsect] | |
1202 | ||
1203 | [section:extended_p_square extended_p_square] | |
1204 | ||
1205 | Multiple quantile estimation with the extended [^P^2] algorithm. For further | |
1206 | details, see [classref boost::accumulators::impl::extended_p_square_impl [^extended_p_square_impl]]. | |
1207 | ||
1208 | [variablelist | |
1209 | [[Result Type] [`` | |
1210 | boost::iterator_range< | |
1211 | _implementation_defined_ | |
1212 | > | |
1213 | ``]] | |
1214 | [[Depends On] [`count`]] | |
1215 | [[Variants] [['none]]] | |
1216 | [[Initialization Parameters] [`tag::extended_p_square::probabilities`]] | |
1217 | [[Accumulator Parameters] [['none]]] | |
1218 | [[Extractor Parameters] [['none]]] | |
1219 | [[Accumulator Complexity] [TODO]] | |
1220 | [[Extractor Complexity] [O(1)]] | |
1221 | ] | |
1222 | ||
1223 | [*Header] | |
1224 | [def _EXTENDED_P_SQUARE_HPP_ [headerref boost/accumulators/statistics/extended_p_square.hpp]] | |
1225 | ||
1226 | #include <_EXTENDED_P_SQUARE_HPP_> | |
1227 | ||
1228 | [*Example] | |
1229 | ||
1230 | boost::array<double> probs = {0.001,0.01,0.1,0.25,0.5,0.75,0.9,0.99,0.999}; | |
1231 | accumulator_set<double, stats<tag::extended_p_square> > | |
1232 | acc(tag::extended_p_square::probabilities = probs); | |
1233 | ||
1234 | boost::lagged_fibonacci607 rng; // a random number generator | |
1235 | for (int i=0; i<10000; ++i) | |
1236 | acc(rng()); | |
1237 | ||
1238 | BOOST_CHECK_CLOSE(extended_p_square(acc)[0], probs[0], 25); | |
1239 | BOOST_CHECK_CLOSE(extended_p_square(acc)[1], probs[1], 10); | |
1240 | BOOST_CHECK_CLOSE(extended_p_square(acc)[2], probs[2], 5); | |
1241 | ||
1242 | for (std::size_t i=3; i < probs.size(); ++i) | |
1243 | { | |
1244 | BOOST_CHECK_CLOSE(extended_p_square(acc)[i], probs[i], 2); | |
1245 | } | |
1246 | ||
1247 | [*See also] | |
1248 | ||
1249 | * [classref boost::accumulators::impl::extended_p_square_impl [^extended_p_square_impl]] | |
1250 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1251 | ||
1252 | [endsect] | |
1253 | ||
1254 | [section:extended_p_square_quantile extended_p_square_quantile ['and variants]] | |
1255 | ||
1256 | Quantile estimation using the extended [^P^2] algorithm for weighted and unweighted samples. | |
1257 | By default, the calculation is linear and unweighted, but quadratic and weighted variants | |
1258 | are also provided. For further implementation details, see | |
1259 | [classref boost::accumulators::impl::extended_p_square_quantile_impl [^extended_p_square_quantile_impl]]. | |
1260 | ||
1261 | All the variants share the `tag::quantile` feature and can be extracted using the `quantile()` | |
1262 | extractor. | |
1263 | ||
1264 | [variablelist | |
1265 | [[Result Type] [`` | |
1266 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1267 | ``]] | |
1268 | [[Depends On] [weighted variants depend on `weighted_extended_p_square` \n | |
1269 | unweighted variants depend on `extended_p_square`]] | |
1270 | [[Variants] [`extended_p_square_quantile_quadratic` \n | |
1271 | `weighted_extended_p_square_quantile` \n | |
1272 | `weighted_extended_p_square_quantile_quadratic`]] | |
1273 | [[Initialization Parameters] [`tag::extended_p_square::probabilities`]] | |
1274 | [[Accumulator Parameters] [`weight` for the weighted variants]] | |
1275 | [[Extractor Parameters] [`quantile_probability`]] | |
1276 | [[Accumulator Complexity] [TODO]] | |
1277 | [[Extractor Complexity] [O(N) where N is the count of probabilities.]] | |
1278 | ] | |
1279 | ||
1280 | [*Header] | |
1281 | [def _EXTENDED_P_SQUARE_QUANTILE_HPP_ [headerref boost/accumulators/statistics/extended_p_square_quantile.hpp]] | |
1282 | ||
1283 | #include <_EXTENDED_P_SQUARE_QUANTILE_HPP_> | |
1284 | ||
1285 | [*Example] | |
1286 | ||
1287 | typedef accumulator_set<double, stats<tag::extended_p_square_quantile> > | |
1288 | accumulator_t; | |
1289 | typedef accumulator_set<double, stats<tag::weighted_extended_p_square_quantile>, double > | |
1290 | accumulator_t_weighted; | |
1291 | typedef accumulator_set<double, stats<tag::extended_p_square_quantile(quadratic)> > | |
1292 | accumulator_t_quadratic; | |
1293 | typedef accumulator_set<double, stats<tag::weighted_extended_p_square_quantile(quadratic)>, double > | |
1294 | accumulator_t_weighted_quadratic; | |
1295 | ||
1296 | // tolerance | |
1297 | double epsilon = 1; | |
1298 | ||
1299 | // a random number generator | |
1300 | boost::lagged_fibonacci607 rng; | |
1301 | ||
1302 | boost::array<double> probs = { 0.990, 0.991, 0.992, 0.993, 0.994, | |
1303 | 0.995, 0.996, 0.997, 0.998, 0.999 }; | |
1304 | accumulator_t acc(extended_p_square_probabilities = probs); | |
1305 | accumulator_t_weighted acc_weighted(extended_p_square_probabilities = probs); | |
1306 | accumulator_t_quadratic acc2(extended_p_square_probabilities = probs); | |
1307 | accumulator_t_weighted_quadratic acc_weighted2(extended_p_square_probabilities = probs); | |
1308 | ||
1309 | for (int i=0; i<10000; ++i) | |
1310 | { | |
1311 | double sample = rng(); | |
1312 | acc(sample); | |
1313 | acc2(sample); | |
1314 | acc_weighted(sample, weight = 1.); | |
1315 | acc_weighted2(sample, weight = 1.); | |
1316 | } | |
1317 | ||
1318 | for (std::size_t i = 0; i < probs.size() - 1; ++i) | |
1319 | { | |
1320 | BOOST_CHECK_CLOSE( | |
1321 | quantile(acc, quantile_probability = 0.99025 + i*0.001) | |
1322 | , 0.99025 + i*0.001 | |
1323 | , epsilon | |
1324 | ); | |
1325 | BOOST_CHECK_CLOSE( | |
1326 | quantile(acc2, quantile_probability = 0.99025 + i*0.001) | |
1327 | , 0.99025 + i*0.001 | |
1328 | , epsilon | |
1329 | ); | |
1330 | BOOST_CHECK_CLOSE( | |
1331 | quantile(acc_weighted, quantile_probability = 0.99025 + i*0.001) | |
1332 | , 0.99025 + i*0.001 | |
1333 | , epsilon | |
1334 | ); | |
1335 | BOOST_CHECK_CLOSE( | |
1336 | quantile(acc_weighted2, quantile_probability = 0.99025 + i*0.001) | |
1337 | , 0.99025 + i*0.001 | |
1338 | , epsilon | |
1339 | ); | |
1340 | } | |
1341 | ||
1342 | [*See also] | |
1343 | ||
1344 | * [classref boost::accumulators::impl::extended_p_square_quantile_impl [^extended_p_square_quantile_impl]] | |
1345 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.extended_p_square [^extended_p_square]] | |
1346 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_extended_p_square [^weighted_extended_p_square]] | |
1347 | ||
1348 | [endsect] | |
1349 | ||
1350 | [section:kurtosis kurtosis] | |
1351 | ||
1352 | The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the | |
1353 | square of the 2nd central moment (the variance) of the samples, minus 3. The term [^-3] is added | |
1354 | in order to ensure that the normal distribution has zero kurtosis. For more implementation | |
1355 | details, see [classref boost::accumulators::impl::kurtosis_impl [^kurtosis_impl]] | |
1356 | ||
1357 | [variablelist | |
1358 | [[Result Type] [`` | |
1359 | numeric::functional::fdiv<_sample_type_, _sample_type_>::result_type | |
1360 | ``]] | |
1361 | [[Depends On] [`mean` \n `moment<2>` \n `moment<3>` \n `moment<4>`]] | |
1362 | [[Variants] [['none]]] | |
1363 | [[Initialization Parameters] [['none]]] | |
1364 | [[Accumulator Parameters] [['none]]] | |
1365 | [[Extractor Parameters] [['none]]] | |
1366 | [[Accumulator Complexity] [O(1)]] | |
1367 | [[Extractor Complexity] [O(1)]] | |
1368 | ] | |
1369 | ||
1370 | [*Header] | |
1371 | [def _KURTOSIS_HPP_ [headerref boost/accumulators/statistics/kurtosis.hpp]] | |
1372 | ||
1373 | #include <_KURTOSIS_HPP_> | |
1374 | ||
1375 | [*Example] | |
1376 | ||
1377 | accumulator_set<int, stats<tag::kurtosis > > acc; | |
1378 | ||
1379 | acc(2); | |
1380 | acc(7); | |
1381 | acc(4); | |
1382 | acc(9); | |
1383 | acc(3); | |
1384 | ||
1385 | BOOST_CHECK_EQUAL( mean(acc), 5 ); | |
1386 | BOOST_CHECK_EQUAL( accumulators::moment<2>(acc), 159./5. ); | |
1387 | BOOST_CHECK_EQUAL( accumulators::moment<3>(acc), 1171./5. ); | |
1388 | BOOST_CHECK_EQUAL( accumulators::moment<4>(acc), 1863 ); | |
1389 | BOOST_CHECK_CLOSE( kurtosis(acc), -1.39965397924, 1e-6 ); | |
1390 | ||
1391 | [*See also] | |
1392 | ||
1393 | * [classref boost::accumulators::impl::kurtosis_impl [^kurtosis_impl]] | |
1394 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.mean [^mean]] | |
1395 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.moment [^moment]] | |
1396 | ||
1397 | [endsect] | |
1398 | ||
1399 | [section:max max] | |
1400 | ||
1401 | Calculates the maximum value of all the samples. | |
1402 | ||
1403 | [variablelist | |
1404 | [[Result Type] [`` | |
1405 | _sample_type_ | |
1406 | ``]] | |
1407 | [[Depends On] [['none]]] | |
1408 | [[Variants] [['none]]] | |
1409 | [[Initialization Parameters] [['none]]] | |
1410 | [[Accumulator Parameters] [['none]]] | |
1411 | [[Extractor Parameters] [['none]]] | |
1412 | [[Accumulator Complexity] [O(1)]] | |
1413 | [[Extractor Complexity] [O(1)]] | |
1414 | ] | |
1415 | ||
1416 | [*Header] | |
1417 | [def _MAX_HPP_ [headerref boost/accumulators/statistics/max.hpp]] | |
1418 | ||
1419 | #include <_MAX_HPP_> | |
1420 | ||
1421 | [*Example] | |
1422 | ||
1423 | accumulator_set<int, stats<tag::max> > acc; | |
1424 | ||
1425 | acc(1); | |
1426 | BOOST_CHECK_EQUAL(1, (max)(acc)); | |
1427 | ||
1428 | acc(0); | |
1429 | BOOST_CHECK_EQUAL(1, (max)(acc)); | |
1430 | ||
1431 | acc(2); | |
1432 | BOOST_CHECK_EQUAL(2, (max)(acc)); | |
1433 | ||
1434 | [*See also] | |
1435 | ||
1436 | * [classref boost::accumulators::impl::max_impl [^max_impl]] | |
1437 | ||
1438 | [endsect] | |
1439 | ||
1440 | [section:mean mean ['and variants]] | |
1441 | ||
1442 | Calculates the mean of samples, weights or variates. The calculation is either | |
1443 | lazy (in the result extractor), or immediate (in the accumulator). The lazy implementation | |
1444 | is the default. For more implementation details, see | |
1445 | [classref boost::accumulators::impl::mean_impl [^mean_impl]] or. | |
1446 | [classref boost::accumulators::impl::immediate_mean_impl [^immediate_mean_impl]] | |
1447 | ||
1448 | [variablelist | |
1449 | [[Result Type] [For samples, `numeric::functional::fdiv<_sample_type_, std::size_t>::result_type` \n | |
1450 | For weights, `numeric::functional::fdiv<_weight_type_, std::size_t>::result_type` \n | |
1451 | For variates, `numeric::functional::fdiv<_variate_type_, std::size_t>::result_type`]] | |
1452 | [[Depends On] [`count` \n | |
1453 | The lazy mean of samples depends on `sum` \n | |
1454 | The lazy mean of weights depends on `sum_of_weights` \n | |
1455 | The lazy mean of variates depends on `sum_of_variates<>`]] | |
1456 | [[Variants] [`mean_of_weights` \n | |
1457 | `mean_of_variates<_variate_type_, _variate_tag_>` \n | |
1458 | `immediate_mean` \n | |
1459 | `immediate_mean_of_weights` \n | |
1460 | `immediate_mean_of_variates<_variate_type_, _variate_tag_>`]] | |
1461 | [[Initialization Parameters] [['none]]] | |
1462 | [[Accumulator Parameters] [['none]]] | |
1463 | [[Extractor Parameters] [['none]]] | |
1464 | [[Accumulator Complexity] [O(1)]] | |
1465 | [[Extractor Complexity] [O(1)]] | |
1466 | ] | |
1467 | ||
1468 | [*Header] | |
1469 | [def _MEAN_HPP_ [headerref boost/accumulators/statistics/mean.hpp]] | |
1470 | ||
1471 | #include <_MEAN_HPP_> | |
1472 | ||
1473 | [*Example] | |
1474 | ||
1475 | accumulator_set< | |
1476 | int | |
1477 | , stats< | |
1478 | tag::mean | |
1479 | , tag::mean_of_weights | |
1480 | , tag::mean_of_variates<int, tag::covariate1> | |
1481 | > | |
1482 | , int | |
1483 | > acc; | |
1484 | ||
1485 | acc(1, weight = 2, covariate1 = 3); | |
1486 | BOOST_CHECK_CLOSE(1., mean(acc), 1e-5); | |
1487 | BOOST_CHECK_EQUAL(1u, count(acc)); | |
1488 | BOOST_CHECK_EQUAL(2, sum(acc)); | |
1489 | BOOST_CHECK_CLOSE(2., mean_of_weights(acc), 1e-5); | |
1490 | BOOST_CHECK_CLOSE(3., (accumulators::mean_of_variates<int, tag::covariate1>(acc)), 1e-5); | |
1491 | ||
1492 | acc(0, weight = 4, covariate1 = 4); | |
1493 | BOOST_CHECK_CLOSE(0.33333333333333333, mean(acc), 1e-5); | |
1494 | BOOST_CHECK_EQUAL(2u, count(acc)); | |
1495 | BOOST_CHECK_EQUAL(2, sum(acc)); | |
1496 | BOOST_CHECK_CLOSE(3., mean_of_weights(acc), 1e-5); | |
1497 | BOOST_CHECK_CLOSE(3.5, (accumulators::mean_of_variates<int, tag::covariate1>(acc)), 1e-5); | |
1498 | ||
1499 | acc(2, weight = 9, covariate1 = 8); | |
1500 | BOOST_CHECK_CLOSE(1.33333333333333333, mean(acc), 1e-5); | |
1501 | BOOST_CHECK_EQUAL(3u, count(acc)); | |
1502 | BOOST_CHECK_EQUAL(20, sum(acc)); | |
1503 | BOOST_CHECK_CLOSE(5., mean_of_weights(acc), 1e-5); | |
1504 | BOOST_CHECK_CLOSE(5., (accumulators::mean_of_variates<int, tag::covariate1>(acc)), 1e-5); | |
1505 | ||
1506 | accumulator_set< | |
1507 | int | |
1508 | , stats< | |
1509 | tag::mean(immediate) | |
1510 | , tag::mean_of_weights(immediate) | |
1511 | , tag::mean_of_variates<int, tag::covariate1>(immediate) | |
1512 | > | |
1513 | , int | |
1514 | > acc2; | |
1515 | ||
1516 | acc2(1, weight = 2, covariate1 = 3); | |
1517 | BOOST_CHECK_CLOSE(1., mean(acc2), 1e-5); | |
1518 | BOOST_CHECK_EQUAL(1u, count(acc2)); | |
1519 | BOOST_CHECK_CLOSE(2., mean_of_weights(acc2), 1e-5); | |
1520 | BOOST_CHECK_CLOSE(3., (accumulators::mean_of_variates<int, tag::covariate1>(acc2)), 1e-5); | |
1521 | ||
1522 | acc2(0, weight = 4, covariate1 = 4); | |
1523 | BOOST_CHECK_CLOSE(0.33333333333333333, mean(acc2), 1e-5); | |
1524 | BOOST_CHECK_EQUAL(2u, count(acc2)); | |
1525 | BOOST_CHECK_CLOSE(3., mean_of_weights(acc2), 1e-5); | |
1526 | BOOST_CHECK_CLOSE(3.5, (accumulators::mean_of_variates<int, tag::covariate1>(acc2)), 1e-5); | |
1527 | ||
1528 | acc2(2, weight = 9, covariate1 = 8); | |
1529 | BOOST_CHECK_CLOSE(1.33333333333333333, mean(acc2), 1e-5); | |
1530 | BOOST_CHECK_EQUAL(3u, count(acc2)); | |
1531 | BOOST_CHECK_CLOSE(5., mean_of_weights(acc2), 1e-5); | |
1532 | BOOST_CHECK_CLOSE(5., (accumulators::mean_of_variates<int, tag::covariate1>(acc2)), 1e-5); | |
1533 | ||
1534 | [*See also] | |
1535 | ||
1536 | * [classref boost::accumulators::impl::mean_impl [^mean_impl]] | |
1537 | * [classref boost::accumulators::impl::immediate_mean_impl [^immediate_mean_impl]] | |
1538 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1539 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
1540 | ||
1541 | [endsect] | |
1542 | ||
1543 | [section:median median ['and variants]] | |
1544 | ||
1545 | Median estimation based on the [^P^2] quantile estimator, the density estimator, or | |
1546 | the [^P^2] cumulative distribution estimator. For more implementation details, see | |
1547 | [classref boost::accumulators::impl::median_impl [^median_impl]], | |
1548 | [classref boost::accumulators::impl::with_density_median_impl [^with_density_median_impl]], | |
1549 | and [classref boost::accumulators::impl::with_p_square_cumulative_distribution_median_impl [^with_p_square_cumulative_distribution_median_impl]]. | |
1550 | ||
1551 | The three median accumulators all satisfy the `tag::median` feature, and can all be | |
1552 | extracted with the `median()` extractor. | |
1553 | ||
1554 | [variablelist | |
1555 | [[Result Type] [`` | |
1556 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1557 | ``]] | |
1558 | [[Depends On] [`median` depends on `p_square_quantile_for_median` \n | |
1559 | `with_density_median` depends on `count` and `density` \n | |
1560 | `with_p_square_cumulative_distribution_median` depends on `p_square_cumulative_distribution`]] | |
1561 | [[Variants] [`with_density_median` \n | |
1562 | `with_p_square_cumulative_distribution_median`]] | |
1563 | [[Initialization Parameters] [`with_density_median` requires `tag::density::cache_size` and `tag::density::num_bins` \n | |
1564 | `with_p_square_cumulative_distribution_median` requires `tag::p_square_cumulative_distribution::num_cells`]] | |
1565 | [[Accumulator Parameters] [['none]]] | |
1566 | [[Extractor Parameters] [['none]]] | |
1567 | [[Accumulator Complexity] [TODO]] | |
1568 | [[Extractor Complexity] [TODO]] | |
1569 | ] | |
1570 | ||
1571 | [*Header] | |
1572 | [def _MEDIAN_HPP_ [headerref boost/accumulators/statistics/median.hpp]] | |
1573 | ||
1574 | #include <_MEDIAN_HPP_> | |
1575 | ||
1576 | [*Example] | |
1577 | ||
1578 | // two random number generators | |
1579 | double mu = 1.; | |
1580 | boost::lagged_fibonacci607 rng; | |
1581 | boost::normal_distribution<> mean_sigma(mu,1); | |
1582 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > | |
1583 | normal(rng, mean_sigma); | |
1584 | ||
1585 | accumulator_set<double, stats<tag::median(with_p_square_quantile) > > acc; | |
1586 | accumulator_set<double, stats<tag::median(with_density) > > | |
1587 | acc_dens( density_cache_size = 10000, density_num_bins = 1000 ); | |
1588 | accumulator_set<double, stats<tag::median(with_p_square_cumulative_distribution) > > | |
1589 | acc_cdist( p_square_cumulative_distribution_num_cells = 100 ); | |
1590 | ||
1591 | for (std::size_t i=0; i<100000; ++i) | |
1592 | { | |
1593 | double sample = normal(); | |
1594 | acc(sample); | |
1595 | acc_dens(sample); | |
1596 | acc_cdist(sample); | |
1597 | } | |
1598 | ||
1599 | BOOST_CHECK_CLOSE(1., median(acc), 1.); | |
1600 | BOOST_CHECK_CLOSE(1., median(acc_dens), 1.); | |
1601 | BOOST_CHECK_CLOSE(1., median(acc_cdist), 3.); | |
1602 | ||
1603 | [*See also] | |
1604 | ||
1605 | * [classref boost::accumulators::impl::median_impl [^median_impl]] | |
1606 | * [classref boost::accumulators::impl::with_density_median_impl [^with_density_median_impl]] | |
1607 | * [classref boost::accumulators::impl::with_p_square_cumulative_distribution_median_impl [^with_p_square_cumulative_distribution_median_impl]] | |
1608 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1609 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.p_square_quantile [^p_square_quantile]] | |
1610 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.p_square_cumulative_distribution [^p_square_cumulative_distribution]] | |
1611 | ||
1612 | [endsect] | |
1613 | ||
1614 | [section:min min] | |
1615 | ||
1616 | Calculates the minimum value of all the samples. | |
1617 | ||
1618 | [variablelist | |
1619 | [[Result Type] [`` | |
1620 | _sample_type_ | |
1621 | ``]] | |
1622 | [[Depends On] [['none]]] | |
1623 | [[Variants] [['none]]] | |
1624 | [[Initialization Parameters] [['none]]] | |
1625 | [[Accumulator Parameters] [['none]]] | |
1626 | [[Extractor Parameters] [['none]]] | |
1627 | [[Accumulator Complexity] [O(1)]] | |
1628 | [[Extractor Complexity] [O(1)]] | |
1629 | ] | |
1630 | ||
1631 | [*Header] | |
1632 | [def _MIN_HPP_ [headerref boost/accumulators/statistics/min.hpp]] | |
1633 | ||
1634 | #include <_MIN_HPP_> | |
1635 | ||
1636 | [*Example] | |
1637 | ||
1638 | accumulator_set<int, stats<tag::min> > acc; | |
1639 | ||
1640 | acc(1); | |
1641 | BOOST_CHECK_EQUAL(1, (min)(acc)); | |
1642 | ||
1643 | acc(0); | |
1644 | BOOST_CHECK_EQUAL(0, (min)(acc)); | |
1645 | ||
1646 | acc(2); | |
1647 | BOOST_CHECK_EQUAL(0, (min)(acc)); | |
1648 | ||
1649 | [*See also] | |
1650 | ||
1651 | * [classref boost::accumulators::impl::min_impl [^min_impl]] | |
1652 | ||
1653 | [endsect] | |
1654 | ||
1655 | [section:moment moment] | |
1656 | ||
1657 | Calculates the N-th moment of the samples, which is defined as the sum of the N-th power of the | |
1658 | samples over the count of samples. | |
1659 | ||
1660 | [variablelist | |
1661 | [[Result Type] [`` | |
1662 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1663 | ``]] | |
1664 | [[Depends On] [`count`]] | |
1665 | [[Variants] [['none]]] | |
1666 | [[Initialization Parameters] [['none]]] | |
1667 | [[Accumulator Parameters] [['none]]] | |
1668 | [[Extractor Parameters] [['none]]] | |
1669 | [[Accumulator Complexity] [O(1)]] | |
1670 | [[Extractor Complexity] [O(1)]] | |
1671 | ] | |
1672 | ||
1673 | [*Header] | |
1674 | [def _MOMENT_HPP_ [headerref boost/accumulators/statistics/moment.hpp]] | |
1675 | ||
1676 | #include <_MOMENT_HPP_> | |
1677 | ||
1678 | [*Example] | |
1679 | ||
1680 | accumulator_set<int, stats<tag::moment<2> > > acc1; | |
1681 | ||
1682 | acc1(2); // 4 | |
1683 | acc1(4); // 16 | |
1684 | acc1(5); // + 25 | |
1685 | // = 45 / 3 = 15 | |
1686 | ||
1687 | BOOST_CHECK_CLOSE(15., accumulators::moment<2>(acc1), 1e-5); | |
1688 | ||
1689 | accumulator_set<int, stats<tag::moment<5> > > acc2; | |
1690 | ||
1691 | acc2(2); // 32 | |
1692 | acc2(3); // 243 | |
1693 | acc2(4); // 1024 | |
1694 | acc2(5); // + 3125 | |
1695 | // = 4424 / 4 = 1106 | |
1696 | ||
1697 | BOOST_CHECK_CLOSE(1106., accumulators::moment<5>(acc2), 1e-5); | |
1698 | ||
1699 | [*See also] | |
1700 | ||
1701 | * [classref boost::accumulators::impl::moment_impl [^moment_impl]] | |
1702 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1703 | ||
1704 | [endsect] | |
1705 | ||
1706 | [section:p_square_cumulative_distribution p_square_cumulative_distribution] | |
1707 | ||
1708 | Histogram calculation of the cumulative distribution with the [^P^2] algorithm. | |
1709 | For more implementation details, see | |
1710 | [classref boost::accumulators::impl::p_square_cumulative_distribution_impl [^p_square_cumulative_distribution_impl]] | |
1711 | ||
1712 | [variablelist | |
1713 | [[Result Type] [`` | |
1714 | iterator_range< | |
1715 | std::vector< | |
1716 | std::pair< | |
1717 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1718 | , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1719 | > | |
1720 | >::iterator | |
1721 | > | |
1722 | ``]] | |
1723 | [[Depends On] [`count`]] | |
1724 | [[Variants] [['none]]] | |
1725 | [[Initialization Parameters] [`tag::p_square_cumulative_distribution::num_cells`]] | |
1726 | [[Accumulator Parameters] [['none]]] | |
1727 | [[Extractor Parameters] [['none]]] | |
1728 | [[Accumulator Complexity] [TODO]] | |
1729 | [[Extractor Complexity] [O(N) where N is `num_cells`]] | |
1730 | ] | |
1731 | ||
1732 | [*Header] | |
1733 | [def _P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_ [headerref boost/accumulators/statistics/p_square_cumul_dist.hpp]] | |
1734 | ||
1735 | #include <_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_> | |
1736 | ||
1737 | [*Example] | |
1738 | ||
1739 | // tolerance in % | |
1740 | double epsilon = 3; | |
1741 | ||
1742 | typedef accumulator_set<double, stats<tag::p_square_cumulative_distribution> > accumulator_t; | |
1743 | ||
1744 | accumulator_t acc(tag::p_square_cumulative_distribution::num_cells = 100); | |
1745 | ||
1746 | // two random number generators | |
1747 | boost::lagged_fibonacci607 rng; | |
1748 | boost::normal_distribution<> mean_sigma(0,1); | |
1749 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal(rng, mean_sigma); | |
1750 | ||
1751 | for (std::size_t i=0; i<100000; ++i) | |
1752 | { | |
1753 | acc(normal()); | |
1754 | } | |
1755 | ||
1756 | typedef iterator_range<std::vector<std::pair<double, double> >::iterator > histogram_type; | |
1757 | histogram_type histogram = p_square_cumulative_distribution(acc); | |
1758 | ||
1759 | for (std::size_t i = 0; i < histogram.size(); ++i) | |
1760 | { | |
1761 | // problem with small results: epsilon is relative (in percent), not absolute! | |
1762 | if ( histogram[i].second > 0.001 ) | |
1763 | BOOST_CHECK_CLOSE( 0.5 * (1.0 + erf( histogram[i].first / sqrt(2.0) )), histogram[i].second, epsilon ); | |
1764 | } | |
1765 | ||
1766 | [*See also] | |
1767 | ||
1768 | * [classref boost::accumulators::impl::p_square_cumulative_distribution_impl [^p_square_cumulative_distribution_impl]] | |
1769 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1770 | ||
1771 | [endsect] | |
1772 | ||
1773 | [section:p_square_quantile p_square_quantile ['and variants]] | |
1774 | ||
1775 | Single quantile estimation with the [^P^2] algorithm. For more implementation details, see | |
1776 | [classref boost::accumulators::impl::p_square_quantile_impl [^p_square_quantile_impl]] | |
1777 | ||
1778 | [variablelist | |
1779 | [[Result Type] [`` | |
1780 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1781 | ``]] | |
1782 | [[Depends On] [`count`]] | |
1783 | [[Variants] [`p_square_quantile_for_median`]] | |
1784 | [[Initialization Parameters] [`quantile_probability`, which defaults to `0.5`. | |
1785 | (Note: for `p_square_quantile_for_median`, the `quantile_probability` | |
1786 | parameter is ignored and is always `0.5`.)]] | |
1787 | [[Accumulator Parameters] [['none]]] | |
1788 | [[Extractor Parameters] [['none]]] | |
1789 | [[Accumulator Complexity] [TODO]] | |
1790 | [[Extractor Complexity] [O(1)]] | |
1791 | ] | |
1792 | ||
1793 | [*Header] | |
1794 | [def _P_SQUARE_QUANTILE_HPP_ [headerref boost/accumulators/statistics/p_square_quantile.hpp]] | |
1795 | ||
1796 | #include <_P_SQUARE_QUANTILE_HPP_> | |
1797 | ||
1798 | [*Example] | |
1799 | ||
1800 | typedef accumulator_set<double, stats<tag::p_square_quantile> > accumulator_t; | |
1801 | ||
1802 | // tolerance in % | |
1803 | double epsilon = 1; | |
1804 | ||
1805 | // a random number generator | |
1806 | boost::lagged_fibonacci607 rng; | |
1807 | ||
1808 | accumulator_t acc0(quantile_probability = 0.001); | |
1809 | accumulator_t acc1(quantile_probability = 0.01 ); | |
1810 | accumulator_t acc2(quantile_probability = 0.1 ); | |
1811 | accumulator_t acc3(quantile_probability = 0.25 ); | |
1812 | accumulator_t acc4(quantile_probability = 0.5 ); | |
1813 | accumulator_t acc5(quantile_probability = 0.75 ); | |
1814 | accumulator_t acc6(quantile_probability = 0.9 ); | |
1815 | accumulator_t acc7(quantile_probability = 0.99 ); | |
1816 | accumulator_t acc8(quantile_probability = 0.999); | |
1817 | ||
1818 | for (int i=0; i<100000; ++i) | |
1819 | { | |
1820 | double sample = rng(); | |
1821 | acc0(sample); | |
1822 | acc1(sample); | |
1823 | acc2(sample); | |
1824 | acc3(sample); | |
1825 | acc4(sample); | |
1826 | acc5(sample); | |
1827 | acc6(sample); | |
1828 | acc7(sample); | |
1829 | acc8(sample); | |
1830 | } | |
1831 | ||
1832 | BOOST_CHECK_CLOSE( p_square_quantile(acc0), 0.001, 15*epsilon ); | |
1833 | BOOST_CHECK_CLOSE( p_square_quantile(acc1), 0.01 , 5*epsilon ); | |
1834 | BOOST_CHECK_CLOSE( p_square_quantile(acc2), 0.1 , epsilon ); | |
1835 | BOOST_CHECK_CLOSE( p_square_quantile(acc3), 0.25 , epsilon ); | |
1836 | BOOST_CHECK_CLOSE( p_square_quantile(acc4), 0.5 , epsilon ); | |
1837 | BOOST_CHECK_CLOSE( p_square_quantile(acc5), 0.75 , epsilon ); | |
1838 | BOOST_CHECK_CLOSE( p_square_quantile(acc6), 0.9 , epsilon ); | |
1839 | BOOST_CHECK_CLOSE( p_square_quantile(acc7), 0.99 , epsilon ); | |
1840 | BOOST_CHECK_CLOSE( p_square_quantile(acc8), 0.999, epsilon ); | |
1841 | ||
1842 | [*See also] | |
1843 | ||
1844 | * [classref boost::accumulators::impl::p_square_quantile_impl [^p_square_quantile_impl]] | |
1845 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1846 | ||
1847 | [endsect] | |
1848 | ||
1849 | [section:peaks_over_threshold peaks_over_threshold ['and variants]] | |
1850 | ||
1851 | Peaks Over Threshold method for quantile and tail mean estimation. For implementation | |
1852 | details, see [classref boost::accumulators::impl::peaks_over_threshold_impl [^peaks_over_threshold_impl]] | |
1853 | and [classref boost::accumulators::impl::peaks_over_threshold_prob_impl [^peaks_over_threshold_prob_impl]]. | |
1854 | ||
1855 | Both `tag::peaks_over_threshold` and `tag::peaks_over_threshold_prob<>` satisfy the `tag::abstract_peaks_over_threshold` | |
1856 | feature, and can be extracted with the `peaks_over_threshold()` extractor. The result is a 3-tuple representing | |
1857 | the fit parameters `u_bar`, `beta_bar` and `xi_hat`. | |
1858 | ||
1859 | [variablelist | |
1860 | [[Result Type] [`` | |
1861 | boost::tuple< | |
1862 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type // u_bar | |
1863 | , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type // beta_bar | |
1864 | , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type // xi_hat | |
1865 | > | |
1866 | ``]] | |
1867 | [[Depends On] [`count` \n | |
1868 | In addition, `tag::peaks_over_threshold_prob<>` depends on `tail<_left_or_right_>`]] | |
1869 | [[Variants] [`peaks_over_threshold_prob<_left_or_right_>`]] | |
1870 | [[Initialization Parameters] [ `tag::peaks_over_threshold::threshold_value` \n | |
1871 | `tag::peaks_over_threshold_prob::threshold_probability` \n | |
1872 | `tag::tail<_left_or_right_>::cache_size` ]] | |
1873 | [[Accumulator Parameters] [['none]]] | |
1874 | [[Extractor Parameters] [['none]]] | |
1875 | [[Accumulator Complexity] [TODO]] | |
1876 | [[Extractor Complexity] [TODO]] | |
1877 | ] | |
1878 | ||
1879 | [*Header] | |
1880 | [def _PEAKS_OVER_THRESHOLD_HPP_ [headerref boost/accumulators/statistics/peaks_over_threshold.hpp]] | |
1881 | ||
1882 | #include <_PEAKS_OVER_THRESHOLD_HPP_> | |
1883 | ||
1884 | [*Example] | |
1885 | ||
1886 | See example for [link accumulators.user_s_guide.the_statistical_accumulators_library.pot_quantile [^pot_quantile]]. | |
1887 | ||
1888 | [*See also] | |
1889 | ||
1890 | * [classref boost::accumulators::impl::peaks_over_threshold_impl [^peaks_over_threshold_impl]] | |
1891 | * [classref boost::accumulators::impl::peaks_over_threshold_prob_impl [^peaks_over_threshold_prob_impl]] | |
1892 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
1893 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
1894 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.pot_quantile [^pot_quantile]] | |
1895 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.pot_tail_mean [^pot_tail_mean]] | |
1896 | ||
1897 | [endsect] | |
1898 | ||
1899 | [section:pot_quantile pot_quantile ['and variants]] | |
1900 | ||
1901 | Quantile estimation based on Peaks over Threshold method (for both left and right tails). For | |
1902 | implementation details, see [classref boost::accumulators::impl::pot_quantile_impl [^pot_quantile_impl]]. | |
1903 | ||
1904 | Both `tag::pot_quantile<_left_or_right_>` and `tag::pot_quantile_prob<_left_or_right_>` satisfy the | |
1905 | `tag::quantile` feature and can be extracted using the `quantile()` extractor. | |
1906 | ||
1907 | [variablelist | |
1908 | [[Result Type] [`` | |
1909 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
1910 | ``]] | |
1911 | [[Depends On] [`pot_quantile<_left_or_right_>` depends on `peaks_over_threshold<_left_or_right_>` \n | |
1912 | `pot_quantile_prob<_left_or_right_>` depends on `peaks_over_threshold_prob<_left_or_right_>` ]] | |
1913 | [[Variants] [`pot_quantile_prob<_left_or_right_>`]] | |
1914 | [[Initialization Parameters] [ `tag::peaks_over_threshold::threshold_value` \n | |
1915 | `tag::peaks_over_threshold_prob::threshold_probability` \n | |
1916 | `tag::tail<_left_or_right_>::cache_size` ]] | |
1917 | [[Accumulator Parameters] [['none]]] | |
1918 | [[Extractor Parameters] [`quantile_probability`]] | |
1919 | [[Accumulator Complexity] [TODO]] | |
1920 | [[Extractor Complexity] [TODO]] | |
1921 | ] | |
1922 | ||
1923 | [*Header] | |
1924 | [def _POT_QUANTILE_HPP_ [headerref boost/accumulators/statistics/pot_quantile.hpp]] | |
1925 | ||
1926 | #include <_POT_QUANTILE_HPP_> | |
1927 | ||
1928 | [*Example] | |
1929 | ||
1930 | // tolerance in % | |
1931 | double epsilon = 1.; | |
1932 | ||
1933 | double alpha = 0.999; | |
1934 | double threshold_probability = 0.99; | |
1935 | double threshold = 3.; | |
1936 | ||
1937 | // two random number generators | |
1938 | boost::lagged_fibonacci607 rng; | |
1939 | boost::normal_distribution<> mean_sigma(0,1); | |
1940 | boost::exponential_distribution<> lambda(1); | |
1941 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal(rng, mean_sigma); | |
1942 | boost::variate_generator<boost::lagged_fibonacci607&, boost::exponential_distribution<> > exponential(rng, lambda); | |
1943 | ||
1944 | accumulator_set<double, stats<tag::pot_quantile<right>(with_threshold_value)> > acc1( | |
1945 | tag::peaks_over_threshold::threshold_value = threshold | |
1946 | ); | |
1947 | accumulator_set<double, stats<tag::pot_quantile<right>(with_threshold_probability)> > acc2( | |
1948 | tag::tail<right>::cache_size = 2000 | |
1949 | , tag::peaks_over_threshold_prob::threshold_probability = threshold_probability | |
1950 | ); | |
1951 | ||
1952 | threshold_probability = 0.995; | |
1953 | threshold = 5.; | |
1954 | ||
1955 | accumulator_set<double, stats<tag::pot_quantile<right>(with_threshold_value)> > acc3( | |
1956 | tag::peaks_over_threshold::threshold_value = threshold | |
1957 | ); | |
1958 | accumulator_set<double, stats<tag::pot_quantile<right>(with_threshold_probability)> > acc4( | |
1959 | tag::tail<right>::cache_size = 2000 | |
1960 | , tag::peaks_over_threshold_prob::threshold_probability = threshold_probability | |
1961 | ); | |
1962 | ||
1963 | for (std::size_t i = 0; i < 100000; ++i) | |
1964 | { | |
1965 | double sample = normal(); | |
1966 | acc1(sample); | |
1967 | acc2(sample); | |
1968 | } | |
1969 | ||
1970 | for (std::size_t i = 0; i < 100000; ++i) | |
1971 | { | |
1972 | double sample = exponential(); | |
1973 | acc3(sample); | |
1974 | acc4(sample); | |
1975 | } | |
1976 | ||
1977 | BOOST_CHECK_CLOSE( quantile(acc1, quantile_probability = alpha), 3.090232, epsilon ); | |
1978 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = alpha), 3.090232, epsilon ); | |
1979 | ||
1980 | BOOST_CHECK_CLOSE( quantile(acc3, quantile_probability = alpha), 6.908, epsilon ); | |
1981 | BOOST_CHECK_CLOSE( quantile(acc4, quantile_probability = alpha), 6.908, epsilon ); | |
1982 | ||
1983 | [*See also] | |
1984 | ||
1985 | * [classref boost::accumulators::impl::pot_quantile_impl [^pot_quantile_impl]] | |
1986 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.peaks_over_threshold [^peaks_over_threshold]] | |
1987 | ||
1988 | [endsect] | |
1989 | ||
1990 | [section:pot_tail_mean pot_tail_mean] | |
1991 | ||
1992 | Estimation of the (coherent) tail mean based on the peaks over threshold method (for both left and right tails). | |
1993 | For implementation details, see [classref boost::accumulators::impl::pot_tail_mean_impl [^pot_tail_mean_impl]]. | |
1994 | ||
1995 | Both `tag::pot_tail_mean<_left_or_right_>` and `tag::pot_tail_mean_prob<_left_or_right_>` satisfy the | |
1996 | `tag::tail_mean` feature and can be extracted using the `tail_mean()` extractor. | |
1997 | ||
1998 | [variablelist | |
1999 | [[Result Type] [`` | |
2000 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2001 | ``]] | |
2002 | [[Depends On] [`pot_tail_mean<_left_or_right_>` depends on `peaks_over_threshold<_left_or_right_>` | |
2003 | and `pot_quantile<_left_or_right_>` \n | |
2004 | `pot_tail_mean_prob<_left_or_right_>` depends on `peaks_over_threshold_prob<_left_or_right_>` | |
2005 | and `pot_quantile_prob<_left_or_right_>` ]] | |
2006 | [[Variants] [`pot_tail_mean_prob<_left_or_right_>`]] | |
2007 | [[Initialization Parameters] [ `tag::peaks_over_threshold::threshold_value` \n | |
2008 | `tag::peaks_over_threshold_prob::threshold_probability` \n | |
2009 | `tag::tail<_left_or_right_>::cache_size` ]] | |
2010 | [[Accumulator Parameters] [['none]]] | |
2011 | [[Extractor Parameters] [`quantile_probability`]] | |
2012 | [[Accumulator Complexity] [TODO]] | |
2013 | [[Extractor Complexity] [TODO]] | |
2014 | ] | |
2015 | ||
2016 | [*Header] | |
2017 | [def _POT_TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/pot_tail_mean.hpp]] | |
2018 | ||
2019 | #include <_POT_TAIL_MEAN_HPP_> | |
2020 | ||
2021 | [*Example] | |
2022 | ||
2023 | // TODO | |
2024 | ||
2025 | [*See also] | |
2026 | ||
2027 | * [classref boost::accumulators::impl::pot_tail_mean_impl [^pot_tail_mean_impl]] | |
2028 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.peaks_over_threshold [^peaks_over_threshold]] | |
2029 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.pot_quantile [^pot_quantile]] | |
2030 | ||
2031 | [endsect] | |
2032 | ||
2033 | [section:rolling_count rolling_count] | |
2034 | ||
2035 | The rolling count is the current number of elements in the rolling window. | |
2036 | ||
2037 | [variablelist | |
2038 | [[Result Type] [``std::size_t``]] | |
2039 | [[Depends On] [`rolling_window_plus1`]] | |
2040 | [[Variants] [['none]]] | |
2041 | [[Initialization Parameters] [`tag::rolling_window::window_size`]] | |
2042 | [[Accumulator Parameters] [['none]]] | |
2043 | [[Extractor Parameters] [['none]]] | |
2044 | [[Accumulator Complexity] [O(1)]] | |
2045 | [[Extractor Complexity] [O(1)]] | |
2046 | ] | |
2047 | ||
2048 | [*Header] | |
2049 | [def _ROLLING_COUNT_HPP_ [headerref boost/accumulators/statistics/rolling_count.hpp]] | |
2050 | ||
2051 | #include <_ROLLING_COUNT_HPP_> | |
2052 | ||
2053 | [*Example] | |
2054 | ||
2055 | accumulator_set<int, stats<tag::rolling_count> > acc(tag::rolling_window::window_size = 3); | |
2056 | ||
2057 | BOOST_CHECK_EQUAL(0u, rolling_count(acc)); | |
2058 | ||
2059 | acc(1); | |
2060 | BOOST_CHECK_EQUAL(1u, rolling_count(acc)); | |
2061 | ||
2062 | acc(1); | |
2063 | BOOST_CHECK_EQUAL(2u, rolling_count(acc)); | |
2064 | ||
2065 | acc(1); | |
2066 | BOOST_CHECK_EQUAL(3u, rolling_count(acc)); | |
2067 | ||
2068 | acc(1); | |
2069 | BOOST_CHECK_EQUAL(3u, rolling_count(acc)); | |
2070 | ||
2071 | acc(1); | |
2072 | BOOST_CHECK_EQUAL(3u, rolling_count(acc)); | |
2073 | ||
2074 | [*See also] | |
2075 | ||
2076 | * [classref boost::accumulators::impl::rolling_count_impl [^rolling_count_impl]] | |
2077 | ||
2078 | [endsect] | |
2079 | ||
2080 | [section:rolling_sum rolling_sum] | |
2081 | ||
2082 | The rolling sum is the sum of the last /N/ samples. | |
2083 | ||
2084 | [variablelist | |
2085 | [[Result Type] [``_sample_type_``]] | |
2086 | [[Depends On] [`rolling_window_plus1`]] | |
2087 | [[Variants] [['none]]] | |
2088 | [[Initialization Parameters] [`tag::rolling_window::window_size`]] | |
2089 | [[Accumulator Parameters] [['none]]] | |
2090 | [[Extractor Parameters] [['none]]] | |
2091 | [[Accumulator Complexity] [O(1)]] | |
2092 | [[Extractor Complexity] [O(1)]] | |
2093 | ] | |
2094 | ||
2095 | [*Header] | |
2096 | [def _ROLLING_SUM_HPP_ [headerref boost/accumulators/statistics/rolling_sum.hpp]] | |
2097 | ||
2098 | #include <_ROLLING_SUM_HPP_> | |
2099 | ||
2100 | [*Example] | |
2101 | ||
2102 | accumulator_set<int, stats<tag::rolling_sum> > acc(tag::rolling_window::window_size = 3); | |
2103 | ||
2104 | BOOST_CHECK_EQUAL(0, rolling_sum(acc)); | |
2105 | ||
2106 | acc(1); | |
2107 | BOOST_CHECK_EQUAL(1, rolling_sum(acc)); | |
2108 | ||
2109 | acc(2); | |
2110 | BOOST_CHECK_EQUAL(3, rolling_sum(acc)); | |
2111 | ||
2112 | acc(3); | |
2113 | BOOST_CHECK_EQUAL(6, rolling_sum(acc)); | |
2114 | ||
2115 | acc(4); | |
2116 | BOOST_CHECK_EQUAL(9, rolling_sum(acc)); | |
2117 | ||
2118 | acc(5); | |
2119 | BOOST_CHECK_EQUAL(12, rolling_sum(acc)); | |
2120 | ||
2121 | [*See also] | |
2122 | ||
2123 | * [classref boost::accumulators::impl::rolling_sum_impl [^rolling_sum_impl]] | |
2124 | ||
2125 | [endsect] | |
2126 | ||
2127 | [section:rolling_mean rolling_mean] | |
2128 | ||
2129 | The rolling mean is the mean over the last /N/ samples. It is computed by dividing | |
2130 | the rolling sum by the rolling count. | |
2131 | ||
2132 | Lazy or iterative calculation of the mean over the last /N/ samples. The lazy calculation is associated with the `tag::lazy_rolling_mean` | |
2133 | feature, and the iterative calculation (which is the default) with the `tag::immediate_rolling_mean` feature. Both can be extracted | |
2134 | using the `tag::rolling_mean()` extractor. For more implementation details, see | |
2135 | [classref boost::accumulators::impl::lazy_rolling_mean_impl [^lazy_rolling_mean_impl]] and | |
2136 | [classref boost::accumulators::impl::immediate_rolling_mean_impl [^immediate_rolling_mean_impl]] | |
2137 | ||
2138 | [variablelist | |
2139 | [[Result Type] [`` | |
2140 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2141 | ``]] | |
2142 | [[Depends On] [`lazy_rolling_mean` depends on `rolling_sum` and `rolling_count` \n | |
2143 | `immediate_rolling_mean` depends on `rolling_count`]] | |
2144 | [[Variants] [`lazy_rolling_mean` (a.k.a. `rolling_mean(lazy))` \n | |
2145 | `immediate_rolling_mean` (a.k.a. `rolling_mean(immediate)`)]] | |
2146 | [[Initialization Parameters] [`tag::rolling_window::window_size`]] | |
2147 | [[Accumulator Parameters] [['none]]] | |
2148 | [[Extractor Parameters] [['none]]] | |
2149 | [[Accumulator Complexity] [O(1)]] | |
2150 | [[Extractor Complexity] [O(1)]] | |
2151 | ] | |
2152 | ||
2153 | [*Header] | |
2154 | [def _ROLLING_MEAN_HPP_ [headerref boost/accumulators/statistics/rolling_mean.hpp]] | |
2155 | ||
2156 | #include <_ROLLING_MEAN_HPP_> | |
2157 | ||
2158 | [*Example] | |
2159 | ||
2160 | accumulator_set<int, stats<tag::rolling_mean> > acc(tag::rolling_window::window_size = 5); | |
2161 | ||
2162 | acc(1); | |
2163 | acc(2); | |
2164 | acc(3); | |
2165 | ||
2166 | BOOST_CHECK_CLOSE( rolling_mean(acc), 2.0, 1e-6 ); | |
2167 | ||
2168 | acc(4); | |
2169 | acc(5); | |
2170 | acc(6); | |
2171 | acc(7); | |
2172 | ||
2173 | BOOST_CHECK_CLOSE( rolling_mean(acc), 5.0, 1e-6 ); | |
2174 | ||
2175 | [*See also] | |
2176 | ||
2177 | * [classref boost::accumulators::impl::lazy_rolling_mean_impl [^lazy_rolling_mean_impl]] | |
2178 | * [classref boost::accumulators::impl::immediate_rolling_mean_impl [^immediate_rolling_mean_impl]] | |
2179 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.rolling_count [^rolling_count]] | |
2180 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.rolling_sum [^rolling_sum]] | |
2181 | ||
2182 | [endsect] | |
2183 | ||
2184 | [section:rolling_moment rolling_moment] | |
2185 | ||
2186 | rolling_moment<M> calculates the /M/-th moment of the samples, which is defined as the sum of the /M/-th power of the samples over the count of samples, over the last /N/ samples. | |
2187 | ||
2188 | [variablelist | |
2189 | [[Result Type] [`` | |
2190 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2191 | ``]] | |
2192 | [[Depends On] [['none]]] | |
2193 | [[Variants] [['none]]] | |
2194 | [[Initialization Parameters] [`tag::rolling_window::window_size`]] | |
2195 | [[Accumulator Parameters] [['none]]] | |
2196 | [[Extractor Parameters] [['none]]] | |
2197 | [[Accumulator Complexity] [O(1)]] | |
2198 | [[Extractor Complexity] [O(1)]] | |
2199 | ] | |
2200 | ||
2201 | [*Header] | |
2202 | [def _ROLLING_MOMENT_HPP_ [headerref boost/accumulators/statistics/rolling_moment.hpp]] | |
2203 | ||
2204 | #include <_ROLLING_MOMENT_HPP_> | |
2205 | ||
2206 | [*Example] | |
2207 | ||
2208 | accumulator_set<int, stats<tag::rolling_moment<2> > > acc(tag::rolling_window::window_size = 3); | |
2209 | ||
2210 | acc(2); | |
2211 | acc(4); | |
2212 | ||
2213 | BOOST_CHECK_CLOSE( rolling_moment<2>(acc), (4.0 + 16.0)/2, 1e-5 ); | |
2214 | ||
2215 | acc(5); | |
2216 | acc(6); | |
2217 | ||
2218 | BOOST_CHECK_CLOSE( rolling_moment<2>(acc), (16.0 + 25.0 + 36.0)/3, 1e-5 ); | |
2219 | ||
2220 | [*See also] | |
2221 | ||
2222 | * [classref boost::accumulators::impl::rolling_moment_impl [^rolling_moment_impl]] | |
2223 | ||
2224 | [endsect] | |
2225 | ||
2226 | [section:rolling_variance rolling_variance] | |
2227 | ||
2228 | Lazy or iterative calculation of the variance over the last /N/ samples. The lazy calculation is associated with the `tag::lazy_rolling_variance` | |
2229 | feature, and the iterative calculation with the `tag::immediate_rolling_variance` feature. Both can be extracted using the `tag::rolling_variance()` extractor. | |
2230 | For more implementation details, see | |
2231 | [classref boost::accumulators::impl::lazy_rolling_variance_impl [^lazy_rolling_variance_impl]] and | |
2232 | [classref boost::accumulators::impl::immediate_rolling_variance_impl [^immediate_rolling_variance_impl]] | |
2233 | ||
2234 | [variablelist | |
2235 | [[Result Type] [`` | |
2236 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2237 | ``]] | |
2238 | [[Depends On] [`lazy_rolling_variance` depends on `rolling_moment<2>`, `rolling_count` and `rolling_mean` \n | |
2239 | `immediate_rolling_variance` depends on `rolling_count` and `immediate_rolling_mean`]] | |
2240 | [[Variants] [`lazy_rolling_variance` (a.k.a. `rolling_variance(lazy))` \n | |
2241 | `immediate_rolling_variance` (a.k.a. `rolling_variance(immediate)`)]] | |
2242 | [[Initialization Parameters] [`tag::rolling_window::window_size`]] | |
2243 | [[Accumulator Parameters] [['none]]] | |
2244 | [[Extractor Parameters] [['none]]] | |
2245 | [[Accumulator Complexity] [O(1)]] | |
2246 | [[Extractor Complexity] [O(1)]] | |
2247 | ] | |
2248 | ||
2249 | [*Header] | |
2250 | [def _ROLLING_VARIANCE_HPP_ [headerref boost/accumulators/statistics/rolling_variance.hpp]] | |
2251 | ||
2252 | #include <_ROLLING_VARIANCE_HPP_> | |
2253 | ||
2254 | [*Example] | |
2255 | ||
2256 | accumulator_set<double, stats<tag::rolling_variance> > acc(tag::rolling_window::window_size = 4); | |
2257 | ||
2258 | acc(1.2); | |
2259 | ||
2260 | BOOST_CHECK_CLOSE( rolling_variance(acc), 0.0, 1e-10 ); // variance is not defined for a single sample | |
2261 | ||
2262 | acc(2.3); | |
2263 | acc(3.4); | |
2264 | ||
2265 | BOOST_CHECK_CLOSE( rolling_variance(acc), 1.21, 1e-10 ); // variance over samples 1-3 | |
2266 | ||
2267 | acc(4.5); | |
2268 | acc(0.4); | |
2269 | acc(2.2); | |
2270 | acc(7.1); | |
2271 | ||
2272 | BOOST_CHECK_CLOSE( rolling_variance(acc), 8.41666666666667, 1e-10 ); // variance over samples 4-7 | |
2273 | ||
2274 | [*See also] | |
2275 | ||
2276 | * [classref boost::accumulators::impl::lazy_rolling_variance_impl [^lazy_rolling_variance_impl]] | |
2277 | * [classref boost::accumulators::impl::immediate_rolling_variance_impl [^immediate_rolling_variance_impl]] | |
2278 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.rolling_count [^rolling_count]] | |
2279 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.rolling_mean [^rolling_mean]] | |
2280 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.immediate_rolling_mean [^immediate_rolling_mean]] | |
2281 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.rolling_moment [^rolling_moment]] | |
2282 | ||
2283 | [endsect] | |
2284 | ||
2285 | ||
2286 | [section:skewness skewness] | |
2287 | ||
2288 | The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the [^3/2]-th power | |
2289 | of the 2nd central moment (the variance) of the samples 3. For implementation details, see | |
2290 | [classref boost::accumulators::impl::skewness_impl [^skewness_impl]]. | |
2291 | ||
2292 | [variablelist | |
2293 | [[Result Type] [`` | |
2294 | numeric::functional::fdiv<_sample_type_, _sample_type_>::result_type | |
2295 | ``]] | |
2296 | [[Depends On] [`mean` \n `moment<2>` \n `moment<3>`]] | |
2297 | [[Variants] [['none]]] | |
2298 | [[Initialization Parameters] [['none]]] | |
2299 | [[Accumulator Parameters] [['none]]] | |
2300 | [[Extractor Parameters] [['none]]] | |
2301 | [[Accumulator Complexity] [O(1)]] | |
2302 | [[Extractor Complexity] [O(1)]] | |
2303 | ] | |
2304 | ||
2305 | [*Header] | |
2306 | [def _SKEWNESS_HPP_ [headerref boost/accumulators/statistics/skewness.hpp]] | |
2307 | ||
2308 | #include <_SKEWNESS_HPP_> | |
2309 | ||
2310 | [*Example] | |
2311 | ||
2312 | accumulator_set<int, stats<tag::skewness > > acc2; | |
2313 | ||
2314 | acc2(2); | |
2315 | acc2(7); | |
2316 | acc2(4); | |
2317 | acc2(9); | |
2318 | acc2(3); | |
2319 | ||
2320 | BOOST_CHECK_EQUAL( mean(acc2), 5 ); | |
2321 | BOOST_CHECK_EQUAL( accumulators::moment<2>(acc2), 159./5. ); | |
2322 | BOOST_CHECK_EQUAL( accumulators::moment<3>(acc2), 1171./5. ); | |
2323 | BOOST_CHECK_CLOSE( skewness(acc2), 0.406040288214, 1e-6 ); | |
2324 | ||
2325 | [*See also] | |
2326 | ||
2327 | * [classref boost::accumulators::impl::skewness_impl [^skewness_impl]] | |
2328 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.mean [^mean]] | |
2329 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.moment [^moment]] | |
2330 | ||
2331 | [endsect] | |
2332 | ||
2333 | [section:sum sum ['and variants]] | |
2334 | ||
2335 | For summing the samples, weights or variates. The default implementation uses the standard sum operation, | |
2336 | but variants using the Kahan summation algorithm are also provided. | |
2337 | ||
2338 | [variablelist | |
2339 | [[Result Type] [`_sample_type_` for summing samples \n | |
2340 | `_weight_type_` for summing weights \n | |
2341 | `_variate_type_` for summing variates]] | |
2342 | [[Depends On] [['none]]] | |
2343 | [[Variants] [`tag::sum` \n | |
2344 | `tag::sum_of_weights` \n | |
2345 | `tag::sum_of_variates<_variate_type_, _variate_tag_>` \n | |
2346 | `tag::sum_kahan` (a.k.a. `tag::sum(kahan)`) \n | |
2347 | `tag::sum_of_weights_kahan` (a.k.a. `tag::sum_of_weights(kahan)`) \n | |
2348 | `tag::sum_of_variates_kahan<_variate_type_, _variate_tag_>` \n]] | |
2349 | [[Initialization Parameters] [['none]]] | |
2350 | [[Accumulator Parameters] [`weight` for summing weights \n | |
2351 | `_variate_tag_` for summing variates]] | |
2352 | [[Extractor Parameters] [['none]]] | |
2353 | [[Accumulator Complexity] [O(1). Note that the Kahan sum performs four floating-point sum | |
2354 | operations per accumulated value, whereas the naive sum | |
2355 | performs only one.]] | |
2356 | [[Extractor Complexity] [O(1)]] | |
2357 | ] | |
2358 | ||
2359 | [*Header] | |
2360 | [def _SUM_HPP_ [headerref boost/accumulators/statistics/sum.hpp]] | |
2361 | [def _SUM_KAHAN_HPP_ [headerref boost/accumulators/statistics/sum_kahan.hpp]] | |
2362 | ||
2363 | #include <_SUM_HPP_> | |
2364 | #include <_SUM_KAHAN_HPP_> | |
2365 | ||
2366 | [*Example] | |
2367 | ||
2368 | accumulator_set< | |
2369 | int | |
2370 | , stats< | |
2371 | tag::sum | |
2372 | , tag::sum_of_weights | |
2373 | , tag::sum_of_variates<int, tag::covariate1> | |
2374 | > | |
2375 | , int | |
2376 | > acc; | |
2377 | ||
2378 | acc(1, weight = 2, covariate1 = 3); | |
2379 | BOOST_CHECK_EQUAL(2, sum(acc)); // weighted sample = 1 * 2 | |
2380 | BOOST_CHECK_EQUAL(2, sum_of_weights(acc)); | |
2381 | BOOST_CHECK_EQUAL(3, sum_of_variates(acc)); | |
2382 | ||
2383 | acc(2, weight = 4, covariate1 = 6); | |
2384 | BOOST_CHECK_EQUAL(10, sum(acc)); // weighted sample = 2 * 4 | |
2385 | BOOST_CHECK_EQUAL(6, sum_of_weights(acc)); | |
2386 | BOOST_CHECK_EQUAL(9, sum_of_variates(acc)); | |
2387 | ||
2388 | acc(3, weight = 6, covariate1 = 9); | |
2389 | BOOST_CHECK_EQUAL(28, sum(acc)); // weighted sample = 3 * 6 | |
2390 | BOOST_CHECK_EQUAL(12, sum_of_weights(acc)); | |
2391 | BOOST_CHECK_EQUAL(18, sum_of_variates(acc)); | |
2392 | ||
2393 | // demonstrate Kahan summation | |
2394 | accumulator_set<float, stats<tag::sum_kahan> > acc; | |
2395 | BOOST_CHECK_EQUAL(0.0f, sum_kahan(acc)); | |
2396 | for (size_t i = 0; i < 1e6; ++i) { | |
2397 | acc(1e-6f); | |
2398 | } | |
2399 | BOOST_CHECK_EQUAL(1.0f, sum_kahan(acc)); | |
2400 | ||
2401 | [*See also] | |
2402 | ||
2403 | * [classref boost::accumulators::impl::sum_impl [^sum_impl]] | |
2404 | * [classref boost::accumulators::impl::sum_kahan_impl [^sum_kahan_impl]] | |
2405 | ||
2406 | [endsect] | |
2407 | ||
2408 | [section:tail tail] | |
2409 | ||
2410 | Tracks the largest or smallest [^N] values. `tag::tail<right>` tracks the largest [^N], | |
2411 | and `tag::tail<left>` tracks the smallest. The parameter [^N] is specified with the | |
2412 | `tag::tail<_left_or_right_>::cache_size` initialization parameter. For implementation details, see | |
2413 | [classref boost::accumulators::impl::tail_impl [^tail_impl]]. | |
2414 | ||
2415 | Both `tag::tail<left>` and `tag::tail<right>` satisfy the `tag::abstract_tail` feature and | |
2416 | can be extracted with the `tail()` extractor. | |
2417 | ||
2418 | [variablelist | |
2419 | [[Result Type] [`` | |
2420 | boost::iterator_range< | |
2421 | boost::reverse_iterator< | |
2422 | boost::permutation_iterator< | |
2423 | std::vector<_sample_type_>::const_iterator // samples | |
2424 | , std::vector<std::size_t>::iterator // indices | |
2425 | > | |
2426 | > | |
2427 | > | |
2428 | ``]] | |
2429 | [[Depends On] [['none]]] | |
2430 | [[Variants] [`abstract_tail`]] | |
2431 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
2432 | [[Accumulator Parameters] [['none]]] | |
2433 | [[Extractor Parameters] [['none]]] | |
2434 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
2435 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
2436 | ] | |
2437 | ||
2438 | [*Header] | |
2439 | [def _TAIL_HPP_ [headerref boost/accumulators/statistics/tail.hpp]] | |
2440 | ||
2441 | #include <_TAIL_HPP_> | |
2442 | ||
2443 | [*Example] | |
2444 | ||
2445 | See the Example for [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_variate [^tail_variate]]. | |
2446 | ||
2447 | [*See also] | |
2448 | ||
2449 | * [classref boost::accumulators::impl::tail_impl [^tail_impl]] | |
2450 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_variate [^tail_variate]] | |
2451 | ||
2452 | [endsect] | |
2453 | ||
2454 | [section:coherent_tail_mean coherent_tail_mean] | |
2455 | ||
2456 | Estimation of the coherent tail mean based on order statistics (for both left and right tails). | |
2457 | The left coherent tail mean feature is `tag::coherent_tail_mean<left>`, and the right coherent | |
2458 | tail mean feature is `tag::coherent_tail_mean<right>`. They both share the `tag::tail_mean` feature | |
2459 | and can be extracted with the `tail_mean()` extractor. For more implementation details, see | |
2460 | [classref boost::accumulators::impl::coherent_tail_mean_impl [^coherent_tail_mean_impl]] | |
2461 | ||
2462 | [variablelist | |
2463 | [[Result Type] [`` | |
2464 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2465 | ``]] | |
2466 | [[Depends On] [`count` \n `quantile` \n `non_coherent_tail_mean<_left_or_right_>`]] | |
2467 | [[Variants] [['none]]] | |
2468 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
2469 | [[Accumulator Parameters] [['none]]] | |
2470 | [[Extractor Parameters] [`quantile_probability`]] | |
2471 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
2472 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
2473 | ] | |
2474 | ||
2475 | [*Header] | |
2476 | [def _TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/tail_mean.hpp]] | |
2477 | ||
2478 | #include <_TAIL_MEAN_HPP_> | |
2479 | ||
2480 | [*Example] | |
2481 | ||
2482 | See the example for | |
2483 | [link accumulators.user_s_guide.the_statistical_accumulators_library.non_coherent_tail_mean [^non_coherent_tail_mean]]. | |
2484 | ||
2485 | [*See also] | |
2486 | ||
2487 | * [classref boost::accumulators::impl::coherent_tail_mean_impl [^coherent_tail_mean_impl]] | |
2488 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
2489 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.extended_p_square_quantile [^extended_p_square_quantile]] | |
2490 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.pot_quantile [^pot_quantile]] | |
2491 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_quantile [^tail_quantile]] | |
2492 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.non_coherent_tail_mean [^non_coherent_tail_mean]] | |
2493 | ||
2494 | [endsect] | |
2495 | ||
2496 | [section:non_coherent_tail_mean non_coherent_tail_mean] | |
2497 | ||
2498 | Estimation of the (non-coherent) tail mean based on order statistics (for both left and right tails). | |
2499 | The left non-coherent tail mean feature is `tag::non_coherent_tail_mean<left>`, and the right non-choherent | |
2500 | tail mean feature is `tag::non_coherent_tail_mean<right>`. They both share the `tag::abstract_non_coherent_tail_mean` | |
2501 | feature and can be extracted with the `non_coherent_tail_mean()` extractor. For more implementation details, see | |
2502 | [classref boost::accumulators::impl::non_coherent_tail_mean_impl [^non_coherent_tail_mean_impl]] | |
2503 | ||
2504 | [variablelist | |
2505 | [[Result Type] [`` | |
2506 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2507 | ``]] | |
2508 | [[Depends On] [`count` \n `tail<_left_or_right_>`]] | |
2509 | [[Variants] [`abstract_non_coherent_tail_mean`]] | |
2510 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
2511 | [[Accumulator Parameters] [['none]]] | |
2512 | [[Extractor Parameters] [`quantile_probability`]] | |
2513 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
2514 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
2515 | ] | |
2516 | ||
2517 | [*Header] | |
2518 | [def _TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/tail_mean.hpp]] | |
2519 | ||
2520 | #include <_TAIL_MEAN_HPP_> | |
2521 | ||
2522 | [*Example] | |
2523 | ||
2524 | // tolerance in % | |
2525 | double epsilon = 1; | |
2526 | ||
2527 | std::size_t n = 100000; // number of MC steps | |
2528 | std::size_t c = 10000; // cache size | |
2529 | ||
2530 | typedef accumulator_set<double, stats<tag::non_coherent_tail_mean<right>, tag::tail_quantile<right> > > accumulator_t_right1; | |
2531 | typedef accumulator_set<double, stats<tag::non_coherent_tail_mean<left>, tag::tail_quantile<left> > > accumulator_t_left1; | |
2532 | typedef accumulator_set<double, stats<tag::coherent_tail_mean<right>, tag::tail_quantile<right> > > accumulator_t_right2; | |
2533 | typedef accumulator_set<double, stats<tag::coherent_tail_mean<left>, tag::tail_quantile<left> > > accumulator_t_left2; | |
2534 | ||
2535 | accumulator_t_right1 acc0( right_tail_cache_size = c ); | |
2536 | accumulator_t_left1 acc1( left_tail_cache_size = c ); | |
2537 | accumulator_t_right2 acc2( right_tail_cache_size = c ); | |
2538 | accumulator_t_left2 acc3( left_tail_cache_size = c ); | |
2539 | ||
2540 | // a random number generator | |
2541 | boost::lagged_fibonacci607 rng; | |
2542 | ||
2543 | for (std::size_t i = 0; i < n; ++i) | |
2544 | { | |
2545 | double sample = rng(); | |
2546 | acc0(sample); | |
2547 | acc1(sample); | |
2548 | acc2(sample); | |
2549 | acc3(sample); | |
2550 | } | |
2551 | ||
2552 | // check uniform distribution | |
2553 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc0, quantile_probability = 0.95), 0.975, epsilon ); | |
2554 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc0, quantile_probability = 0.975), 0.9875, epsilon ); | |
2555 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc0, quantile_probability = 0.99), 0.995, epsilon ); | |
2556 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc0, quantile_probability = 0.999), 0.9995, epsilon ); | |
2557 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc1, quantile_probability = 0.05), 0.025, epsilon ); | |
2558 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc1, quantile_probability = 0.025), 0.0125, epsilon ); | |
2559 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc1, quantile_probability = 0.01), 0.005, 5 ); | |
2560 | BOOST_CHECK_CLOSE( non_coherent_tail_mean(acc1, quantile_probability = 0.001), 0.0005, 10 ); | |
2561 | BOOST_CHECK_CLOSE( tail_mean(acc2, quantile_probability = 0.95), 0.975, epsilon ); | |
2562 | BOOST_CHECK_CLOSE( tail_mean(acc2, quantile_probability = 0.975), 0.9875, epsilon ); | |
2563 | BOOST_CHECK_CLOSE( tail_mean(acc2, quantile_probability = 0.99), 0.995, epsilon ); | |
2564 | BOOST_CHECK_CLOSE( tail_mean(acc2, quantile_probability = 0.999), 0.9995, epsilon ); | |
2565 | BOOST_CHECK_CLOSE( tail_mean(acc3, quantile_probability = 0.05), 0.025, epsilon ); | |
2566 | BOOST_CHECK_CLOSE( tail_mean(acc3, quantile_probability = 0.025), 0.0125, epsilon ); | |
2567 | BOOST_CHECK_CLOSE( tail_mean(acc3, quantile_probability = 0.01), 0.005, 5 ); | |
2568 | BOOST_CHECK_CLOSE( tail_mean(acc3, quantile_probability = 0.001), 0.0005, 10 ); | |
2569 | ||
2570 | [*See also] | |
2571 | ||
2572 | * [classref boost::accumulators::impl::non_coherent_tail_mean_impl [^non_coherent_tail_mean_impl]] | |
2573 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
2574 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
2575 | ||
2576 | [endsect] | |
2577 | ||
2578 | [section:tail_quantile tail_quantile] | |
2579 | ||
2580 | Tail quantile estimation based on order statistics (for both left and right tails). | |
2581 | The left tail quantile feature is `tag::tail_quantile<left>`, and the right | |
2582 | tail quantile feature is `tag::tail_quantile<right>`. They both share the `tag::quantile` | |
2583 | feature and can be extracted with the `quantile()` extractor. For more implementation details, see | |
2584 | [classref boost::accumulators::impl::tail_quantile_impl [^tail_quantile_impl]] | |
2585 | ||
2586 | [variablelist | |
2587 | [[Result Type] [`` | |
2588 | _sample_type_ | |
2589 | ``]] | |
2590 | [[Depends On] [`count` \n `tail<_left_or_right_>`]] | |
2591 | [[Variants] [['none]]] | |
2592 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
2593 | [[Accumulator Parameters] [['none]]] | |
2594 | [[Extractor Parameters] [`quantile_probability`]] | |
2595 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
2596 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
2597 | ] | |
2598 | ||
2599 | [*Header] | |
2600 | [def _TAIL_QUANTILE_HPP_ [headerref boost/accumulators/statistics/tail_quantile.hpp]] | |
2601 | ||
2602 | #include <_TAIL_QUANTILE_HPP_> | |
2603 | ||
2604 | [*Example] | |
2605 | ||
2606 | // tolerance in % | |
2607 | double epsilon = 1; | |
2608 | ||
2609 | std::size_t n = 100000; // number of MC steps | |
2610 | std::size_t c = 10000; // cache size | |
2611 | ||
2612 | typedef accumulator_set<double, stats<tag::tail_quantile<right> > > accumulator_t_right; | |
2613 | typedef accumulator_set<double, stats<tag::tail_quantile<left> > > accumulator_t_left; | |
2614 | ||
2615 | accumulator_t_right acc0( tag::tail<right>::cache_size = c ); | |
2616 | accumulator_t_right acc1( tag::tail<right>::cache_size = c ); | |
2617 | accumulator_t_left acc2( tag::tail<left>::cache_size = c ); | |
2618 | accumulator_t_left acc3( tag::tail<left>::cache_size = c ); | |
2619 | ||
2620 | // two random number generators | |
2621 | boost::lagged_fibonacci607 rng; | |
2622 | boost::normal_distribution<> mean_sigma(0,1); | |
2623 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal(rng, mean_sigma); | |
2624 | ||
2625 | for (std::size_t i = 0; i < n; ++i) | |
2626 | { | |
2627 | double sample1 = rng(); | |
2628 | double sample2 = normal(); | |
2629 | acc0(sample1); | |
2630 | acc1(sample2); | |
2631 | acc2(sample1); | |
2632 | acc3(sample2); | |
2633 | } | |
2634 | ||
2635 | // check uniform distribution | |
2636 | BOOST_CHECK_CLOSE( quantile(acc0, quantile_probability = 0.95 ), 0.95, epsilon ); | |
2637 | BOOST_CHECK_CLOSE( quantile(acc0, quantile_probability = 0.975), 0.975, epsilon ); | |
2638 | BOOST_CHECK_CLOSE( quantile(acc0, quantile_probability = 0.99 ), 0.99, epsilon ); | |
2639 | BOOST_CHECK_CLOSE( quantile(acc0, quantile_probability = 0.999), 0.999, epsilon ); | |
2640 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = 0.05 ), 0.05, 2 ); | |
2641 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = 0.025), 0.025, 2 ); | |
2642 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = 0.01 ), 0.01, 3 ); | |
2643 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = 0.001), 0.001, 20 ); | |
2644 | ||
2645 | // check standard normal distribution | |
2646 | BOOST_CHECK_CLOSE( quantile(acc1, quantile_probability = 0.975), 1.959963, epsilon ); | |
2647 | BOOST_CHECK_CLOSE( quantile(acc1, quantile_probability = 0.999), 3.090232, epsilon ); | |
2648 | BOOST_CHECK_CLOSE( quantile(acc3, quantile_probability = 0.025), -1.959963, epsilon ); | |
2649 | BOOST_CHECK_CLOSE( quantile(acc3, quantile_probability = 0.001), -3.090232, epsilon ); | |
2650 | ||
2651 | [*See also] | |
2652 | ||
2653 | * [classref boost::accumulators::impl::tail_quantile_impl [^tail_quantile_impl]] | |
2654 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
2655 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
2656 | ||
2657 | [endsect] | |
2658 | ||
2659 | [section:tail_variate tail_variate] | |
2660 | ||
2661 | Tracks the covariates of largest or smallest [^N] samples. | |
2662 | `tag::tail_variate<_variate_type_, _variate_tag_, right>` tracks the covariate associated with | |
2663 | _variate_tag_ for the largest [^N], and `tag::tail_variate<_variate_type_, _variate_tag_, left>` | |
2664 | for the smallest. The parameter [^N] is specified with the `tag::tail<_left_or_right_>::cache_size` | |
2665 | initialization parameter. For implementation details, see | |
2666 | [classref boost::accumulators::impl::tail_variate_impl [^tail_variate_impl]]. | |
2667 | ||
2668 | Both `tag::tail_variate<_variate_type_, _variate_tag_, right>` and | |
2669 | `tag::tail_variate<_variate_type_, _variate_tag_, left>` satisfy the `tag::abstract_tail_variate` feature | |
2670 | and can be extracted with the `tail_variate()` extractor. | |
2671 | ||
2672 | [variablelist | |
2673 | [[Result Type] [`` | |
2674 | boost::iterator_range< | |
2675 | boost::reverse_iterator< | |
2676 | boost::permutation_iterator< | |
2677 | std::vector<_variate_type_>::const_iterator // variates | |
2678 | , std::vector<std::size_t>::iterator // indices | |
2679 | > | |
2680 | > | |
2681 | > | |
2682 | ``]] | |
2683 | [[Depends On] [`tail<_left_or_right_>`]] | |
2684 | [[Variants] [`abstract_tail_variate`]] | |
2685 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
2686 | [[Accumulator Parameters] [['none]]] | |
2687 | [[Extractor Parameters] [['none]]] | |
2688 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
2689 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
2690 | ] | |
2691 | ||
2692 | [*Header] | |
2693 | [def _TAIL_VARIATE_HPP_ [headerref boost/accumulators/statistics/tail_variate.hpp]] | |
2694 | ||
2695 | #include <_TAIL_VARIATE_HPP_> | |
2696 | ||
2697 | [*Example] | |
2698 | ||
2699 | accumulator_set<int, stats<tag::tail_variate<int, tag::covariate1, right> > > acc( | |
2700 | tag::tail<right>::cache_size = 4 | |
2701 | ); | |
2702 | ||
2703 | acc(8, covariate1 = 3); | |
2704 | CHECK_RANGE_EQUAL(tail(acc), {8}); | |
2705 | CHECK_RANGE_EQUAL(tail_variate(acc), {3}); | |
2706 | ||
2707 | acc(16, covariate1 = 1); | |
2708 | CHECK_RANGE_EQUAL(tail(acc), {16, 8}); | |
2709 | CHECK_RANGE_EQUAL(tail_variate(acc), {1, 3}); | |
2710 | ||
2711 | acc(12, covariate1 = 4); | |
2712 | CHECK_RANGE_EQUAL(tail(acc), {16, 12, 8}); | |
2713 | CHECK_RANGE_EQUAL(tail_variate(acc), {1, 4, 3}); | |
2714 | ||
2715 | acc(24, covariate1 = 5); | |
2716 | CHECK_RANGE_EQUAL(tail(acc), {24, 16, 12, 8}); | |
2717 | CHECK_RANGE_EQUAL(tail_variate(acc), {5, 1, 4, 3}); | |
2718 | ||
2719 | acc(1, covariate1 = 9); | |
2720 | CHECK_RANGE_EQUAL(tail(acc), {24, 16, 12, 8}); | |
2721 | CHECK_RANGE_EQUAL(tail_variate(acc), {5, 1, 4, 3}); | |
2722 | ||
2723 | acc(9, covariate1 = 7); | |
2724 | CHECK_RANGE_EQUAL(tail(acc), {24, 16, 12, 9}); | |
2725 | CHECK_RANGE_EQUAL(tail_variate(acc), {5, 1, 4, 7}); | |
2726 | ||
2727 | [*See also] | |
2728 | ||
2729 | * [classref boost::accumulators::impl::tail_variate_impl [^tail_variate_impl]] | |
2730 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
2731 | ||
2732 | [endsect] | |
2733 | ||
2734 | [section:tail_variate_means tail_variate_means ['and variants]] | |
2735 | ||
2736 | Estimation of the absolute and relative tail variate means (for both left and right tails). | |
2737 | The absolute tail variate means has the feature | |
2738 | `tag::absolute_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>` | |
2739 | and the relative tail variate mean has the feature | |
2740 | `tag::relative_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`. All | |
2741 | absolute tail variate mean features share the `tag::abstract_absolute_tail_variate_means` | |
2742 | feature and can be extracted with the `tail_variate_means()` extractor. All the | |
2743 | relative tail variate mean features share the `tag::abstract_relative_tail_variate_means` | |
2744 | feature and can be extracted with the `relative_tail_variate_means()` extractor. | |
2745 | ||
2746 | For more implementation details, see | |
2747 | [classref boost::accumulators::impl::tail_variate_means_impl [^tail_variate_means_impl]] | |
2748 | ||
2749 | [variablelist | |
2750 | [[Result Type] [`` | |
2751 | boost::iterator_range< | |
2752 | std::vector< | |
2753 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2754 | >::iterator | |
2755 | > | |
2756 | ``]] | |
2757 | [[Depends On] [`non_coherent_tail_mean<_left_or_right_>` \n | |
2758 | `tail_variate<_variate_type_, _variate_tag_, _left_or_right_>`]] | |
2759 | [[Variants] [`tag::absolute_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>` \n | |
2760 | `tag::relative_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`]] | |
2761 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
2762 | [[Accumulator Parameters] [['none]]] | |
2763 | [[Extractor Parameters] [`quantile_probability`]] | |
2764 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
2765 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
2766 | ] | |
2767 | ||
2768 | [*Header] | |
2769 | [def _TAIL_VARIATE_MEANS_HPP_ [headerref boost/accumulators/statistics/tail_variate_means.hpp]] | |
2770 | ||
2771 | #include <_TAIL_VARIATE_MEANS_HPP_> | |
2772 | ||
2773 | [*Example] | |
2774 | ||
2775 | std::size_t c = 5; // cache size | |
2776 | ||
2777 | typedef double variate_type; | |
2778 | typedef std::vector<variate_type> variate_set_type; | |
2779 | ||
2780 | typedef accumulator_set<double, stats< | |
2781 | tag::tail_variate_means<right, variate_set_type, tag::covariate1>(relative)>, tag::tail<right> > | |
2782 | accumulator_t1; | |
2783 | ||
2784 | typedef accumulator_set<double, stats< | |
2785 | tag::tail_variate_means<right, variate_set_type, tag::covariate1>(absolute)>, tag::tail<right> > | |
2786 | accumulator_t2; | |
2787 | ||
2788 | typedef accumulator_set<double, stats< | |
2789 | tag::tail_variate_means<left, variate_set_type, tag::covariate1>(relative)>, tag::tail<left> > | |
2790 | accumulator_t3; | |
2791 | ||
2792 | typedef accumulator_set<double, stats< | |
2793 | tag::tail_variate_means<left, variate_set_type, tag::covariate1>(absolute)>, tag::tail<left> > | |
2794 | accumulator_t4; | |
2795 | ||
2796 | accumulator_t1 acc1( right_tail_cache_size = c ); | |
2797 | accumulator_t2 acc2( right_tail_cache_size = c ); | |
2798 | accumulator_t3 acc3( left_tail_cache_size = c ); | |
2799 | accumulator_t4 acc4( left_tail_cache_size = c ); | |
2800 | ||
2801 | variate_set_type cov1, cov2, cov3, cov4, cov5; | |
2802 | double c1[] = { 10., 20., 30., 40. }; // 100 | |
2803 | double c2[] = { 26., 4., 17., 3. }; // 50 | |
2804 | double c3[] = { 46., 64., 40., 50. }; // 200 | |
2805 | double c4[] = { 1., 3., 70., 6. }; // 80 | |
2806 | double c5[] = { 2., 2., 2., 14. }; // 20 | |
2807 | cov1.assign(c1, c1 + sizeof(c1)/sizeof(variate_type)); | |
2808 | cov2.assign(c2, c2 + sizeof(c2)/sizeof(variate_type)); | |
2809 | cov3.assign(c3, c3 + sizeof(c3)/sizeof(variate_type)); | |
2810 | cov4.assign(c4, c4 + sizeof(c4)/sizeof(variate_type)); | |
2811 | cov5.assign(c5, c5 + sizeof(c5)/sizeof(variate_type)); | |
2812 | ||
2813 | acc1(100., covariate1 = cov1); | |
2814 | acc1( 50., covariate1 = cov2); | |
2815 | acc1(200., covariate1 = cov3); | |
2816 | acc1( 80., covariate1 = cov4); | |
2817 | acc1( 20., covariate1 = cov5); | |
2818 | ||
2819 | acc2(100., covariate1 = cov1); | |
2820 | acc2( 50., covariate1 = cov2); | |
2821 | acc2(200., covariate1 = cov3); | |
2822 | acc2( 80., covariate1 = cov4); | |
2823 | acc2( 20., covariate1 = cov5); | |
2824 | ||
2825 | acc3(100., covariate1 = cov1); | |
2826 | acc3( 50., covariate1 = cov2); | |
2827 | acc3(200., covariate1 = cov3); | |
2828 | acc3( 80., covariate1 = cov4); | |
2829 | acc3( 20., covariate1 = cov5); | |
2830 | ||
2831 | acc4(100., covariate1 = cov1); | |
2832 | acc4( 50., covariate1 = cov2); | |
2833 | acc4(200., covariate1 = cov3); | |
2834 | acc4( 80., covariate1 = cov4); | |
2835 | acc4( 20., covariate1 = cov5); | |
2836 | ||
2837 | // check relative risk contributions | |
2838 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.7).begin() ), 14./75. ); // (10 + 46) / 300 = 14/75 | |
2839 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.7).begin() + 1), 7./25. ); // (20 + 64) / 300 = 7/25 | |
2840 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.7).begin() + 2), 7./30. ); // (30 + 40) / 300 = 7/30 | |
2841 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.7).begin() + 3), 3./10. ); // (40 + 50) / 300 = 3/10 | |
2842 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.3).begin() ), 14./35. ); // (26 + 2) / 70 = 14/35 | |
2843 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.3).begin() + 1), 3./35. ); // ( 4 + 2) / 70 = 3/35 | |
2844 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.3).begin() + 2), 19./70. ); // (17 + 2) / 70 = 19/70 | |
2845 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.3).begin() + 3), 17./70. ); // ( 3 + 14) / 70 = 17/70 | |
2846 | ||
2847 | // check absolute risk contributions | |
2848 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.7).begin() ), 28 ); // (10 + 46) / 2 = 28 | |
2849 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.7).begin() + 1), 42 ); // (20 + 64) / 2 = 42 | |
2850 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.7).begin() + 2), 35 ); // (30 + 40) / 2 = 35 | |
2851 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.7).begin() + 3), 45 ); // (40 + 50) / 2 = 45 | |
2852 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.3).begin() ), 14 ); // (26 + 2) / 2 = 14 | |
2853 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.3).begin() + 1), 3 ); // ( 4 + 2) / 2 = 3 | |
2854 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.3).begin() + 2),9.5 ); // (17 + 2) / 2 = 9.5 | |
2855 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.3).begin() + 3),8.5 ); // ( 3 + 14) / 2 = 8.5 | |
2856 | ||
2857 | // check relative risk contributions | |
2858 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.9).begin() ), 23./100. ); // 46/200 = 23/100 | |
2859 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.9).begin() + 1), 8./25. ); // 64/200 = 8/25 | |
2860 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.9).begin() + 2), 1./5. ); // 40/200 = 1/5 | |
2861 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc1, quantile_probability = 0.9).begin() + 3), 1./4. ); // 50/200 = 1/4 | |
2862 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.1).begin() ), 1./10. ); // 2/ 20 = 1/10 | |
2863 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.1).begin() + 1), 1./10. ); // 2/ 20 = 1/10 | |
2864 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.1).begin() + 2), 1./10. ); // 2/ 20 = 1/10 | |
2865 | BOOST_CHECK_EQUAL( *(relative_tail_variate_means(acc3, quantile_probability = 0.1).begin() + 3), 7./10. ); // 14/ 20 = 7/10 | |
2866 | ||
2867 | // check absolute risk contributions | |
2868 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.9).begin() ), 46 ); // 46 | |
2869 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.9).begin() + 1), 64 ); // 64 | |
2870 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.9).begin() + 2), 40 ); // 40 | |
2871 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc2, quantile_probability = 0.9).begin() + 3), 50 ); // 50 | |
2872 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.1).begin() ), 2 ); // 2 | |
2873 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.1).begin() + 1), 2 ); // 2 | |
2874 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.1).begin() + 2), 2 ); // 2 | |
2875 | BOOST_CHECK_EQUAL( *(tail_variate_means(acc4, quantile_probability = 0.1).begin() + 3), 14 ); // 14 | |
2876 | ||
2877 | [*See also] | |
2878 | ||
2879 | * [classref boost::accumulators::impl::tail_variate_means_impl [^tail_variate_means_impl]] | |
2880 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.non_coherent_tail_mean [^non_coherent_tail_mean]] | |
2881 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_variate [^tail_variate]] | |
2882 | ||
2883 | [endsect] | |
2884 | ||
2885 | [section:variance variance ['and variants]] | |
2886 | ||
2887 | Lazy or iterative calculation of the variance. The lazy calculation is associated with the `tag::lazy_variance` | |
2888 | feature, and the iterative calculation with the `tag::variance` feature. Both can be extracted | |
2889 | using the `tag::variance()` extractor. For more implementation details, see | |
2890 | [classref boost::accumulators::impl::lazy_variance_impl [^lazy_variance_impl]] and | |
2891 | [classref boost::accumulators::impl::variance_impl [^variance_impl]] | |
2892 | ||
2893 | [variablelist | |
2894 | [[Result Type] [`` | |
2895 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2896 | ``]] | |
2897 | [[Depends On] [`tag::lazy_variance` depends on `tag::moment<2>` and `tag::mean` \n | |
2898 | `tag::variance` depends on `tag::count` and `tag::immediate_mean`]] | |
2899 | [[Variants] [`tag::lazy_variance` (a.k.a. `tag::variance(lazy))` \n | |
2900 | `tag::variance` (a.k.a. `tag::variance(immediate)`)]] | |
2901 | [[Initialization Parameters] [['none]]] | |
2902 | [[Accumulator Parameters] [['none]]] | |
2903 | [[Extractor Parameters] [['none]]] | |
2904 | [[Accumulator Complexity] [O(1)]] | |
2905 | [[Extractor Complexity] [O(1)]] | |
2906 | ] | |
2907 | ||
2908 | [*Header] | |
2909 | [def _VARIANCE_HPP_ [headerref boost/accumulators/statistics/variance.hpp]] | |
2910 | ||
2911 | #include <_VARIANCE_HPP_> | |
2912 | ||
2913 | [*Example] | |
2914 | ||
2915 | // lazy variance | |
2916 | accumulator_set<int, stats<tag::variance(lazy)> > acc1; | |
2917 | ||
2918 | acc1(1); | |
2919 | acc1(2); | |
2920 | acc1(3); | |
2921 | acc1(4); | |
2922 | acc1(5); | |
2923 | ||
2924 | BOOST_CHECK_EQUAL(5u, count(acc1)); | |
2925 | BOOST_CHECK_CLOSE(3., mean(acc1), 1e-5); | |
2926 | BOOST_CHECK_CLOSE(11., accumulators::moment<2>(acc1), 1e-5); | |
2927 | BOOST_CHECK_CLOSE(2., variance(acc1), 1e-5); | |
2928 | ||
2929 | // immediate variance | |
2930 | accumulator_set<int, stats<tag::variance> > acc2; | |
2931 | ||
2932 | acc2(1); | |
2933 | acc2(2); | |
2934 | acc2(3); | |
2935 | acc2(4); | |
2936 | acc2(5); | |
2937 | ||
2938 | BOOST_CHECK_EQUAL(5u, count(acc2)); | |
2939 | BOOST_CHECK_CLOSE(3., mean(acc2), 1e-5); | |
2940 | BOOST_CHECK_CLOSE(2., variance(acc2), 1e-5); | |
2941 | ||
2942 | [*See also] | |
2943 | ||
2944 | * [classref boost::accumulators::impl::lazy_variance_impl [^lazy_variance_impl]] | |
2945 | * [classref boost::accumulators::impl::variance_impl [^variance_impl]] | |
2946 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
2947 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.mean [^mean]] | |
2948 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.moment [^moment]] | |
2949 | ||
2950 | [endsect] | |
2951 | ||
2952 | [section:weighted_covariance weighted_covariance] | |
2953 | ||
2954 | An iterative Monte Carlo estimator for the weighted covariance. The feature is specified as | |
2955 | `tag::weighted_covariance<_variate_type_, _variate_tag_>` and is extracted with the `weighted_variate()` | |
2956 | extractor. For more implementation details, see | |
2957 | [classref boost::accumulators::impl::weighted_covariance_impl [^weighted_covariance_impl]] | |
2958 | ||
2959 | [variablelist | |
2960 | [[Result Type] [`` | |
2961 | numeric::functional::outer_product< | |
2962 | numeric::functional::multiplies< | |
2963 | _weight_type_ | |
2964 | , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
2965 | >::result_type | |
2966 | , numeric::functional::multiplies< | |
2967 | _weight_type_ | |
2968 | , numeric::functional::fdiv<_variate_type_, std::size_t>::result_type | |
2969 | >::result_type | |
2970 | > | |
2971 | ``]] | |
2972 | [[Depends On] [`count` \n | |
2973 | `sum_of_weights` \n | |
2974 | `weighted_mean` \n | |
2975 | `weighted_mean_of_variates<_variate_type_, _variate_tag_>`]] | |
2976 | [[Variants] [`abstract_weighted_covariance`]] | |
2977 | [[Initialization Parameters] [['none]]] | |
2978 | [[Accumulator Parameters] [`weight` \n | |
2979 | `_variate_tag_`]] | |
2980 | [[Extractor Parameters] [['none]]] | |
2981 | [[Accumulator Complexity] [O(1)]] | |
2982 | [[Extractor Complexity] [O(1)]] | |
2983 | ] | |
2984 | ||
2985 | [*Header] | |
2986 | [def _WEIGHTED_COVARIANCE_HPP_ [headerref boost/accumulators/statistics/weighted_covariance.hpp]] | |
2987 | ||
2988 | #include <_WEIGHTED_COVARIANCE_HPP_> | |
2989 | ||
2990 | [*Example] | |
2991 | ||
2992 | accumulator_set<double, stats<tag::weighted_covariance<double, tag::covariate1> >, double > acc; | |
2993 | ||
2994 | acc(1., weight = 1.1, covariate1 = 2.); | |
2995 | acc(1., weight = 2.2, covariate1 = 4.); | |
2996 | acc(2., weight = 3.3, covariate1 = 3.); | |
2997 | acc(6., weight = 4.4, covariate1 = 1.); | |
2998 | ||
2999 | double epsilon = 1e-6; | |
3000 | BOOST_CHECK_CLOSE(weighted_covariance(acc), -2.39, epsilon); | |
3001 | ||
3002 | [*See also] | |
3003 | ||
3004 | * [classref boost::accumulators::impl::weighted_covariance_impl [^weighted_covariance_impl]] | |
3005 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3006 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3007 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_mean [^weighted_mean]] | |
3008 | ||
3009 | [endsect] | |
3010 | ||
3011 | [section:weighted_density weighted_density] | |
3012 | ||
3013 | The `tag::weighted_density` feature returns a histogram of the weighted sample distribution. For more | |
3014 | implementation details, see [classref boost::accumulators::impl::weighted_density_impl [^weighted_density_impl]]. | |
3015 | ||
3016 | [variablelist | |
3017 | [[Result Type] [`` | |
3018 | iterator_range< | |
3019 | std::vector< | |
3020 | std::pair< | |
3021 | numeric::functional::fdiv<_weight_type_, std::size_t>::result_type | |
3022 | , numeric::functional::fdiv<_weight_type_, std::size_t>::result_type | |
3023 | > | |
3024 | >::iterator | |
3025 | > | |
3026 | ``]] | |
3027 | [[Depends On] [`count` \n `sum_of_weights` \n `min` \n `max`]] | |
3028 | [[Variants] [['none]]] | |
3029 | [[Initialization Parameters] [`tag::weighted_density::cache_size` \n `tag::weighted_density::num_bins`]] | |
3030 | [[Accumulator Parameters] [`weight`]] | |
3031 | [[Extractor Parameters] [['none]]] | |
3032 | [[Accumulator Complexity] [TODO]] | |
3033 | [[Extractor Complexity] [O(N), when N is `weighted_density::num_bins`]] | |
3034 | ] | |
3035 | ||
3036 | [*Header] | |
3037 | [def _WEIGHTED_DENSITY_HPP_ [headerref boost/accumulators/statistics/weighted_density.hpp]] | |
3038 | ||
3039 | #include <_WEIGHTED_DENSITY_HPP_> | |
3040 | ||
3041 | [/ TODO add example ] | |
3042 | ||
3043 | [*See also] | |
3044 | ||
3045 | * [classref boost::accumulators::impl::weighted_density_impl [^weighted_density_impl]] | |
3046 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3047 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3048 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.min [^min]] | |
3049 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.max [^max]] | |
3050 | ||
3051 | [endsect] | |
3052 | ||
3053 | [section:weighted_extended_p_square weighted_extended_p_square] | |
3054 | ||
3055 | Multiple quantile estimation with the extended [^P^2] algorithm for weighted samples. For further | |
3056 | details, see [classref boost::accumulators::impl::weighted_extended_p_square_impl [^weighted_extended_p_square_impl]]. | |
3057 | ||
3058 | [variablelist | |
3059 | [[Result Type] [`` | |
3060 | boost::iterator_range< | |
3061 | _implementation_defined_ | |
3062 | > | |
3063 | ``]] | |
3064 | [[Depends On] [`count` \n `sum_of_weights`]] | |
3065 | [[Variants] [['none]]] | |
3066 | [[Initialization Parameters] [`tag::weighted_extended_p_square::probabilities`]] | |
3067 | [[Accumulator Parameters] [`weight`]] | |
3068 | [[Extractor Parameters] [['none]]] | |
3069 | [[Accumulator Complexity] [TODO]] | |
3070 | [[Extractor Complexity] [O(1)]] | |
3071 | ] | |
3072 | ||
3073 | [*Header] | |
3074 | [def _WEIGHTED_EXTENDED_P_SQUARE_HPP_ [headerref boost/accumulators/statistics/weighted_extended_p_square.hpp]] | |
3075 | ||
3076 | #include <_WEIGHTED_EXTENDED_P_SQUARE_HPP_> | |
3077 | ||
3078 | [*Example] | |
3079 | ||
3080 | typedef accumulator_set<double, stats<tag::weighted_extended_p_square>, double> accumulator_t; | |
3081 | ||
3082 | // tolerance in % | |
3083 | double epsilon = 1; | |
3084 | ||
3085 | // some random number generators | |
3086 | double mu1 = -1.0; | |
3087 | double mu2 = 1.0; | |
3088 | boost::lagged_fibonacci607 rng; | |
3089 | boost::normal_distribution<> mean_sigma1(mu1, 1); | |
3090 | boost::normal_distribution<> mean_sigma2(mu2, 1); | |
3091 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal1(rng, mean_sigma1); | |
3092 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal2(rng, mean_sigma2); | |
3093 | ||
3094 | std::vector<double> probs_uniform, probs_normal1, probs_normal2, probs_normal_exact1, probs_normal_exact2; | |
3095 | ||
3096 | double p1[] = {/*0.001,*/ 0.01, 0.1, 0.5, 0.9, 0.99, 0.999}; | |
3097 | probs_uniform.assign(p1, p1 + sizeof(p1) / sizeof(double)); | |
3098 | ||
3099 | double p2[] = {0.001, 0.025}; | |
3100 | double p3[] = {0.975, 0.999}; | |
3101 | probs_normal1.assign(p2, p2 + sizeof(p2) / sizeof(double)); | |
3102 | probs_normal2.assign(p3, p3 + sizeof(p3) / sizeof(double)); | |
3103 | ||
3104 | double p4[] = {-3.090232, -1.959963}; | |
3105 | double p5[] = {1.959963, 3.090232}; | |
3106 | probs_normal_exact1.assign(p4, p4 + sizeof(p4) / sizeof(double)); | |
3107 | probs_normal_exact2.assign(p5, p5 + sizeof(p5) / sizeof(double)); | |
3108 | ||
3109 | accumulator_t acc_uniform(tag::weighted_extended_p_square::probabilities = probs_uniform); | |
3110 | accumulator_t acc_normal1(tag::weighted_extended_p_square::probabilities = probs_normal1); | |
3111 | accumulator_t acc_normal2(tag::weighted_extended_p_square::probabilities = probs_normal2); | |
3112 | ||
3113 | for (std::size_t i = 0; i < 100000; ++i) | |
3114 | { | |
3115 | acc_uniform(rng(), weight = 1.); | |
3116 | ||
3117 | double sample1 = normal1(); | |
3118 | double sample2 = normal2(); | |
3119 | acc_normal1(sample1, weight = std::exp(-mu1 * (sample1 - 0.5 * mu1))); | |
3120 | acc_normal2(sample2, weight = std::exp(-mu2 * (sample2 - 0.5 * mu2))); | |
3121 | } | |
3122 | ||
3123 | // check for uniform distribution | |
3124 | for (std::size_t i = 0; i < probs_uniform.size(); ++i) | |
3125 | { | |
3126 | BOOST_CHECK_CLOSE(weighted_extended_p_square(acc_uniform)[i], probs_uniform[i], epsilon); | |
3127 | } | |
3128 | ||
3129 | // check for standard normal distribution | |
3130 | for (std::size_t i = 0; i < probs_normal1.size(); ++i) | |
3131 | { | |
3132 | BOOST_CHECK_CLOSE(weighted_extended_p_square(acc_normal1)[i], probs_normal_exact1[i], epsilon); | |
3133 | BOOST_CHECK_CLOSE(weighted_extended_p_square(acc_normal2)[i], probs_normal_exact2[i], epsilon); | |
3134 | } | |
3135 | ||
3136 | [*See also] | |
3137 | ||
3138 | * [classref boost::accumulators::impl::weighted_extended_p_square_impl [^weighted_extended_p_square_impl]] | |
3139 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3140 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3141 | ||
3142 | [endsect] | |
3143 | ||
3144 | [section:weighted_kurtosis weighted_kurtosis] | |
3145 | ||
3146 | The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the | |
3147 | square of the 2nd central moment (the variance) of the samples, minus 3. The term [^-3] is added | |
3148 | in order to ensure that the normal distribution has zero kurtosis. For more implementation | |
3149 | details, see [classref boost::accumulators::impl::weighted_kurtosis_impl [^weighted_kurtosis_impl]] | |
3150 | ||
3151 | [variablelist | |
3152 | [[Result Type] [`` | |
3153 | numeric::functional::fdiv< | |
3154 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3155 | , numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3156 | >::result_type | |
3157 | ``]] | |
3158 | [[Depends On] [`weighted_mean` \n `weighted_moment<2>` \n `weighted_moment<3>` \n `weighted_moment<4>`]] | |
3159 | [[Variants] [['none]]] | |
3160 | [[Initialization Parameters] [['none]]] | |
3161 | [[Accumulator Parameters] [['none]]] | |
3162 | [[Extractor Parameters] [['none]]] | |
3163 | [[Accumulator Complexity] [O(1)]] | |
3164 | [[Extractor Complexity] [O(1)]] | |
3165 | ] | |
3166 | ||
3167 | [*Header] | |
3168 | [def _WEIGHTED_KURTOSIS_HPP_ [headerref boost/accumulators/statistics/weighted_kurtosis.hpp]] | |
3169 | ||
3170 | #include <_WEIGHTED_KURTOSIS_HPP_> | |
3171 | ||
3172 | [*Example] | |
3173 | ||
3174 | accumulator_set<int, stats<tag::weighted_kurtosis>, int > acc2; | |
3175 | ||
3176 | acc2(2, weight = 4); | |
3177 | acc2(7, weight = 1); | |
3178 | acc2(4, weight = 3); | |
3179 | acc2(9, weight = 1); | |
3180 | acc2(3, weight = 2); | |
3181 | ||
3182 | BOOST_CHECK_EQUAL( weighted_mean(acc2), 42./11. ); | |
3183 | BOOST_CHECK_EQUAL( accumulators::weighted_moment<2>(acc2), 212./11. ); | |
3184 | BOOST_CHECK_EQUAL( accumulators::weighted_moment<3>(acc2), 1350./11. ); | |
3185 | BOOST_CHECK_EQUAL( accumulators::weighted_moment<4>(acc2), 9956./11. ); | |
3186 | BOOST_CHECK_CLOSE( weighted_kurtosis(acc2), 0.58137026432, 1e-6 ); | |
3187 | ||
3188 | [*See also] | |
3189 | ||
3190 | * [classref boost::accumulators::impl::weighted_kurtosis_impl [^weighted_kurtosis_impl]] | |
3191 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_mean [^weighted_mean]] | |
3192 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_moment [^weighted_moment]] | |
3193 | ||
3194 | [endsect] | |
3195 | ||
3196 | [section:weighted_mean weighted_mean ['and variants]] | |
3197 | ||
3198 | Calculates the weighted mean of samples or variates. The calculation is either | |
3199 | lazy (in the result extractor), or immediate (in the accumulator). The lazy implementation | |
3200 | is the default. For more implementation details, see | |
3201 | [classref boost::accumulators::impl::weighted_mean_impl [^weighted_mean_impl]] or. | |
3202 | [classref boost::accumulators::impl::immediate_weighted_mean_impl [^immediate_weighted_mean_impl]] | |
3203 | ||
3204 | [variablelist | |
3205 | [[Result Type] [For samples, `numeric::functional::fdiv<numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type, _weight_type_>::result_type` \n | |
3206 | For variates, `numeric::functional::fdiv<numeric::functional::multiplies<_variate_type_, _weight_type_>::result_type, _weight_type_>::result_type`]] | |
3207 | [[Depends On] [`sum_of_weights` \n | |
3208 | The lazy mean of samples depends on `weighted_sum` \n | |
3209 | The lazy mean of variates depends on `weighted_sum_of_variates<>`]] | |
3210 | [[Variants] [`weighted_mean_of_variates<_variate_type_, _variate_tag_>` \n | |
3211 | `immediate_weighted_mean` \n | |
3212 | `immediate_weighted_mean_of_variates<_variate_type_, _variate_tag_>`]] | |
3213 | [[Initialization Parameters] [['none]]] | |
3214 | [[Accumulator Parameters] [['none]]] | |
3215 | [[Extractor Parameters] [['none]]] | |
3216 | [[Accumulator Complexity] [O(1)]] | |
3217 | [[Extractor Complexity] [O(1)]] | |
3218 | ] | |
3219 | ||
3220 | [*Header] | |
3221 | [def _WEIGHTED_MEAN_HPP_ [headerref boost/accumulators/statistics/weighted_mean.hpp]] | |
3222 | ||
3223 | #include <_WEIGHTED_MEAN_HPP_> | |
3224 | ||
3225 | [*Example] | |
3226 | ||
3227 | accumulator_set< | |
3228 | int | |
3229 | , stats< | |
3230 | tag::weighted_mean | |
3231 | , tag::weighted_mean_of_variates<int, tag::covariate1> | |
3232 | > | |
3233 | , int | |
3234 | > acc; | |
3235 | ||
3236 | acc(10, weight = 2, covariate1 = 7); // 20 | |
3237 | BOOST_CHECK_EQUAL(2, sum_of_weights(acc)); // | |
3238 | // | |
3239 | acc(6, weight = 3, covariate1 = 8); // 18 | |
3240 | BOOST_CHECK_EQUAL(5, sum_of_weights(acc)); // | |
3241 | // | |
3242 | acc(4, weight = 4, covariate1 = 9); // 16 | |
3243 | BOOST_CHECK_EQUAL(9, sum_of_weights(acc)); // | |
3244 | // | |
3245 | acc(6, weight = 5, covariate1 = 6); //+ 30 | |
3246 | BOOST_CHECK_EQUAL(14, sum_of_weights(acc)); // | |
3247 | //= 84 / 14 = 6 | |
3248 | ||
3249 | BOOST_CHECK_EQUAL(6., weighted_mean(acc)); | |
3250 | BOOST_CHECK_EQUAL(52./7., (accumulators::weighted_mean_of_variates<int, tag::covariate1>(acc))); | |
3251 | ||
3252 | accumulator_set< | |
3253 | int | |
3254 | , stats< | |
3255 | tag::weighted_mean(immediate) | |
3256 | , tag::weighted_mean_of_variates<int, tag::covariate1>(immediate) | |
3257 | > | |
3258 | , int | |
3259 | > acc2; | |
3260 | ||
3261 | acc2(10, weight = 2, covariate1 = 7); // 20 | |
3262 | BOOST_CHECK_EQUAL(2, sum_of_weights(acc2)); // | |
3263 | // | |
3264 | acc2(6, weight = 3, covariate1 = 8); // 18 | |
3265 | BOOST_CHECK_EQUAL(5, sum_of_weights(acc2)); // | |
3266 | // | |
3267 | acc2(4, weight = 4, covariate1 = 9); // 16 | |
3268 | BOOST_CHECK_EQUAL(9, sum_of_weights(acc2)); // | |
3269 | // | |
3270 | acc2(6, weight = 5, covariate1 = 6); //+ 30 | |
3271 | BOOST_CHECK_EQUAL(14, sum_of_weights(acc2)); // | |
3272 | //= 84 / 14 = 6 | |
3273 | ||
3274 | BOOST_CHECK_EQUAL(6., weighted_mean(acc2)); | |
3275 | BOOST_CHECK_EQUAL(52./7., (accumulators::weighted_mean_of_variates<int, tag::covariate1>(acc2))); | |
3276 | ||
3277 | [*See also] | |
3278 | ||
3279 | * [classref boost::accumulators::impl::weighted_mean_impl [^weighted_mean_impl]] | |
3280 | * [classref boost::accumulators::impl::immediate_weighted_mean_impl [^immediate_weighted_mean_impl]] | |
3281 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_sum [^weighted_sum]] | |
3282 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3283 | ||
3284 | [endsect] | |
3285 | ||
3286 | [section:weighted_median weighted_median ['and variants]] | |
3287 | ||
3288 | Median estimation for weighted samples based on the [^P^2] quantile estimator, the density estimator, or | |
3289 | the [^P^2] cumulative distribution estimator. For more implementation details, see | |
3290 | [classref boost::accumulators::impl::weighted_median_impl [^weighted_median_impl]], | |
3291 | [classref boost::accumulators::impl::with_weighted_density_median_impl [^with_weighted_density_median_impl]], | |
3292 | and [classref boost::accumulators::impl::with_weighted_p_square_cumulative_distribution_median_impl [^with_weighted_p_square_cumulative_distribution_median_impl]]. | |
3293 | ||
3294 | The three median accumulators all satisfy the `tag::weighted_median` feature, and can all be | |
3295 | extracted with the `weighted_median()` extractor. | |
3296 | ||
3297 | [variablelist | |
3298 | [[Result Type] [`` | |
3299 | numeric::functional::fdiv<_sample_type_, std::size_t>::result_type | |
3300 | ``]] | |
3301 | [[Depends On] [`weighted_median` depends on `weighted_p_square_quantile_for_median` \n | |
3302 | `with_weighted_density_median` depends on `count` and `weighted_density` \n | |
3303 | `with_weighted_p_square_cumulative_distribution_median` depends on `weighted_p_square_cumulative_distribution`]] | |
3304 | [[Variants] [`with_weighted_density_median` (a.k.a. `weighted_median(with_weighted_density)`) \n | |
3305 | `with_weighted_p_square_cumulative_distribution_median` (a.k.a. `weighted_median(with_weighted_p_square_cumulative_distribution)`)]] | |
3306 | [[Initialization Parameters] [`with_weighted_density_median` requires `tag::weighted_density::cache_size` and `tag::weighted_density::num_bins` \n | |
3307 | `with_weighted_p_square_cumulative_distribution_median` requires `tag::weighted_p_square_cumulative_distribution::num_cells`]] | |
3308 | [[Accumulator Parameters] [`weight`]] | |
3309 | [[Extractor Parameters] [['none]]] | |
3310 | [[Accumulator Complexity] [TODO]] | |
3311 | [[Extractor Complexity] [TODO]] | |
3312 | ] | |
3313 | ||
3314 | [*Header] | |
3315 | [def _WEIGHTED_MEDIAN_HPP_ [headerref boost/accumulators/statistics/weighted_median.hpp]] | |
3316 | ||
3317 | #include <_WEIGHTED_MEDIAN_HPP_> | |
3318 | ||
3319 | [*Example] | |
3320 | ||
3321 | // Median estimation of normal distribution N(1,1) using samples from a narrow normal distribution N(1,0.01) | |
3322 | // The weights equal to the likelihood ratio of the corresponding samples | |
3323 | ||
3324 | // two random number generators | |
3325 | double mu = 1.; | |
3326 | double sigma_narrow = 0.01; | |
3327 | double sigma = 1.; | |
3328 | boost::lagged_fibonacci607 rng; | |
3329 | boost::normal_distribution<> mean_sigma_narrow(mu,sigma_narrow); | |
3330 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal_narrow(rng, mean_sigma_narrow); | |
3331 | ||
3332 | accumulator_set<double, stats<tag::weighted_median(with_weighted_p_square_quantile) >, double > acc; | |
3333 | accumulator_set<double, stats<tag::weighted_median(with_weighted_density) >, double > | |
3334 | acc_dens( tag::weighted_density::cache_size = 10000, tag::weighted_density::num_bins = 1000 ); | |
3335 | accumulator_set<double, stats<tag::weighted_median(with_weighted_p_square_cumulative_distribution) >, double > | |
3336 | acc_cdist( tag::weighted_p_square_cumulative_distribution::num_cells = 100 ); | |
3337 | ||
3338 | for (std::size_t i=0; i<100000; ++i) | |
3339 | { | |
3340 | double sample = normal_narrow(); | |
3341 | acc(sample, weight = std::exp(0.5 * (sample - mu) * (sample - mu) * ( 1./sigma_narrow/sigma_narrow - 1./sigma/sigma ))); | |
3342 | acc_dens(sample, weight = std::exp(0.5 * (sample - mu) * (sample - mu) * ( 1./sigma_narrow/sigma_narrow - 1./sigma/sigma ))); | |
3343 | acc_cdist(sample, weight = std::exp(0.5 * (sample - mu) * (sample - mu) * ( 1./sigma_narrow/sigma_narrow - 1./sigma/sigma ))); | |
3344 | } | |
3345 | ||
3346 | BOOST_CHECK_CLOSE(1., weighted_median(acc), 1e-1); | |
3347 | BOOST_CHECK_CLOSE(1., weighted_median(acc_dens), 1e-1); | |
3348 | BOOST_CHECK_CLOSE(1., weighted_median(acc_cdist), 1e-1); | |
3349 | ||
3350 | [*See also] | |
3351 | ||
3352 | * [classref boost::accumulators::impl::weighted_median_impl [^weighted_median_impl]] | |
3353 | * [classref boost::accumulators::impl::with_weighted_density_median_impl [^with_weighted_density_median_impl]] | |
3354 | * [classref boost::accumulators::impl::with_weighted_p_square_cumulative_distribution_median_impl [^with_weighted_p_square_cumulative_distribution_median_impl]] | |
3355 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3356 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_p_square_quantile [^weighted_p_square_quantile]] | |
3357 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_p_square_cumulative_distribution [^weighted_p_square_cumulative_distribution]] | |
3358 | ||
3359 | [endsect] | |
3360 | ||
3361 | [section:weighted_moment weighted_moment] | |
3362 | ||
3363 | Calculates the N-th moment of the weighted samples, which is defined as the sum of the weighted N-th | |
3364 | power of the samples over the sum of the weights. | |
3365 | ||
3366 | [variablelist | |
3367 | [[Result Type] [`` | |
3368 | numeric::functional::fdiv< | |
3369 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3370 | , weight_type | |
3371 | >::result_type | |
3372 | ``]] | |
3373 | [[Depends On] [`count` \n `sum_of_weights`]] | |
3374 | [[Variants] [['none]]] | |
3375 | [[Initialization Parameters] [['none]]] | |
3376 | [[Accumulator Parameters] [`weight`]] | |
3377 | [[Extractor Parameters] [['none]]] | |
3378 | [[Accumulator Complexity] [O(1)]] | |
3379 | [[Extractor Complexity] [O(1)]] | |
3380 | ] | |
3381 | ||
3382 | [*Header] | |
3383 | [def _WEIGHTED_MOMENT_HPP_ [headerref boost/accumulators/statistics/weighted_moment.hpp]] | |
3384 | ||
3385 | #include <_WEIGHTED_MOMENT_HPP_> | |
3386 | ||
3387 | [*Example] | |
3388 | ||
3389 | accumulator_set<double, stats<tag::weighted_moment<2> >, double> acc2; | |
3390 | accumulator_set<double, stats<tag::weighted_moment<7> >, double> acc7; | |
3391 | ||
3392 | acc2(2.1, weight = 0.7); | |
3393 | acc2(2.7, weight = 1.4); | |
3394 | acc2(1.8, weight = 0.9); | |
3395 | ||
3396 | acc7(2.1, weight = 0.7); | |
3397 | acc7(2.7, weight = 1.4); | |
3398 | acc7(1.8, weight = 0.9); | |
3399 | ||
3400 | BOOST_CHECK_CLOSE(5.403, accumulators::weighted_moment<2>(acc2), 1e-5); | |
3401 | BOOST_CHECK_CLOSE(548.54182, accumulators::weighted_moment<7>(acc7), 1e-5); | |
3402 | ||
3403 | [*See also] | |
3404 | ||
3405 | * [classref boost::accumulators::impl::weighted_moment_impl [^weighted_moment_impl]] | |
3406 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3407 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3408 | ||
3409 | [endsect] | |
3410 | ||
3411 | [section:weighted_p_square_cumulative_distribution weighted_p_square_cumulative_distribution] | |
3412 | ||
3413 | Histogram calculation of the cumulative distribution with the [^P^2] algorithm for weighted samples. | |
3414 | For more implementation details, see | |
3415 | [classref boost::accumulators::impl::weighted_p_square_cumulative_distribution_impl [^weighted_p_square_cumulative_distribution_impl]] | |
3416 | ||
3417 | [variablelist | |
3418 | [[Result Type] [`` | |
3419 | iterator_range< | |
3420 | std::vector< | |
3421 | std::pair< | |
3422 | numeric::functional::fdiv<weighted_sample, std::size_t>::result_type | |
3423 | , numeric::functional::fdiv<weighted_sample, std::size_t>::result_type | |
3424 | > | |
3425 | >::iterator | |
3426 | > | |
3427 | `` | |
3428 | where `weighted_sample` is `numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type`]] | |
3429 | [[Depends On] [`count` \n `sum_or_weights`]] | |
3430 | [[Variants] [['none]]] | |
3431 | [[Initialization Parameters] [`tag::weighted_p_square_cumulative_distribution::num_cells`]] | |
3432 | [[Accumulator Parameters] [`weight`]] | |
3433 | [[Extractor Parameters] [['none]]] | |
3434 | [[Accumulator Complexity] [TODO]] | |
3435 | [[Extractor Complexity] [O(N) where N is `num_cells`]] | |
3436 | ] | |
3437 | ||
3438 | [*Header] | |
3439 | [def _WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_ [headerref boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp]] | |
3440 | ||
3441 | #include <_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_> | |
3442 | ||
3443 | [*Example] | |
3444 | ||
3445 | // tolerance in % | |
3446 | double epsilon = 4; | |
3447 | ||
3448 | typedef accumulator_set<double, stats<tag::weighted_p_square_cumulative_distribution>, double > accumulator_t; | |
3449 | ||
3450 | accumulator_t acc_upper(tag::weighted_p_square_cumulative_distribution::num_cells = 100); | |
3451 | accumulator_t acc_lower(tag::weighted_p_square_cumulative_distribution::num_cells = 100); | |
3452 | ||
3453 | // two random number generators | |
3454 | double mu_upper = 1.0; | |
3455 | double mu_lower = -1.0; | |
3456 | boost::lagged_fibonacci607 rng; | |
3457 | boost::normal_distribution<> mean_sigma_upper(mu_upper,1); | |
3458 | boost::normal_distribution<> mean_sigma_lower(mu_lower,1); | |
3459 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal_upper(rng, mean_sigma_upper); | |
3460 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal_lower(rng, mean_sigma_lower); | |
3461 | ||
3462 | for (std::size_t i=0; i<100000; ++i) | |
3463 | { | |
3464 | double sample = normal_upper(); | |
3465 | acc_upper(sample, weight = std::exp(-mu_upper * (sample - 0.5 * mu_upper))); | |
3466 | } | |
3467 | ||
3468 | for (std::size_t i=0; i<100000; ++i) | |
3469 | { | |
3470 | double sample = normal_lower(); | |
3471 | acc_lower(sample, weight = std::exp(-mu_lower * (sample - 0.5 * mu_lower))); | |
3472 | } | |
3473 | ||
3474 | typedef iterator_range<std::vector<std::pair<double, double> >::iterator > histogram_type; | |
3475 | histogram_type histogram_upper = weighted_p_square_cumulative_distribution(acc_upper); | |
3476 | histogram_type histogram_lower = weighted_p_square_cumulative_distribution(acc_lower); | |
3477 | ||
3478 | // Note that applying importance sampling results in a region of the distribution | |
3479 | // to be estimated more accurately and another region to be estimated less accurately | |
3480 | // than without importance sampling, i.e., with unweighted samples | |
3481 | ||
3482 | for (std::size_t i = 0; i < histogram_upper.size(); ++i) | |
3483 | { | |
3484 | // problem with small results: epsilon is relative (in percent), not absolute! | |
3485 | ||
3486 | // check upper region of distribution | |
3487 | if ( histogram_upper[i].second > 0.1 ) | |
3488 | BOOST_CHECK_CLOSE( 0.5 * (1.0 + erf( histogram_upper[i].first / sqrt(2.0) )), histogram_upper[i].second, epsilon ); | |
3489 | // check lower region of distribution | |
3490 | if ( histogram_lower[i].second < -0.1 ) | |
3491 | BOOST_CHECK_CLOSE( 0.5 * (1.0 + erf( histogram_lower[i].first / sqrt(2.0) )), histogram_lower[i].second, epsilon ); | |
3492 | } | |
3493 | ||
3494 | [*See also] | |
3495 | ||
3496 | * [classref boost::accumulators::impl::weighted_p_square_cumulative_distribution_impl [^weighted_p_square_cumulative_distribution_impl]] | |
3497 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3498 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3499 | ||
3500 | [endsect] | |
3501 | ||
3502 | [section:weighted_p_square_quantile weighted_p_square_quantile ['and variants]] | |
3503 | ||
3504 | Single quantile estimation with the [^P^2] algorithm. For more implementation details, see | |
3505 | [classref boost::accumulators::impl::weighted_p_square_quantile_impl [^weighted_p_square_quantile_impl]] | |
3506 | ||
3507 | [variablelist | |
3508 | [[Result Type] [`` | |
3509 | numeric::functional::fdiv< | |
3510 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3511 | , std::size_t | |
3512 | >::result_type | |
3513 | ``]] | |
3514 | [[Depends On] [`count` \n `sum_of_weights`]] | |
3515 | [[Variants] [`weighted_p_square_quantile_for_median`]] | |
3516 | [[Initialization Parameters] [`quantile_probability`, which defaults to `0.5`. | |
3517 | (Note: for `weighted_p_square_quantile_for_median`, the `quantile_probability` | |
3518 | parameter is ignored and is always `0.5`.)]] | |
3519 | [[Accumulator Parameters] [`weight`]] | |
3520 | [[Extractor Parameters] [['none]]] | |
3521 | [[Accumulator Complexity] [TODO]] | |
3522 | [[Extractor Complexity] [O(1)]] | |
3523 | ] | |
3524 | ||
3525 | [*Header] | |
3526 | [def _WEIGHTED_P_SQUARE_QUANTILE_HPP_ [headerref boost/accumulators/statistics/weighted_p_square_quantile.hpp]] | |
3527 | ||
3528 | #include <_WEIGHTED_P_SQUARE_QUANTILE_HPP_> | |
3529 | ||
3530 | [*Example] | |
3531 | ||
3532 | typedef accumulator_set<double, stats<tag::weighted_p_square_quantile>, double> accumulator_t; | |
3533 | ||
3534 | // tolerance in % | |
3535 | double epsilon = 1; | |
3536 | ||
3537 | // some random number generators | |
3538 | double mu4 = -1.0; | |
3539 | double mu5 = -1.0; | |
3540 | double mu6 = 1.0; | |
3541 | double mu7 = 1.0; | |
3542 | boost::lagged_fibonacci607 rng; | |
3543 | boost::normal_distribution<> mean_sigma4(mu4, 1); | |
3544 | boost::normal_distribution<> mean_sigma5(mu5, 1); | |
3545 | boost::normal_distribution<> mean_sigma6(mu6, 1); | |
3546 | boost::normal_distribution<> mean_sigma7(mu7, 1); | |
3547 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal4(rng, mean_sigma4); | |
3548 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal5(rng, mean_sigma5); | |
3549 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal6(rng, mean_sigma6); | |
3550 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal7(rng, mean_sigma7); | |
3551 | ||
3552 | accumulator_t acc0(quantile_probability = 0.001); | |
3553 | accumulator_t acc1(quantile_probability = 0.025); | |
3554 | accumulator_t acc2(quantile_probability = 0.975); | |
3555 | accumulator_t acc3(quantile_probability = 0.999); | |
3556 | ||
3557 | accumulator_t acc4(quantile_probability = 0.001); | |
3558 | accumulator_t acc5(quantile_probability = 0.025); | |
3559 | accumulator_t acc6(quantile_probability = 0.975); | |
3560 | accumulator_t acc7(quantile_probability = 0.999); | |
3561 | ||
3562 | ||
3563 | for (std::size_t i=0; i<100000; ++i) | |
3564 | { | |
3565 | double sample = rng(); | |
3566 | acc0(sample, weight = 1.); | |
3567 | acc1(sample, weight = 1.); | |
3568 | acc2(sample, weight = 1.); | |
3569 | acc3(sample, weight = 1.); | |
3570 | ||
3571 | double sample4 = normal4(); | |
3572 | double sample5 = normal5(); | |
3573 | double sample6 = normal6(); | |
3574 | double sample7 = normal7(); | |
3575 | acc4(sample4, weight = std::exp(-mu4 * (sample4 - 0.5 * mu4))); | |
3576 | acc5(sample5, weight = std::exp(-mu5 * (sample5 - 0.5 * mu5))); | |
3577 | acc6(sample6, weight = std::exp(-mu6 * (sample6 - 0.5 * mu6))); | |
3578 | acc7(sample7, weight = std::exp(-mu7 * (sample7 - 0.5 * mu7))); | |
3579 | } | |
3580 | ||
3581 | // check for uniform distribution with weight = 1 | |
3582 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc0), 0.001, 15 ); | |
3583 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc1), 0.025, 5 ); | |
3584 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc2), 0.975, epsilon ); | |
3585 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc3), 0.999, epsilon ); | |
3586 | ||
3587 | // check for shifted standard normal distribution ("importance sampling") | |
3588 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc4), -3.090232, epsilon ); | |
3589 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc5), -1.959963, epsilon ); | |
3590 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc6), 1.959963, epsilon ); | |
3591 | BOOST_CHECK_CLOSE( weighted_p_square_quantile(acc7), 3.090232, epsilon ); | |
3592 | ||
3593 | [*See also] | |
3594 | ||
3595 | * [classref boost::accumulators::impl::weighted_p_square_quantile_impl [^weighted_p_square_quantile_impl]] | |
3596 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
3597 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3598 | ||
3599 | [endsect] | |
3600 | ||
3601 | [section:weighted_peaks_over_threshold weighted_peaks_over_threshold ['and variants]] | |
3602 | ||
3603 | Weighted peaks over threshold method for weighted quantile and weighted tail mean estimation. | |
3604 | For more implementation details, | |
3605 | see [classref boost::accumulators::impl::weighted_peaks_over_threshold_impl [^weighted_peaks_over_threshold_impl]] | |
3606 | and [classref boost::accumulators::impl::weighted_peaks_over_threshold_prob_impl [^weighted_peaks_over_threshold_prob_impl]]. | |
3607 | ||
3608 | Both `tag::weighted_peaks_over_threshold<_left_or_right_>` and | |
3609 | `tag::weighted_peaks_over_threshold_prob<_left_or_right_>` satisfy the | |
3610 | `tag::weighted_peaks_over_threshold<_left_or_right_>` feature and can be extracted using the | |
3611 | `weighted_peaks_over_threshold()` extractor. | |
3612 | ||
3613 | [variablelist | |
3614 | [[Result Type] [`tuple<float_type, float_type, float_type>` where `float_type` is | |
3615 | `` | |
3616 | numeric::functional::fdiv< | |
3617 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3618 | , std::size_t | |
3619 | >::result_type | |
3620 | ``]] | |
3621 | [[Depends On] [`weighted_peaks_over_threshold<_left_or_right_>` depends on `sum_of_weights` \n | |
3622 | `weighted_peaks_over_threshold_prob<_left_or_right_>` depends on `sum_of_weights` and `tail_weights<_left_or_right_>`]] | |
3623 | [[Variants] [`weighted_peaks_over_threshold_prob`]] | |
3624 | [[Initialization Parameters] [ `tag::peaks_over_threshold::threshold_value` \n | |
3625 | `tag::peaks_over_threshold_prob::threshold_probability` \n | |
3626 | `tag::tail<_left_or_right_>::cache_size` ]] | |
3627 | [[Accumulator Parameters] [`weight`]] | |
3628 | [[Extractor Parameters] [['none]]] | |
3629 | [[Accumulator Complexity] [TODO]] | |
3630 | [[Extractor Complexity] [O(1)]] | |
3631 | ] | |
3632 | ||
3633 | [*Header] | |
3634 | [def _WEIGHTED_PEAKS_OVER_THRESHOLD_HPP_ [headerref boost/accumulators/statistics/weighted_peaks_over_threshold.hpp]] | |
3635 | ||
3636 | #include <_WEIGHTED_PEAKS_OVER_THRESHOLD_HPP_> | |
3637 | ||
3638 | [/ TODO Add example] | |
3639 | ||
3640 | [*See also] | |
3641 | ||
3642 | * [classref boost::accumulators::impl::weighted_peaks_over_threshold_impl [^weighted_peaks_over_threshold_impl]] | |
3643 | * [classref boost::accumulators::impl::weighted_peaks_over_threshold_prob_impl [^weighted_peaks_over_threshold_prob_impl]] | |
3644 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3645 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
3646 | ||
3647 | [endsect] | |
3648 | ||
3649 | [section:weighted_skewness weighted_skewness] | |
3650 | ||
3651 | The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the [^3/2]-th power | |
3652 | of the 2nd central moment (the variance) of the samples 3. The skewness estimator for weighted samples | |
3653 | is formally identical to the estimator for unweighted samples, except that the weighted counterparts of | |
3654 | all measures it depends on are to be taken. | |
3655 | ||
3656 | For implementation details, see | |
3657 | [classref boost::accumulators::impl::weighted_skewness_impl [^weighted_skewness_impl]]. | |
3658 | ||
3659 | [variablelist | |
3660 | [[Result Type] [`` | |
3661 | numeric::functional::fdiv< | |
3662 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3663 | , numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3664 | >::result_type | |
3665 | ``]] | |
3666 | [[Depends On] [`weighted_mean` \n `weighted_moment<2>` \n `weighted_moment<3>`]] | |
3667 | [[Variants] [['none]]] | |
3668 | [[Initialization Parameters] [['none]]] | |
3669 | [[Accumulator Parameters] [`weight`]] | |
3670 | [[Extractor Parameters] [['none]]] | |
3671 | [[Accumulator Complexity] [O(1)]] | |
3672 | [[Extractor Complexity] [O(1)]] | |
3673 | ] | |
3674 | ||
3675 | [*Header] | |
3676 | [def _WEIGHTED_SKEWNESS_HPP_ [headerref boost/accumulators/statistics/weighted_skewness.hpp]] | |
3677 | ||
3678 | #include <_WEIGHTED_SKEWNESS_HPP_> | |
3679 | ||
3680 | [*Example] | |
3681 | ||
3682 | accumulator_set<int, stats<tag::weighted_skewness>, int > acc2; | |
3683 | ||
3684 | acc2(2, weight = 4); | |
3685 | acc2(7, weight = 1); | |
3686 | acc2(4, weight = 3); | |
3687 | acc2(9, weight = 1); | |
3688 | acc2(3, weight = 2); | |
3689 | ||
3690 | BOOST_CHECK_EQUAL( weighted_mean(acc2), 42./11. ); | |
3691 | BOOST_CHECK_EQUAL( accumulators::weighted_moment<2>(acc2), 212./11. ); | |
3692 | BOOST_CHECK_EQUAL( accumulators::weighted_moment<3>(acc2), 1350./11. ); | |
3693 | BOOST_CHECK_CLOSE( weighted_skewness(acc2), 1.30708406282, 1e-6 ); | |
3694 | ||
3695 | [*See also] | |
3696 | ||
3697 | * [classref boost::accumulators::impl::weighted_skewness_impl [^weighted_skewness_impl]] | |
3698 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_mean [^weighted_mean]] | |
3699 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_moment [^weighted_moment]] | |
3700 | ||
3701 | [endsect] | |
3702 | ||
3703 | [section:weighted_sum weighted_sum ['and variants]] | |
3704 | ||
3705 | For summing the weighted samples or variates. All of the `tag::weighted_sum_of_variates<>` features | |
3706 | can be extracted with the `weighted_sum_of_variates()` extractor. Variants that implement the Kahan | |
3707 | summation algorithm are also provided. | |
3708 | ||
3709 | [variablelist | |
3710 | [[Result Type] [`numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type` for summing weighted samples \n | |
3711 | `numeric::functional::multiplies<_variate_type_, _weight_type_>::result_type` for summing weighted variates]] | |
3712 | [[Depends On] [['none]]] | |
3713 | [[Variants] [`tag::weighted_sum` \n | |
3714 | `tag::weighted_sum_of_variates<_variate_type_, _variate_tag_>` \n | |
3715 | `tag::weighted_sum_kahan` (a.k.a. tag::weighted_sum(kahan)) \n | |
3716 | `tag::weighted_sum_of_variates_kahan<_variate_type_, _variate_tag_>` \n]] | |
3717 | [[Initialization Parameters] [['none]]] | |
3718 | [[Accumulator Parameters] [`weight` \n | |
3719 | `_variate_tag_` for summing variates]] | |
3720 | [[Extractor Parameters] [['none]]] | |
3721 | [[Accumulator Complexity] [O(1). Note that the Kahan sum performs four floating-point sum | |
3722 | operations per accumulated value, whereas the naive sum | |
3723 | performs only one.]] | |
3724 | [[Extractor Complexity] [O(1)]] | |
3725 | ] | |
3726 | ||
3727 | [*Header] | |
3728 | [def _WEIGHTED_SUM_HPP_ [headerref boost/accumulators/statistics/weighted_sum.hpp]] | |
3729 | [def _WEIGHTED_SUM_KAHAN_HPP_ [headerref boost/accumulators/statistics/weighted_sum_kahan.hpp]] | |
3730 | ||
3731 | #include <_WEIGHTED_SUM_HPP_> | |
3732 | #include <_WEIGHTED_SUM_KAHAN_HPP_> | |
3733 | ||
3734 | ||
3735 | [*Example] | |
3736 | ||
3737 | accumulator_set<int, stats<tag::weighted_sum, tag::weighted_sum_of_variates<int, tag::covariate1> >, int> acc; | |
3738 | ||
3739 | acc(1, weight = 2, covariate1 = 3); | |
3740 | BOOST_CHECK_EQUAL(2, weighted_sum(acc)); | |
3741 | BOOST_CHECK_EQUAL(6, weighted_sum_of_variates(acc)); | |
3742 | ||
3743 | acc(2, weight = 3, covariate1 = 6); | |
3744 | BOOST_CHECK_EQUAL(8, weighted_sum(acc)); | |
3745 | BOOST_CHECK_EQUAL(24, weighted_sum_of_variates(acc)); | |
3746 | ||
3747 | acc(4, weight = 6, covariate1 = 9); | |
3748 | BOOST_CHECK_EQUAL(32, weighted_sum(acc)); | |
3749 | BOOST_CHECK_EQUAL(78, weighted_sum_of_variates(acc)); | |
3750 | ||
3751 | // demonstrate weighted Kahan summation | |
3752 | accumulator_set<float, stats<tag::weighted_sum_kahan>, float > acc; | |
3753 | BOOST_CHECK_EQUAL(0.0f, weighted_sum_kahan(acc)); | |
3754 | for (size_t i = 0; i < 1e6; ++i) { | |
3755 | acc(1.0f, weight = 1e-6f); | |
3756 | } | |
3757 | BOOST_CHECK_EQUAL(1.0f, weighted_sum_kahan(acc)); | |
3758 | ||
3759 | [*See also] | |
3760 | ||
3761 | * [classref boost::accumulators::impl::weighted_sum_impl [^weighted_sum_impl]] | |
3762 | * [classref boost::accumulators::impl::weighted_sum_impl [^weighted_sum_kahan_impl]] | |
3763 | ||
3764 | [endsect] | |
3765 | ||
3766 | [section:non_coherent_weighted_tail_mean non_coherent_weighted_tail_mean] | |
3767 | ||
3768 | Estimation of the (non-coherent) weighted tail mean based on order statistics (for both left and right tails). | |
3769 | The left non-coherent weighted tail mean feature is `tag::non_coherent_weighted_tail_mean<left>`, and the right | |
3770 | non-choherent weighted tail mean feature is `tag::non_coherent_weighted_tail_mean<right>`. They both share the | |
3771 | `tag::abstract_non_coherent_tail_mean` feature with the unweighted non-coherent tail mean accumulators and can | |
3772 | be extracted with either the `non_coherent_tail_mean()` or the `non_coherent_weighted_tail_mean()` extractors. | |
3773 | For more implementation details, see | |
3774 | [classref boost::accumulators::impl::non_coherent_weighted_tail_mean_impl [^non_coherent_weighted_tail_mean_impl]]. | |
3775 | ||
3776 | [variablelist | |
3777 | [[Result Type] [`` | |
3778 | numeric::functional::fdiv< | |
3779 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
3780 | , std::size_t | |
3781 | >::result_type | |
3782 | ``]] | |
3783 | [[Depends On] [`sum_of_weights` \n `tail_weights<_left_or_right_>`]] | |
3784 | [[Variants] [`abstract_non_coherent_tail_mean`]] | |
3785 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
3786 | [[Accumulator Parameters] [['none]]] | |
3787 | [[Extractor Parameters] [`quantile_probability`]] | |
3788 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
3789 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
3790 | ] | |
3791 | ||
3792 | [*Header] | |
3793 | [def _WEIGHTED_TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/weighted_tail_mean.hpp]] | |
3794 | ||
3795 | #include <_WEIGHTED_TAIL_MEAN_HPP_> | |
3796 | ||
3797 | [*Example] | |
3798 | ||
3799 | // tolerance in % | |
3800 | double epsilon = 1; | |
3801 | ||
3802 | std::size_t n = 100000; // number of MC steps | |
3803 | std::size_t c = 25000; // cache size | |
3804 | ||
3805 | accumulator_set<double, stats<tag::non_coherent_weighted_tail_mean<right> >, double > | |
3806 | acc0( right_tail_cache_size = c ); | |
3807 | accumulator_set<double, stats<tag::non_coherent_weighted_tail_mean<left> >, double > | |
3808 | acc1( left_tail_cache_size = c ); | |
3809 | ||
3810 | // random number generators | |
3811 | boost::lagged_fibonacci607 rng; | |
3812 | ||
3813 | for (std::size_t i = 0; i < n; ++i) | |
3814 | { | |
3815 | double smpl = std::sqrt(rng()); | |
3816 | acc0(smpl, weight = 1./smpl); | |
3817 | } | |
3818 | ||
3819 | for (std::size_t i = 0; i < n; ++i) | |
3820 | { | |
3821 | double smpl = rng(); | |
3822 | acc1(smpl*smpl, weight = smpl); | |
3823 | } | |
3824 | ||
3825 | // check uniform distribution | |
3826 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc0, quantile_probability = 0.95), 0.975, epsilon ); | |
3827 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc0, quantile_probability = 0.975), 0.9875, epsilon ); | |
3828 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc0, quantile_probability = 0.99), 0.995, epsilon ); | |
3829 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc0, quantile_probability = 0.999), 0.9995, epsilon ); | |
3830 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc1, quantile_probability = 0.05), 0.025, epsilon ); | |
3831 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc1, quantile_probability = 0.025), 0.0125, epsilon ); | |
3832 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc1, quantile_probability = 0.01), 0.005, epsilon ); | |
3833 | BOOST_CHECK_CLOSE( non_coherent_weighted_tail_mean(acc1, quantile_probability = 0.001), 0.0005, 5*epsilon ); | |
3834 | ||
3835 | [*See also] | |
3836 | ||
3837 | * [classref boost::accumulators::impl::non_coherent_weighted_tail_mean_impl [^non_coherent_weighted_tail_mean_impl]] | |
3838 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3839 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
3840 | ||
3841 | [endsect] | |
3842 | ||
3843 | [section:weighted_tail_quantile weighted_tail_quantile] | |
3844 | ||
3845 | Tail quantile estimation based on order statistics of weighted samples (for both left | |
3846 | and right tails). The left weighted tail quantile feature is `tag::weighted_tail_quantile<left>`, | |
3847 | and the right weighted tail quantile feature is `tag::weighted_tail_quantile<right>`. They both | |
3848 | share the `tag::quantile` feature with the unweighted tail quantile accumulators and can be | |
3849 | extracted with either the `quantile()` or the `weighted_tail_quantile()` extractors. For more | |
3850 | implementation details, see | |
3851 | [classref boost::accumulators::impl::weighted_tail_quantile_impl [^weighted_tail_quantile_impl]] | |
3852 | ||
3853 | [variablelist | |
3854 | [[Result Type] [`` | |
3855 | _sample_type_ | |
3856 | ``]] | |
3857 | [[Depends On] [`sum_of_weights` \n `tail_weights<_left_or_right_>`]] | |
3858 | [[Variants] [['none]]] | |
3859 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
3860 | [[Accumulator Parameters] [['none]]] | |
3861 | [[Extractor Parameters] [`quantile_probability`]] | |
3862 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
3863 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
3864 | ] | |
3865 | ||
3866 | [*Header] | |
3867 | [def _WEIGHTED_TAIL_QUANTILE_HPP_ [headerref boost/accumulators/statistics/weighted_tail_quantile.hpp]] | |
3868 | ||
3869 | #include <_WEIGHTED_TAIL_QUANTILE_HPP_> | |
3870 | ||
3871 | [*Example] | |
3872 | ||
3873 | // tolerance in % | |
3874 | double epsilon = 1; | |
3875 | ||
3876 | std::size_t n = 100000; // number of MC steps | |
3877 | std::size_t c = 20000; // cache size | |
3878 | ||
3879 | double mu1 = 1.0; | |
3880 | double mu2 = -1.0; | |
3881 | boost::lagged_fibonacci607 rng; | |
3882 | boost::normal_distribution<> mean_sigma1(mu1,1); | |
3883 | boost::normal_distribution<> mean_sigma2(mu2,1); | |
3884 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal1(rng, mean_sigma1); | |
3885 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal2(rng, mean_sigma2); | |
3886 | ||
3887 | accumulator_set<double, stats<tag::weighted_tail_quantile<right> >, double> | |
3888 | acc1(right_tail_cache_size = c); | |
3889 | ||
3890 | accumulator_set<double, stats<tag::weighted_tail_quantile<left> >, double> | |
3891 | acc2(left_tail_cache_size = c); | |
3892 | ||
3893 | for (std::size_t i = 0; i < n; ++i) | |
3894 | { | |
3895 | double sample1 = normal1(); | |
3896 | double sample2 = normal2(); | |
3897 | acc1(sample1, weight = std::exp(-mu1 * (sample1 - 0.5 * mu1))); | |
3898 | acc2(sample2, weight = std::exp(-mu2 * (sample2 - 0.5 * mu2))); | |
3899 | } | |
3900 | ||
3901 | // check standard normal distribution | |
3902 | BOOST_CHECK_CLOSE( quantile(acc1, quantile_probability = 0.975), 1.959963, epsilon ); | |
3903 | BOOST_CHECK_CLOSE( quantile(acc1, quantile_probability = 0.999), 3.090232, epsilon ); | |
3904 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = 0.025), -1.959963, epsilon ); | |
3905 | BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = 0.001), -3.090232, epsilon ); | |
3906 | ||
3907 | [*See also] | |
3908 | ||
3909 | * [classref boost::accumulators::impl::weighted_tail_quantile_impl [^weighted_tail_quantile_impl]] | |
3910 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.sum [^sum]] | |
3911 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
3912 | ||
3913 | [endsect] | |
3914 | ||
3915 | [section:weighted_tail_variate_means weighted_tail_variate_means ['and variants]] | |
3916 | ||
3917 | Estimation of the absolute and relative weighted tail variate means (for both left and right tails) | |
3918 | The absolute weighted tail variate means has the feature | |
3919 | `tag::absolute_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>` | |
3920 | and the relative weighted tail variate mean has the feature | |
3921 | `tag::relative_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`. All | |
3922 | absolute weighted tail variate mean features share the `tag::abstract_absolute_tail_variate_means` | |
3923 | feature with their unweighted variants and can be extracted with the `tail_variate_means()` and | |
3924 | `weighted_tail_variate_means()` extractors. All the relative weighted tail variate mean features | |
3925 | share the `tag::abstract_relative_tail_variate_means` feature with their unweighted variants | |
3926 | and can be extracted with either the `relative_tail_variate_means()` or | |
3927 | `relative_weighted_tail_variate_means()` extractors. | |
3928 | ||
3929 | For more implementation details, see | |
3930 | [classref boost::accumulators::impl::weighted_tail_variate_means_impl [^weighted_tail_variate_means_impl]] | |
3931 | ||
3932 | [variablelist | |
3933 | [[Result Type] [`` | |
3934 | boost::iterator_range< | |
3935 | numeric::functional::fdiv< | |
3936 | numeric::functional::multiplies<_variate_type_, _weight_type_>::result_type | |
3937 | , _weight_type_ | |
3938 | >::result_type::iterator | |
3939 | > | |
3940 | ``]] | |
3941 | [[Depends On] [`non_coherent_weighted_tail_mean<_left_or_right_>` \n | |
3942 | `tail_variate<_variate_type_, _variate_tag_, _left_or_right_>` \n | |
3943 | `tail_weights<_left_or_right_>`]] | |
3944 | [[Variants] [`tag::absolute_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>` \n | |
3945 | `tag::relative_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`]] | |
3946 | [[Initialization Parameters] [`tag::tail<_left_or_right_>::cache_size`]] | |
3947 | [[Accumulator Parameters] [['none]]] | |
3948 | [[Extractor Parameters] [`quantile_probability`]] | |
3949 | [[Accumulator Complexity] [O(log N), where N is the cache size]] | |
3950 | [[Extractor Complexity] [O(N log N), where N is the cache size]] | |
3951 | ] | |
3952 | ||
3953 | [*Header] | |
3954 | [def _WEIGHTED_TAIL_VARIATE_MEANS_HPP_ [headerref boost/accumulators/statistics/weighted_tail_variate_means.hpp]] | |
3955 | ||
3956 | #include <_WEIGHTED_TAIL_VARIATE_MEANS_HPP_> | |
3957 | ||
3958 | [*Example] | |
3959 | ||
3960 | std::size_t c = 5; // cache size | |
3961 | ||
3962 | typedef double variate_type; | |
3963 | typedef std::vector<variate_type> variate_set_type; | |
3964 | ||
3965 | accumulator_set<double, stats<tag::weighted_tail_variate_means<right, variate_set_type, tag::covariate1>(relative)>, double > | |
3966 | acc1( right_tail_cache_size = c ); | |
3967 | accumulator_set<double, stats<tag::weighted_tail_variate_means<right, variate_set_type, tag::covariate1>(absolute)>, double > | |
3968 | acc2( right_tail_cache_size = c ); | |
3969 | accumulator_set<double, stats<tag::weighted_tail_variate_means<left, variate_set_type, tag::covariate1>(relative)>, double > | |
3970 | acc3( left_tail_cache_size = c ); | |
3971 | accumulator_set<double, stats<tag::weighted_tail_variate_means<left, variate_set_type, tag::covariate1>(absolute)>, double > | |
3972 | acc4( left_tail_cache_size = c ); | |
3973 | ||
3974 | variate_set_type cov1, cov2, cov3, cov4, cov5; | |
3975 | double c1[] = { 10., 20., 30., 40. }; // 100 | |
3976 | double c2[] = { 26., 4., 17., 3. }; // 50 | |
3977 | double c3[] = { 46., 64., 40., 50. }; // 200 | |
3978 | double c4[] = { 1., 3., 70., 6. }; // 80 | |
3979 | double c5[] = { 2., 2., 2., 14. }; // 20 | |
3980 | cov1.assign(c1, c1 + sizeof(c1)/sizeof(variate_type)); | |
3981 | cov2.assign(c2, c2 + sizeof(c2)/sizeof(variate_type)); | |
3982 | cov3.assign(c3, c3 + sizeof(c3)/sizeof(variate_type)); | |
3983 | cov4.assign(c4, c4 + sizeof(c4)/sizeof(variate_type)); | |
3984 | cov5.assign(c5, c5 + sizeof(c5)/sizeof(variate_type)); | |
3985 | ||
3986 | acc1(100., weight = 0.8, covariate1 = cov1); | |
3987 | acc1( 50., weight = 0.9, covariate1 = cov2); | |
3988 | acc1(200., weight = 1.0, covariate1 = cov3); | |
3989 | acc1( 80., weight = 1.1, covariate1 = cov4); | |
3990 | acc1( 20., weight = 1.2, covariate1 = cov5); | |
3991 | ||
3992 | acc2(100., weight = 0.8, covariate1 = cov1); | |
3993 | acc2( 50., weight = 0.9, covariate1 = cov2); | |
3994 | acc2(200., weight = 1.0, covariate1 = cov3); | |
3995 | acc2( 80., weight = 1.1, covariate1 = cov4); | |
3996 | acc2( 20., weight = 1.2, covariate1 = cov5); | |
3997 | ||
3998 | acc3(100., weight = 0.8, covariate1 = cov1); | |
3999 | acc3( 50., weight = 0.9, covariate1 = cov2); | |
4000 | acc3(200., weight = 1.0, covariate1 = cov3); | |
4001 | acc3( 80., weight = 1.1, covariate1 = cov4); | |
4002 | acc3( 20., weight = 1.2, covariate1 = cov5); | |
4003 | ||
4004 | acc4(100., weight = 0.8, covariate1 = cov1); | |
4005 | acc4( 50., weight = 0.9, covariate1 = cov2); | |
4006 | acc4(200., weight = 1.0, covariate1 = cov3); | |
4007 | acc4( 80., weight = 1.1, covariate1 = cov4); | |
4008 | acc4( 20., weight = 1.2, covariate1 = cov5); | |
4009 | ||
4010 | // check relative risk contributions | |
4011 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.7).begin() ), (0.8*10 + 1.0*46)/(0.8*100 + 1.0*200) ); | |
4012 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.7).begin() + 1), (0.8*20 + 1.0*64)/(0.8*100 + 1.0*200) ); | |
4013 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.7).begin() + 2), (0.8*30 + 1.0*40)/(0.8*100 + 1.0*200) ); | |
4014 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.7).begin() + 3), (0.8*40 + 1.0*50)/(0.8*100 + 1.0*200) ); | |
4015 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.3).begin() ), (0.9*26 + 1.2*2)/(0.9*50 + 1.2*20) ); | |
4016 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.3).begin() + 1), (0.9*4 + 1.2*2)/(0.9*50 + 1.2*20) ); | |
4017 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.3).begin() + 2), (0.9*17 + 1.2*2)/(0.9*50 + 1.2*20) ); | |
4018 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.3).begin() + 3), (0.9*3 + 1.2*14)/(0.9*50 + 1.2*20) ); | |
4019 | ||
4020 | // check absolute risk contributions | |
4021 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.7).begin() ), (0.8*10 + 1.0*46)/1.8 ); | |
4022 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.7).begin() + 1), (0.8*20 + 1.0*64)/1.8 ); | |
4023 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.7).begin() + 2), (0.8*30 + 1.0*40)/1.8 ); | |
4024 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.7).begin() + 3), (0.8*40 + 1.0*50)/1.8 ); | |
4025 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.3).begin() ), (0.9*26 + 1.2*2)/2.1 ); | |
4026 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.3).begin() + 1), (0.9*4 + 1.2*2)/2.1 ); | |
4027 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.3).begin() + 2), (0.9*17 + 1.2*2)/2.1 ); | |
4028 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.3).begin() + 3), (0.9*3 + 1.2*14)/2.1 ); | |
4029 | ||
4030 | // check relative risk contributions | |
4031 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.9).begin() ), 1.0*46/(1.0*200) ); | |
4032 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.9).begin() + 1), 1.0*64/(1.0*200) ); | |
4033 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.9).begin() + 2), 1.0*40/(1.0*200) ); | |
4034 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc1, quantile_probability = 0.9).begin() + 3), 1.0*50/(1.0*200) ); | |
4035 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.1).begin() ), 1.2*2/(1.2*20) ); | |
4036 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.1).begin() + 1), 1.2*2/(1.2*20) ); | |
4037 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.1).begin() + 2), 1.2*2/(1.2*20) ); | |
4038 | BOOST_CHECK_EQUAL( *(relative_weighted_tail_variate_means(acc3, quantile_probability = 0.1).begin() + 3), 1.2*14/(1.2*20) ); | |
4039 | ||
4040 | // check absolute risk contributions | |
4041 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.9).begin() ), 1.0*46/1.0 ); | |
4042 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.9).begin() + 1), 1.0*64/1.0 ); | |
4043 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.9).begin() + 2), 1.0*40/1.0 ); | |
4044 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc2, quantile_probability = 0.9).begin() + 3), 1.0*50/1.0 ); | |
4045 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.1).begin() ), 1.2*2/1.2 ); | |
4046 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.1).begin() + 1), 1.2*2/1.2 ); | |
4047 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.1).begin() + 2), 1.2*2/1.2 ); | |
4048 | BOOST_CHECK_EQUAL( *(weighted_tail_variate_means(acc4, quantile_probability = 0.1).begin() + 3), 1.2*14/1.2 ); | |
4049 | ||
4050 | [*See also] | |
4051 | ||
4052 | * [classref boost::accumulators::impl::weighted_tail_variate_means_impl [^weighted_tail_variate_means_impl]] | |
4053 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.non_coherent_weighted_tail_mean [^non_coherent_weighted_tail_mean]] | |
4054 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_variate [^tail_variate]] | |
4055 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]] | |
4056 | ||
4057 | [endsect] | |
4058 | ||
4059 | [section:weighted_variance weighted_variance ['and variants]] | |
4060 | ||
4061 | Lazy or iterative calculation of the weighted variance. The lazy calculation is associated with the `tag::lazy_weighted_variance` | |
4062 | feature, and the iterative calculation with the `tag::weighted_variance` feature. Both can be extracted | |
4063 | using the `tag::weighted_variance()` extractor. For more implementation details, see | |
4064 | [classref boost::accumulators::impl::lazy_weighted_variance_impl [^lazy_weighted_variance_impl]] and | |
4065 | [classref boost::accumulators::impl::weighted_variance_impl [^weighted_variance_impl]] | |
4066 | ||
4067 | [variablelist | |
4068 | [[Result Type] [`` | |
4069 | numeric::functional::fdiv< | |
4070 | numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type | |
4071 | , std::size_t | |
4072 | >::result_type | |
4073 | ``]] | |
4074 | [[Depends On] [`tag::lazy_weighted_variance` depends on `tag::weighted_moment<2>` and `tag::weighted_mean` \n | |
4075 | `tag::weighted_variance` depends on `tag::count` and `tag::immediate_weighted_mean`]] | |
4076 | [[Variants] [`tag::lazy_weighted_variance` (a.k.a. `tag::weighted_variance(lazy))` \n | |
4077 | `tag::weighted_variance` (a.k.a. `tag::weighted_variance(immediate)`)]] | |
4078 | [[Initialization Parameters] [['none]]] | |
4079 | [[Accumulator Parameters] [`weight`]] | |
4080 | [[Extractor Parameters] [['none]]] | |
4081 | [[Accumulator Complexity] [O(1)]] | |
4082 | [[Extractor Complexity] [O(1)]] | |
4083 | ] | |
4084 | ||
4085 | [*Header] | |
4086 | [def _WEIGHTED_VARIANCE_HPP_ [headerref boost/accumulators/statistics/weighted_variance.hpp]] | |
4087 | ||
4088 | #include <_WEIGHTED_VARIANCE_HPP_> | |
4089 | ||
4090 | [*Example] | |
4091 | ||
4092 | // lazy weighted_variance | |
4093 | accumulator_set<int, stats<tag::weighted_variance(lazy)>, int> acc1; | |
4094 | ||
4095 | acc1(1, weight = 2); // 2 | |
4096 | acc1(2, weight = 3); // 6 | |
4097 | acc1(3, weight = 1); // 3 | |
4098 | acc1(4, weight = 4); // 16 | |
4099 | acc1(5, weight = 1); // 5 | |
4100 | ||
4101 | // weighted_mean = (2+6+3+16+5) / (2+3+1+4+1) = 32 / 11 = 2.9090909090909090909090909090909 | |
4102 | ||
4103 | BOOST_CHECK_EQUAL(5u, count(acc1)); | |
4104 | BOOST_CHECK_CLOSE(2.9090909, weighted_mean(acc1), 1e-5); | |
4105 | BOOST_CHECK_CLOSE(10.1818182, accumulators::weighted_moment<2>(acc1), 1e-5); | |
4106 | BOOST_CHECK_CLOSE(1.7190083, weighted_variance(acc1), 1e-5); | |
4107 | ||
4108 | // immediate weighted_variance | |
4109 | accumulator_set<int, stats<tag::weighted_variance>, int> acc2; | |
4110 | ||
4111 | acc2(1, weight = 2); | |
4112 | acc2(2, weight = 3); | |
4113 | acc2(3, weight = 1); | |
4114 | acc2(4, weight = 4); | |
4115 | acc2(5, weight = 1); | |
4116 | ||
4117 | BOOST_CHECK_EQUAL(5u, count(acc2)); | |
4118 | BOOST_CHECK_CLOSE(2.9090909, weighted_mean(acc2), 1e-5); | |
4119 | BOOST_CHECK_CLOSE(1.7190083, weighted_variance(acc2), 1e-5); | |
4120 | ||
4121 | // check lazy and immediate variance with random numbers | |
4122 | ||
4123 | // two random number generators | |
4124 | boost::lagged_fibonacci607 rng; | |
4125 | boost::normal_distribution<> mean_sigma(0,1); | |
4126 | boost::variate_generator<boost::lagged_fibonacci607&, boost::normal_distribution<> > normal(rng, mean_sigma); | |
4127 | ||
4128 | accumulator_set<double, stats<tag::weighted_variance>, double > acc_lazy; | |
4129 | accumulator_set<double, stats<tag::weighted_variance(immediate)>, double > acc_immediate; | |
4130 | ||
4131 | for (std::size_t i=0; i<10000; ++i) | |
4132 | { | |
4133 | double value = normal(); | |
4134 | acc_lazy(value, weight = rng()); | |
4135 | acc_immediate(value, weight = rng()); | |
4136 | } | |
4137 | ||
4138 | BOOST_CHECK_CLOSE(1., weighted_variance(acc_lazy), 1.); | |
4139 | BOOST_CHECK_CLOSE(1., weighted_variance(acc_immediate), 1.); | |
4140 | ||
4141 | [*See also] | |
4142 | ||
4143 | * [classref boost::accumulators::impl::lazy_weighted_variance_impl [^lazy_weighted_variance_impl]] | |
4144 | * [classref boost::accumulators::impl::weighted_variance_impl [^weighted_variance_impl]] | |
4145 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]] | |
4146 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_mean [^weighted_mean]] | |
4147 | * [link accumulators.user_s_guide.the_statistical_accumulators_library.weighted_moment [^weighted_moment]] | |
4148 | ||
4149 | [endsect] | |
4150 | ||
4151 | [endsect] | |
4152 | ||
4153 | [endsect] | |
4154 | ||
4155 | [section Acknowledgements] | |
4156 | ||
4157 | Boost.Accumulators represents the efforts of many individuals. I would like to thank | |
4158 | Daniel Egloff of _ZKB_ for helping to conceive the library and realize its | |
4159 | implementation. I would also like to thank David Abrahams and Matthias Troyer for | |
4160 | their key contributions to the design of the library. Many thanks are due to Michael | |
4161 | Gauckler and Olivier Gygi, who, along with Daniel Egloff, implemented many of the | |
4162 | statistical accumulators. | |
4163 | ||
4164 | I would also like to thank Simon West for all his assistance maintaining | |
4165 | Boost.Accumulators. | |
4166 | ||
4167 | Finally, I would like to thank _ZKB_ for sponsoring the work on Boost.Accumulators | |
4168 | and graciously donating it to the community. | |
4169 | ||
4170 | [endsect] | |
4171 | ||
4172 | [section Reference] | |
4173 | ||
4174 | [xinclude accdoc.xml] | |
4175 | ||
4176 | [xinclude statsdoc.xml] | |
4177 | ||
4178 | [xinclude opdoc.xml] | |
4179 | ||
4180 | [endsect] |