Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / accumulators / doc / accumulators.qbk
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'''&uuml;'''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]