• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
59Boost.Accumulators is both a library for incremental statistical computation as
60well as an extensible framework for incremental calculation in general. The library
61deals primarily with the concept of an ['accumulator], which is a primitive
62computational entity that accepts data one sample at a time and maintains some
63internal state. These accumulators may offload some of their computations on other
64accumulators, on which they depend. Accumulators are grouped within an ['accumulator
65set]. Boost.Accumulators resolves the inter-dependencies between accumulators in a
66set and ensures that accumulators are processed in the proper order.
67
68[endsect]
69
70[section User's Guide]
71
72This section describes how to use the Boost.Accumulators framework to create new
73accumulators and how to use the existing statistical accumulators to perform incremental
74statistical computation. For detailed information regarding specific components in
75Boost.Accumulators, check the [link accumulators_framework_reference Reference] section.
76
77[h2 Hello, World!]
78
79Below is a complete example of how to use the Accumulators Framework and the
80Statistical Accumulators to perform an incremental statistical calculation. It
81calculates 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: " << moment<2>(acc) << std::endl;
105
106        return 0;
107    }
108
109This program displays the following:
110
111[pre
112Mean:   2.85
113Moment: 9.635
114]
115
116[section The Accumulators Framework]
117
118The Accumulators Framework is framework for performing incremental calculations. Usage
119of 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
129The Accumulators Framework defines the utilities needed for defining primitive
130computational elements, called ['accumulators]. It also provides the _accumulator_set_
131type, described above.
132
133[h2 Terminology]
134
135The 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
166Here is a list of the important types and functions in the Accumulator Framework and
167a 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
199Our 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
204The 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
212For example, the following line declares an _accumulator_set_ that will accept
213a 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
217Notice 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
223Once we have defined an _accumulator_set_, we can then push data into it,
224and 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
231Since _accumulator_set_ defines its accumulate function to be the function call operator,
232we might be tempted to use an _accumulator_set_ as a UnaryFunction to a standard
233algorithm such as `std::for_each`. That's fine as long as we keep in mind that the standard
234algorithms 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
246Notice how we must assign the return value of `std::for_each` back to the _accumulator_set_.
247This works, but some accumulators are not cheap to copy. For
248example, the _tail_ and _tail_variate_ accumulators must store a `std::vector<>`, so copying
249these accumulators involves a dynamic allocation. We might be better off in this
250case 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
263Notice 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>]
267and [^<boost/ref.hpp>]]
268
269[endsect]
270
271[section Extracting Results]
272
273Once we have declared an _accumulator_set_ and pushed data into it, we need to be able
274to extract results from it. For each feature we can add to an _accumulator_set_, there
275is a corresponding extractor for fetching its result. Usually, the extractor has the
276same name as the feature, but in a different namespace. For example, if we accumulate
277the `tag::min` and `tag::max` features, we can extract the results with the `min` and `max`
278extractors, 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
289The extractors are all declared in the `boost::accumulators::extract` namespace, but they
290are 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
297Another 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
299object handy for a certain feature. The line above which displays results could
300equally 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
306Finally, we can define our own extractor using the _extractor_ class template. For
307instance, another way to avoid the `min` / `max` macro business would be to define
308extractors 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
320Some accumulators need initialization parameters. In addition, perhaps some auxiliary
321information needs to be passed into the _accumulator_set_ along with each sample.
322Boost.Accumulators handles these cases with named parameters from the _parameter_
323library.
324
325For example, consider the _tail_ and _tail_variate_ features. _tail_ keeps
326an ordered list of the largest [^['N]] samples, where [^['N]] can be specified at
327construction time. Also, the _tail_variate_ feature, which depends on _tail_, keeps
328track of some data that is covariate with the [^['N]] samples tracked by _tail_. The
329code 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
357There are several things to note about the code above. First, notice that we didn't have
358to request that the _tail_ feature be calculated. That is implicit because the _tail_variate_
359feature depends on the _tail_ feature. Next, notice how the `acc` object
360is initialized: `acc( tag::tail<left>::cache_size = 2 )`. Here, `cache_size` is a named parameter.
361It is used to tell the _tail_ and _tail_variate_ accumulators how many samples and
362covariates to store. Conceptually, every construction parameter is made available to
363every accumulator in an accumulator set.
364
365We also use a named parameter to pass covariate data into the accumulator set along with
366the samples. As with the constructor parameters, all parameters to the accumulate function
367are made available to all the accumulators in the set. In this case, only the accumulator
368for the `my_tail_variate` feature would be interested in the value of the `covariate1` named
369parameter.
370
371We can make one final observation about the example above. Since _tail_ and _tail_variate_
372are multi-valued features, the result we extract for them is represented as an iterator
373range. That is why we can say `tail( acc ).begin()` and `tail( acc ).end()`.
374
375Even the extractors can accept named parameters. In a bit, we'll see a situation where that
376is useful.
377
378[endsect]
379
380[section Weighted Samples]
381
382Some accumulators, statistical accumulators in particular, deal with data that are
383['weighted]. Each sample pushed into the accumulator has an associated weight, by which
384the sample is conceptually multiplied. The Statistical Accumulators Library provides an
385assortment of these weighted statistical accumulators. And many unweighted statistical
386accumulators have weighted variants. For instance, the weighted variant of the `sum`
387accumulator is called `weighted_sum`, and is calculated by accumulating all the
388samples multiplied by their weights.
389
390To declare an _accumulator_set_ that accepts weighted samples, you must specify the
391type 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
397When you specify a weight, all the accumulators in the set are replaced with
398their weighted equivalents. For example, the above _accumulator_set_ declaration
399is 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
404When passing samples to the accumulator set, you must also specify the
405weight of each sample. You can do that with the `weight` named parameter,
406as 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
414You 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
420Accumulators 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
427This section describes the function objects in the `boost::numeric` namespace, which
428is a sub-library that provides function objects and meta-functions corresponding
429to the infix operators in C++.
430
431In the `boost::numeric::operators` namespace are additional operator overloads for
432some useful operations not provided by the standard library, such as multiplication
433of a `std::complex<>` with a scalar.
434
435In the `boost::numeric::functional` namespace are function object equivalents of
436the infix operators. These function object types are heterogeneous, and so are more
437general than the standard ones found in the [^<functional>] header. They use the
438Boost.Typeof library to deduce the return types of the infix expressions they
439evaluate. In addition, they look within the `boost::numeric::operators` namespace
440to consider any additional overloads that might be defined there.
441
442In the `boost::numeric` namespace are global polymorphic function objects
443corresponding to the function object types defined in the `boost::numeric::functional`
444namespace. 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
448The Numeric Operators Sub-Library also gives several ways to sub-class and
449a way to sub-class and specialize operations. One way uses tag dispatching on
450the types of the operands. The other way is based on the compile-time
451properties of the operands.
452
453[endsect]
454
455[section Extending the Accumulators Framework]
456
457This section describes how to extend the Accumulators Framework by defining new accumulators,
458features and extractors. Also covered are how to control the dependency resolution of
459features within an accumulator set.
460
461[section Defining a New Accumulator]
462
463All new accumulators must satisfy the [link
464accumulators.user_s_guide.the_accumulators_framework.concepts.accumulator_concept Accumulator
465Concept]. Below is a sample class that satisfies the accumulator concept, which simply sums
466the 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
503Much of the above should be pretty self-explanatory, except for the use of argument packs
504which may be confusing if you have never used the _parameter_ library before. An argument
505pack is a cluster of values, each of which can be accessed with a key. So `args[sample]`
506extracts 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
508exists, or a default-constructed `Sample` if it doesn't.
509
510The example above demonstrates the most common attributes of an accumulator. There are
511other 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
522Some accumulators depend on other accumulators within the same accumulator set. In those
523cases, it is necessary to be able to access those other accumulators. To make this possible,
524the _accumulator_set_ passes a reference to itself when invoking the member functions of
525its contained accumulators. It can be accessed by using the special `accumulator` key with
526the 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
543to specify these dependencies.) The result of the mean accumulator is merely the result of
544the sum accumulator divided by the result of the count accumulator. Consider how we write
545that: `sum(args[accumulator]) / count(args[accumulator])`. The expression `args[accumulator]`
546evaluates to a reference to the _accumulator_set_ that contains this `mean_accumulator`. It
547also contains the `sum` and `count` accumulators, and we can access their results with the
548extractors 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
553All the member functions that accept an argument pack have access to the enclosing
554_accumulator_set_ via the `accumulator` key, including the constructor. The
555accumulators within the set are constructed in an order determined by their interdependencies.
556As 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
560Although not necessary, it can be a good idea to put your accumulator implementations in
561the `boost::accumulators::impl` namespace. This namespace pulls in any operators defined
562in the `boost::numeric::operators` namespace with a using directive. The Numeric Operators
563Sub-Library defines some additional overloads that will make your accumulators work with
564all sorts of data types.
565
566Consider `mean_accumulator` defined above. It divides the sum of the samples by the count.
567The 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
569is `std::complex<>`, the code would not work, but in fact it does. That's because
570Numeric Operators Sub-Library defines an overloaded `operator/` for `std::complex<>`
571and `std::size_t`. This operator is defined in the `boost::numeric::operators` namespace and
572will be found within the `boost::accumulators::impl` namespace. That's why it's a good idea
573to put your accumulators there.
574
575[h3 Droppable Accumulators]
576
577The term "droppable" refers to an accumulator that can be removed from the _accumulator_set_.
578You 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
596Any accumulators that get added to an accumulator set in order to satisfy
597dependencies on droppable accumulators are themselves droppable. Consider
598the 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`.
605However, we have explicitly requested that `sum` be not droppable, so it isn't. Had
606we left `tag::sum` out of the above declaration, the `sum` accumulator would have
607been implicitly droppable.
608
609A droppable accumulator is reference counted, and is only really dropped after all the
610accumulators that depend on it have been dropped. This can lead to some surprising
611behavior 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
634Note that at the point at which `mean` is dropped, `sum` is 3, `count` is 2, and
635therefore `mean` is 1.5. But since `sum` continues to accumulate even after `mean`
636has been dropped, the value of `mean` continues to change. If you want to remember
637the value of `mean` at the point it is dropped, you should save its value into
638a local variable.
639
640The following rules more precisely specify how droppable and non-droppable
641accumulators 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
673And 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
683Once we have implemented an accumulator, we must define a feature for it so
684that users can specify the feature when declaring an _accumulator_set_. We
685typically put the features into a nested namespace, so that later we can
686define an extractor of the same name. All features must satisfy the
687[link accumulators.user_s_guide.the_accumulators_framework.concepts.feature_concept
688Feature Concept]. Using _depends_on_ makes satisfying the concept simple.
689Below 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
703The only two things we must do to define the `mean` feature is to specify the
704dependencies with _depends_on_ and define the nested `impl` typedef. Even features
705that have no dependencies should inherit from _depends_on_. The nested `impl` type
706must be an _mpl_lambda_expression_. The result of
707`mpl::apply< impl, _sample_type_, _weight_type_ >::type` must be
708be the type of the accumulator that implements this feature. The use of _mpl_
709placeholders like `mpl::_1` make it especially easy to make a template such
710as `mean_accumulator<>` an _mpl_lambda_expression_. Here, `mpl::_1` will be
711replaced with the sample type. Had we used `mpl::_2`, it would have been replaced
712with the weight type.
713
714What about accumulator types that are not templates? If you have a `foo_accumulator`
715which 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
722If you are ever unsure, or if you are not comfortable with MPL lambda expressions,
723you 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
735Here, `impl` is a binary [@../../libs/mpl/doc/refmanual/metafunction-class.html
736MPL 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
738to build the accumulator type given the sample and weight types.
739
740All features must also provide a nested `is_weight_accumulator` typedef. It must
741be 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
744an accumulation of information about the weights instead of the samples, we
745can mark this feature as such with `typedef mpl::true_ is_weight_accumulator;`.
746The weight accumulators are made external if the weight type is specified using
747the _external_ template.
748
749[endsect]
750
751[section Defining a New Extractor]
752
753Now that we have an accumulator and a feature, the only thing lacking is a way
754to 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
756feature. 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
769Once defined, the `mean` extractor can be used to extract the result of the
770`tag::mean` feature from an _accumulator_set_.
771
772Parameterized features complicate this simple picture. Consider the `moment`
773feature, for calculating the [^['N]]-th moment, where [^['N]] is specified as
774a 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
784In the expression `accumulators::moment<2>(acc)`, what is `moment`? It cannot be an object --
785the syntax of C++ will not allow it. Clearly, if we want to provide this syntax,
786we 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
805The return type deserves some explanation. Every _accumulator_set_ type
806is actually a unary [@../../libs/mpl/doc/refmanual/metafunction-class.html
807MPL Metafunction Class]. When you `mpl::apply<>` an _accumulator_set_ and
808a feature, the result is the type of the accumulator within the set that
809implements that feature. And every accumulator provides a nested `result_type`
810typedef that tells what its return type is. The extractor simply delegates
811its work to the _extract_result_ function.
812
813[endsect]
814
815[section Controlling Dependencies]
816
817The feature-based dependency resolution of the Accumulators Framework is
818designed to allow multiple different implementation strategies for each
819feature. For instance, two different accumulators may calculate the same
820quantity with different rounding modes, or using different algorithms with
821different size/speed tradeoffs. Other accumulators that depend on that
822quantity shouldn't care how it's calculated. The Accumulators Framework
823handles this by allowing several different accumulators satisfy the same
824feature.
825
826[*Aliasing feature dependencies with [^feature_of<>]]
827
828Imagine that you would like to implement the hypothetical ['fubar] statistic,
829and that you know two ways to calculate fubar on a bunch of samples: an
830accurate but slow calculation and an approximate but fast calculation. You
831might opt to make the accurate calculation the default, so you implement
832two accumulators and call them `impl::fubar_impl` and `impl::fast_fubar_impl`.
833You 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].
835Now, you would like to inform the Accumulators Framework that these two features
836are the same from the point of view of dependency resolution. You can do that
837with _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
850The above code instructs the Accumulators Framework that, if another accumulator
851in the set depends on the `tag::fubar` feature, the `tag::fast_fubar` feature
852is an acceptable substitute.
853
854[*Registering feature variants with [^as_feature<>]]
855
856You may have noticed that some feature variants in the Accumulators Framework can be
857specified with a nicer syntax. For instance, instead of `tag::mean` and `tag::immediate_mean`
858you can specify them with `tag::mean(lazy)` and `tag::mean(immediate)` respectively.
859These are merely aliases, but the syntax makes the relationship between the two clearer.
860You can create these feature aliases with the _as_feature_ trait. Given the fubar example
861above, 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
882Once you have done this, users of your fubar accumulator can request the `tag::fubar(fast)`
883and `tag::fubar(accurate)` features when defining their `accumulator_set`s and get the correct
884accumulator.
885
886[endsect]
887
888[section:operators_ex Specializing Numeric Operators]
889
890This section describes how to adapt third-party numeric types to work with the Accumulator
891Framework.
892
893Rather than relying on the built-in operators, the Accumulators Framework relies on functions
894and operator overloads defined in the
895[link accumulators.user_s_guide.the_accumulators_framework.numeric_operators_sub_library
896Numeric Operators Sub-Library] for many of its numeric operations. This is so that it
897is possible to assign non-standard meanings to arithmetic operations. For instance, when
898calculating an average by dividing two integers, the standard integer division behavior
899would be mathematically incorrect for most statistical quantities. So rather than use `x / y`,
900the Accumulators Framework uses `numeric::fdiv(x, y)`, which does floating-point division
901even if both `x` and `y` are integers.
902
903Another example where the Numeric Operators Sub-Library is useful is when a type does not
904define 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
907defines the necessary operator overloads in the `boost::numeric::operators` namespace,
908which is brought into scope by the Accumulators Framework with a using directive.
909
910[*Numeric Function Objects and Tag Dispatching]
911
912How are the numeric function object defined by the Numeric Operators Sub-Library made
913to work with types such as `std::vector<>`? The free functions in the `boost::numeric` namespace
914are implemented in terms of the function objects in the `boost::numeric::functional` namespace,
915so to make `boost::numeric::fdiv()` do something sensible with a `std::vector<>`, for instance,
916we'll need to partially specialize the `boost::numeric::functional::fdiv<>` function object.
917
918The functional objects make use of a technique known as
919[@http://www.boost.org/community/generic_programming.html#tag_dispatching ['tag dispatching]] to
920select 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
943If you have some user-defined type `MyDouble` for which you would like to customize the behavior
944of `numeric::fdiv()`, you would specialize `numeric::functional::fdiv<>` by
945first 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
974Once you have done this, `numeric::fdiv()` will use your specialization
975of `numeric::functional::fdiv<>` when the first argument is a `MyDouble`
976object. All of the function objects in the Numeric Operators Sub-Library can
977be customized in a similar fashion.
978
979[endsect]
980
981[endsect]
982
983[section Concepts]
984
985[h2 Accumulator Concept]
986
987In 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
1005In 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
1030The Statistical Accumulators Library defines accumulators for incremental statistical
1031computations. It is built on top of [link accumulators.user_s_guide.the_accumulators_framework
1032The Accumulator Framework].
1033
1034[section:count count]
1035
1036The `count` feature is a simple counter that tracks the
1037number 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
1073The `covariance` feature is an iterative Monte Carlo estimator for the covariance.
1074It 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
1118The `tag::density` feature returns a histogram of the sample distribution. For more
1119implementation 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
1148Results from the `density` accumulator can only be extracted after the number of
1149samples 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
1164The `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
1205Multiple quantile estimation with the extended [^P^2] algorithm. For further
1206details, 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
1256Quantile estimation using the extended [^P^2] algorithm for weighted and unweighted samples.
1257By default, the calculation is linear and unweighted, but quadratic and weighted variants
1258are also provided. For further implementation details, see
1259[classref boost::accumulators::impl::extended_p_square_quantile_impl [^extended_p_square_quantile_impl]].
1260
1261All the variants share the `tag::quantile` feature and can be extracted using the `quantile()`
1262extractor.
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
1352The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the
1353square of the 2nd central moment (the variance) of the samples, minus 3. The term [^-3] is added
1354in order to ensure that the normal distribution has zero kurtosis. For more implementation
1355details, 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
1401Calculates 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
1442Calculates the mean of samples, weights or variates. The calculation is either
1443lazy (in the result extractor), or immediate (in the accumulator). The lazy implementation
1444is 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
1545Median estimation based on the [^P^2] quantile estimator, the density estimator, or
1546the [^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]],
1549and [classref boost::accumulators::impl::with_p_square_cumulative_distribution_median_impl [^with_p_square_cumulative_distribution_median_impl]].
1550
1551The three median accumulators all satisfy the `tag::median` feature, and can all be
1552extracted 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
1616Calculates 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
1657Calculates the N-th moment of the samples, which is defined as the sum of the N-th power of the
1658samples 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
1708Histogram calculation of the cumulative distribution with the [^P^2] algorithm.
1709For 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
1775Single 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
1851Peaks Over Threshold method for quantile and tail mean estimation. For implementation
1852details, see [classref boost::accumulators::impl::peaks_over_threshold_impl [^peaks_over_threshold_impl]]
1853and [classref boost::accumulators::impl::peaks_over_threshold_prob_impl [^peaks_over_threshold_prob_impl]].
1854
1855Both `tag::peaks_over_threshold` and `tag::peaks_over_threshold_prob<>` satisfy the `tag::abstract_peaks_over_threshold`
1856feature, and can be extracted with the `peaks_over_threshold()` extractor. The result is a 3-tuple representing
1857the 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
1886See 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
1901Quantile estimation based on Peaks over Threshold method (for both left and right tails). For
1902implementation details, see [classref boost::accumulators::impl::pot_quantile_impl [^pot_quantile_impl]].
1903
1904Both `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
1992Estimation of the (coherent) tail mean based on the peaks over threshold method (for both left and right tails).
1993For implementation details, see [classref boost::accumulators::impl::pot_tail_mean_impl [^pot_tail_mean_impl]].
1994
1995Both `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
2035The 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
2082The 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
2129The rolling mean is the mean over the last /N/ samples. It is computed by dividing
2130the rolling sum by the rolling count.
2131
2132Lazy or iterative calculation of the mean over the last /N/ samples. The lazy calculation is associated with the `tag::lazy_rolling_mean`
2133feature, and the iterative calculation (which is the default) with the `tag::immediate_rolling_mean` feature. Both can be extracted
2134using 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
2186rolling_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
2228Lazy or iterative calculation of the variance over the last /N/ samples. The lazy calculation is associated with the `tag::lazy_rolling_variance`
2229feature, and the iterative calculation with the `tag::immediate_rolling_variance` feature. Both can be extracted using the `tag::rolling_variance()` extractor.
2230For 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
2288The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the [^3/2]-th power
2289of 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
2335For summing the samples, weights or variates. The default implementation uses the standard sum operation,
2336but 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
2410Tracks the largest or smallest [^N] values. `tag::tail<right>` tracks the largest [^N],
2411and `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
2415Both `tag::tail<left>` and `tag::tail<right>` satisfy the `tag::abstract_tail` feature and
2416can 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
2445See 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
2456Estimation of the coherent tail mean based on order statistics (for both left and right tails).
2457The left coherent tail mean feature is `tag::coherent_tail_mean<left>`, and the right coherent
2458tail mean feature is `tag::coherent_tail_mean<right>`. They both share the `tag::tail_mean` feature
2459and 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
2482See 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
2498Estimation of the (non-coherent) tail mean based on order statistics (for both left and right tails).
2499The left non-coherent tail mean feature is `tag::non_coherent_tail_mean<left>`, and the right non-choherent
2500tail mean feature is `tag::non_coherent_tail_mean<right>`. They both share the `tag::abstract_non_coherent_tail_mean`
2501feature 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
2580Tail quantile estimation based on order statistics (for both left and right tails).
2581The left tail quantile feature is `tag::tail_quantile<left>`, and the right
2582tail quantile feature is `tag::tail_quantile<right>`. They both share the `tag::quantile`
2583feature 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
2661Tracks 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>`
2664for the smallest. The parameter [^N] is specified with the `tag::tail<_left_or_right_>::cache_size`
2665initialization parameter. For implementation details, see
2666[classref boost::accumulators::impl::tail_variate_impl [^tail_variate_impl]].
2667
2668Both `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
2670and 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
2736Estimation of the absolute and relative tail variate means (for both left and right tails).
2737The absolute tail variate means has the feature
2738`tag::absolute_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`
2739and the relative tail variate mean has the feature
2740`tag::relative_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`. All
2741absolute tail variate mean features share the `tag::abstract_absolute_tail_variate_means`
2742feature and can be extracted with the `tail_variate_means()` extractor. All the
2743relative tail variate mean features share the `tag::abstract_relative_tail_variate_means`
2744feature and can be extracted with the `relative_tail_variate_means()` extractor.
2745
2746For 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
2887Lazy or iterative calculation of the variance. The lazy calculation is associated with the `tag::lazy_variance`
2888feature, and the iterative calculation with the `tag::variance` feature. Both can be extracted
2889using 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
2954An 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()`
2956extractor. 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
3013The `tag::weighted_density` feature returns a histogram of the weighted sample distribution. For more
3014implementation 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
3055Multiple quantile estimation with the extended [^P^2] algorithm for weighted samples. For further
3056details, 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
3146The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the
3147square of the 2nd central moment (the variance) of the samples, minus 3. The term [^-3] is added
3148in order to ensure that the normal distribution has zero kurtosis. For more implementation
3149details, 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
3198Calculates the weighted mean of samples or variates. The calculation is either
3199lazy (in the result extractor), or immediate (in the accumulator). The lazy implementation
3200is 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
3288Median estimation for weighted samples based on the [^P^2] quantile estimator, the density estimator, or
3289the [^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]],
3292and [classref boost::accumulators::impl::with_weighted_p_square_cumulative_distribution_median_impl [^with_weighted_p_square_cumulative_distribution_median_impl]].
3293
3294The three median accumulators all satisfy the `tag::weighted_median` feature, and can all be
3295extracted 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
3363Calculates the N-th moment of the weighted samples, which is defined as the sum of the weighted N-th
3364power 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
3413Histogram calculation of the cumulative distribution with the [^P^2] algorithm for weighted samples.
3414For 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
3504Single 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
3603Weighted peaks over threshold method for weighted quantile and weighted tail mean estimation.
3604For more implementation details,
3605see [classref boost::accumulators::impl::weighted_peaks_over_threshold_impl [^weighted_peaks_over_threshold_impl]]
3606and [classref boost::accumulators::impl::weighted_peaks_over_threshold_prob_impl [^weighted_peaks_over_threshold_prob_impl]].
3607
3608Both `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
3651The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the [^3/2]-th power
3652of the 2nd central moment (the variance) of the samples 3. The skewness estimator for weighted samples
3653is formally identical to the estimator for unweighted samples, except that the weighted counterparts of
3654all measures it depends on are to be taken.
3655
3656For 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
3705For summing the weighted samples or variates. All of the `tag::weighted_sum_of_variates<>` features
3706can be extracted with the `weighted_sum_of_variates()` extractor. Variants that implement the Kahan
3707summation 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
3768Estimation of the (non-coherent) weighted tail mean based on order statistics (for both left and right tails).
3769The left non-coherent weighted tail mean feature is `tag::non_coherent_weighted_tail_mean<left>`, and the right
3770non-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
3772be extracted with either the `non_coherent_tail_mean()` or the `non_coherent_weighted_tail_mean()` extractors.
3773For 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
3845Tail quantile estimation based on order statistics of weighted samples (for both left
3846and right tails). The left weighted tail quantile feature is `tag::weighted_tail_quantile<left>`,
3847and the right weighted tail quantile feature is `tag::weighted_tail_quantile<right>`. They both
3848share the `tag::quantile` feature with the unweighted tail quantile accumulators and can be
3849extracted with either the `quantile()` or the `weighted_tail_quantile()` extractors. For more
3850implementation 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
3917Estimation of the absolute and relative weighted tail variate means (for both left and right tails)
3918The absolute weighted tail variate means has the feature
3919`tag::absolute_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`
3920and the relative weighted tail variate mean has the feature
3921`tag::relative_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`. All
3922absolute weighted tail variate mean features share the `tag::abstract_absolute_tail_variate_means`
3923feature 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
3925share the `tag::abstract_relative_tail_variate_means` feature with their unweighted variants
3926and can be extracted with either the `relative_tail_variate_means()` or
3927`relative_weighted_tail_variate_means()` extractors.
3928
3929For 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
4061Lazy or iterative calculation of the weighted variance. The lazy calculation is associated with the `tag::lazy_weighted_variance`
4062feature, and the iterative calculation with the `tag::weighted_variance` feature. Both can be extracted
4063using 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
4157Boost.Accumulators represents the efforts of many individuals. I would like to thank
4158Daniel Egloff of _ZKB_ for helping to conceive the library and realize its
4159implementation. I would also like to thank David Abrahams and Matthias Troyer for
4160their key contributions to the design of the library. Many thanks are due to Michael
4161Gauckler and Olivier Gygi, who, along with Daniel Egloff, implemented many of the
4162statistical accumulators.
4163
4164I would also like to thank Simon West for all his assistance maintaining
4165Boost.Accumulators.
4166
4167Finally, I would like to thank _ZKB_ for sponsoring the work on Boost.Accumulators
4168and 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]
4181