2 [library Boost.Accumulators
4 [authors [Niebler, Eric]]
5 [copyright 2005 2006 Eric Niebler]
10 Incremental accumulation framework and statistical accumulator library.
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])
21 [def _note_ [$images/note.png]]
22 [def _alert_ [$images/caution.png]]
23 [def _detail_ [$images/note.png]]
24 [def _tip_ [$images/tip.png]]
28 [def _sample_type_ '''<replaceable>sample-type</replaceable>''']
29 [def _weight_type_ '''<replaceable>weight-type</replaceable>''']
30 [def _variate_type_ '''<replaceable>variate-type</replaceable>''']
31 [def _variate_tag_ '''<replaceable>variate-tag</replaceable>''']
32 [def _left_or_right_ '''<replaceable>left-or-right</replaceable>''']
33 [def _implementation_defined_ '''<replaceable>implementation-defined</replaceable>''']
34 [def _boost_ [@http://www.boost.org Boost]]
35 [def _mpl_ [@../../libs/mpl/index.html MPL]]
36 [def _mpl_lambda_expression_ [@../../libs/mpl/doc/refmanual/lambda-expression.html MPL Lambda Expression]]
37 [def _parameter_ [@../../libs/parameter/index.html Boost.Parameter]]
38 [def _accumulator_set_ [classref boost::accumulators::accumulator_set `accumulator_set<>`]]
39 [def _accumulator_base_ [classref boost::accumulators::accumulator_base `accumulator_base`]]
40 [def _depends_on_ [classref boost::accumulators::depends_on `depends_on<>`]]
41 [def _feature_of_ [classref boost::accumulators::feature_of `feature_of<>`]]
42 [def _as_feature_ [classref boost::accumulators::as_feature `as_feature<>`]]
43 [def _features_ [classref boost::accumulators::features `features<>`]]
44 [def _external_ [classref boost::accumulators::external `external<>`]]
45 [def _droppable_ [classref boost::accumulators::droppable `droppable<>`]]
46 [def _droppable_accumulator_ [classref boost::accumulators::droppable_accumulator `droppable_accumulator<>`]]
47 [def _extractor_ [classref boost::accumulators::tag::extractor `extractor<>`]]
48 [def _tail_ [classref boost::accumulators::tag::tail `tail`]]
49 [def _tail_variate_ [classref boost::accumulators::tag::tail_variate `tail_variate<>`]]
50 [def _extract_result_ [funcref boost::accumulators::extract_result `extract_result()`]]
51 [def _ZKB_ [@http://www.zkb.com Z'''ü'''rcher Kantonalbank]]
55 [:["It is better to be approximately right than exactly wrong.]\n['-- Old adage]]
59 Boost.Accumulators is both a library for incremental statistical computation as
60 well as an extensible framework for incremental calculation in general. The library
61 deals primarily with the concept of an ['accumulator], which is a primitive
62 computational entity that accepts data one sample at a time and maintains some
63 internal state. These accumulators may offload some of their computations on other
64 accumulators, on which they depend. Accumulators are grouped within an ['accumulator
65 set]. Boost.Accumulators resolves the inter-dependencies between accumulators in a
66 set and ensures that accumulators are processed in the proper order.
70 [section User's Guide]
72 This section describes how to use the Boost.Accumulators framework to create new
73 accumulators and how to use the existing statistical accumulators to perform incremental
74 statistical computation. For detailed information regarding specific components in
75 Boost.Accumulators, check the [link accumulators_framework_reference Reference] section.
79 Below is a complete example of how to use the Accumulators Framework and the
80 Statistical Accumulators to perform an incremental statistical calculation. It
81 calculates the mean and 2nd moment of a sequence of doubles.
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;
92 // Define an accumulator set for calculating the mean and the
94 accumulator_set<double, stats<tag::mean, tag::moment<2> > > acc;
96 // push in some data ...
102 // Display the results ...
103 std::cout << "Mean: " << mean(acc) << std::endl;
104 std::cout << "Moment: " << accumulators::moment<2>(acc) << std::endl;
109 This program displays the following:
116 [section The Accumulators Framework]
118 The Accumulators Framework is framework for performing incremental calculations. Usage
119 of the framework follows the following pattern:
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.
129 The Accumulators Framework defines the utilities needed for defining primitive
130 computational elements, called ['accumulators]. It also provides the _accumulator_set_
131 type, described above.
135 The following terms are used in the rest of the documentation.
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_.]]
166 Here is a list of the important types and functions in the Accumulator Framework and
167 a brief description of each.
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
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
197 [section Using [^accumulator_set<>]]
199 Our tour of the _accumulator_set_ class template begins with the forward declaration:
201 template< typename Sample, typename Features, typename Weight = void >
202 struct accumulator_set;
204 The template parameters have the following meaning:
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.]]
212 For example, the following line declares an _accumulator_set_ that will accept
213 a sequence of doubles one at a time and calculate the min and mean:
215 accumulator_set< double, features< tag::min, tag::mean > > acc;
217 Notice that we use the _features_ template to specify a list of features to be calculated.
218 _features_ is an MPL sequence of features.
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.]
223 Once we have defined an _accumulator_set_, we can then push data into it,
224 and it will calculate the quantities you requested, as shown below.
226 // push some data into the accumulator_set ...
231 Since _accumulator_set_ defines its accumulate function to be the function call operator,
232 we might be tempted to use an _accumulator_set_ as a UnaryFunction to a standard
233 algorithm such as `std::for_each`. That's fine as long as we keep in mind that the standard
234 algorithms take UnaryFunction objects by value, which involves making a copy of the
235 _accumulator_set_ object. Consider the following:
237 // The data for which we wish to calculate statistical properties:
238 std::vector< double > data( /* stuff */ );
240 // The accumulator set which will calculate the properties for us:
241 accumulator_set< double, features< tag::min, tag::mean > > acc;
243 // Use std::for_each to accumulate the statistical properties:
244 acc = std::for_each( data.begin(), data.end(), acc );
246 Notice how we must assign the return value of `std::for_each` back to the _accumulator_set_.
247 This works, but some accumulators are not cheap to copy. For
248 example, the _tail_ and _tail_variate_ accumulators must store a `std::vector<>`, so copying
249 these accumulators involves a dynamic allocation. We might be better off in this
250 case passing the accumulator by reference, with the help of `boost::bind()` and
251 `boost::ref()`. See below:
253 // The data for which we wish to calculate statistical properties:
254 std::vector< double > data( /* stuff */ );
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 );
260 // Use std::for_each to accumulate the statistical properties:
261 std::for_each( data.begin(), data.end(), bind<void>( ref(acc), _1 ) );
263 Notice now that we don't care about the return value of `std::for_each()` anymore because
264 `std::for_each()` is modifying `acc` directly.
266 [note To use `boost::bind()` and `boost::ref()`, you must `#include` [^<boost/bind.hpp>]
267 and [^<boost/ref.hpp>]]
271 [section Extracting Results]
273 Once we have declared an _accumulator_set_ and pushed data into it, we need to be able
274 to extract results from it. For each feature we can add to an _accumulator_set_, there
275 is a corresponding extractor for fetching its result. Usually, the extractor has the
276 same name as the feature, but in a different namespace. For example, if we accumulate
277 the `tag::min` and `tag::max` features, we can extract the results with the `min` and `max`
278 extractors, as follows:
280 // Calculate the minimum and maximum for a sequence of integers.
281 accumulator_set< int, features< tag::min, tag::max > > acc;
286 // This displays "(-1, 2)"
287 std::cout << '(' << min( acc ) << ", " << max( acc ) << ")\n";
289 The extractors are all declared in the `boost::accumulators::extract` namespace, but they
290 are brought into the `boost::accumulators` namespace with a `using` declaration.
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.]
297 Another way to extract a result from an _accumulator_set_ is with the
298 `extract_result()` function. This can be more convenient if there isn't an extractor
299 object handy for a certain feature. The line above which displays results could
300 equally be written as:
302 // This displays "(-1, 2)"
303 std::cout << '(' << extract_result< tag::min >( acc )
304 << ", " << extract_result< tag::max >( acc ) << ")\n";
306 Finally, we can define our own extractor using the _extractor_ class template. For
307 instance, another way to avoid the `min` / `max` macro business would be to define
308 extractors with names that don't conflict with the macros, like this:
310 extractor< tag::min > min_;
311 extractor< tag::min > max_;
313 // This displays "(-1, 2)"
314 std::cout << '(' << min_( acc ) << ", " << max_( acc ) << ")\n";
318 [section Passing Optional Parameters]
320 Some accumulators need initialization parameters. In addition, perhaps some auxiliary
321 information needs to be passed into the _accumulator_set_ along with each sample.
322 Boost.Accumulators handles these cases with named parameters from the _parameter_
325 For example, consider the _tail_ and _tail_variate_ features. _tail_ keeps
326 an ordered list of the largest [^['N]] samples, where [^['N]] can be specified at
327 construction time. Also, the _tail_variate_ feature, which depends on _tail_, keeps
328 track of some data that is covariate with the [^['N]] samples tracked by _tail_. The
329 code below shows how this all works, and is described in more detail below.
331 // Define a feature for tracking covariate data
332 typedef tag::tail_variate< int, tag::covariate1, left > my_tail_variate_tag;
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 );
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 );
346 // Define an extractor for the my_tail_variate_tag feature
347 extractor< my_tail_variate_tag > my_tail_variate;
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 );
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 );
357 There are several things to note about the code above. First, notice that we didn't have
358 to request that the _tail_ feature be calculated. That is implicit because the _tail_variate_
359 feature depends on the _tail_ feature. Next, notice how the `acc` object
360 is initialized: `acc( tag::tail<left>::cache_size = 2 )`. Here, `cache_size` is a named parameter.
361 It is used to tell the _tail_ and _tail_variate_ accumulators how many samples and
362 covariates to store. Conceptually, every construction parameter is made available to
363 every accumulator in an accumulator set.
365 We also use a named parameter to pass covariate data into the accumulator set along with
366 the samples. As with the constructor parameters, all parameters to the accumulate function
367 are made available to all the accumulators in the set. In this case, only the accumulator
368 for the `my_tail_variate` feature would be interested in the value of the `covariate1` named
371 We can make one final observation about the example above. Since _tail_ and _tail_variate_
372 are multi-valued features, the result we extract for them is represented as an iterator
373 range. That is why we can say `tail( acc ).begin()` and `tail( acc ).end()`.
375 Even the extractors can accept named parameters. In a bit, we'll see a situation where that
380 [section Weighted Samples]
382 Some accumulators, statistical accumulators in particular, deal with data that are
383 ['weighted]. Each sample pushed into the accumulator has an associated weight, by which
384 the sample is conceptually multiplied. The Statistical Accumulators Library provides an
385 assortment of these weighted statistical accumulators. And many unweighted statistical
386 accumulators have weighted variants. For instance, the weighted variant of the `sum`
387 accumulator is called `weighted_sum`, and is calculated by accumulating all the
388 samples multiplied by their weights.
390 To declare an _accumulator_set_ that accepts weighted samples, you must specify the
391 type of the weight parameter as the 3rd template parameter, as follows:
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;
397 When you specify a weight, all the accumulators in the set are replaced with
398 their weighted equivalents. For example, the above _accumulator_set_ declaration
399 is equivalent to the following:
401 // Since we specified a weight, tag::sum becomes tag::weighted_sum
402 accumulator_set< int, features< tag::weighted_sum >, int > acc;
404 When passing samples to the accumulator set, you must also specify the
405 weight of each sample. You can do that with the `weight` named parameter,
408 acc(1, weight = 2); // 1 * 2
409 acc(2, weight = 4); // 2 * 4
410 acc(3, weight = 6); // + 3 * 6
414 You can then extract the result with the `sum()` extractor, as follows:
417 std::cout << sum(acc) << std::endl;
419 [note When working with weighted statistical accumulators from the Statistical
420 Accumulators Library, be sure to include the appropriate header. For instance,
421 `weighted_sum` is defined in `<boost/accumulators/statistics/weighted_sum.hpp>`.]
425 [section Numeric Operators Sub-Library]
427 This section describes the function objects in the `boost::numeric` namespace, which
428 is a sub-library that provides function objects and meta-functions corresponding
429 to the infix operators in C++.
431 In the `boost::numeric::operators` namespace are additional operator overloads for
432 some useful operations not provided by the standard library, such as multiplication
433 of a `std::complex<>` with a scalar.
435 In the `boost::numeric::functional` namespace are function object equivalents of
436 the infix operators. These function object types are heterogeneous, and so are more
437 general than the standard ones found in the [^<functional>] header. They use the
438 Boost.Typeof library to deduce the return types of the infix expressions they
439 evaluate. In addition, they look within the `boost::numeric::operators` namespace
440 to consider any additional overloads that might be defined there.
442 In the `boost::numeric` namespace are global polymorphic function objects
443 corresponding to the function object types defined in the `boost::numeric::functional`
444 namespace. For example, `boost::numeric::plus(a, b)` is equivalent to
445 `boost::numeric::functional::plus<A, B>()(a, b)`, and both are equivalent to
446 `using namespace boost::numeric::operators; a + b;`.
448 The Numeric Operators Sub-Library also gives several ways to sub-class and
449 a way to sub-class and specialize operations. One way uses tag dispatching on
450 the types of the operands. The other way is based on the compile-time
451 properties of the operands.
455 [section Extending the Accumulators Framework]
457 This section describes how to extend the Accumulators Framework by defining new accumulators,
458 features and extractors. Also covered are how to control the dependency resolution of
459 features within an accumulator set.
461 [section Defining a New Accumulator]
463 All new accumulators must satisfy the [link
464 accumulators.user_s_guide.the_accumulators_framework.concepts.accumulator_concept Accumulator
465 Concept]. Below is a sample class that satisfies the accumulator concept, which simply sums
466 the values of all samples passed into it.
468 #include <boost/accumulators/framework/accumulator_base.hpp>
469 #include <boost/accumulators/framework/parameters/sample.hpp>
471 namespace boost { // Putting your accumulators in the
472 namespace accumulators { // impl namespace has some
473 namespace impl { // advantages. See below.
475 template<typename Sample>
476 struct sum_accumulator // All accumulators should inherit from
477 : accumulator_base // accumulator_base.
479 typedef Sample result_type; // The type returned by result() below.
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.)
487 template<typename Args> // The accumulate function is the function
488 void operator ()(Args const & args) // call operator, and it also accepts an
490 this->sum += args[sample];
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.
503 Much of the above should be pretty self-explanatory, except for the use of argument packs
504 which may be confusing if you have never used the _parameter_ library before. An argument
505 pack is a cluster of values, each of which can be accessed with a key. So `args[sample]`
506 extracts from the pack the value associated with the `sample` key. And the cryptic
507 `args[sample | Sample()]` evaluates to the value associated with the `sample` key if it
508 exists, or a default-constructed `Sample` if it doesn't.
510 The example above demonstrates the most common attributes of an accumulator. There are
511 other optional member functions that have special meaning. In particular:
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].]]
520 [h3 Accessing Other Accumulators in the Set]
522 Some accumulators depend on other accumulators within the same accumulator set. In those
523 cases, it is necessary to be able to access those other accumulators. To make this possible,
524 the _accumulator_set_ passes a reference to itself when invoking the member functions of
525 its contained accumulators. It can be accessed by using the special `accumulator` key with
526 the argument pack. Consider how we might implement `mean_accumulator`:
528 // Mean == (Sum / Count)
529 template<typename Sample>
530 struct mean_accumulator : accumulator_base
532 typedef Sample result_type;
533 mean_accumulator(dont_care) {}
535 template<typename Args>
536 result_type result(Args const &args) const
538 return sum(args[accumulator]) / count(args[accumulator]);
542 `mean` depends on the `sum` and `count` accumulators. (We'll see in the next section how
543 to specify these dependencies.) The result of the mean accumulator is merely the result of
544 the sum accumulator divided by the result of the count accumulator. Consider how we write
545 that: `sum(args[accumulator]) / count(args[accumulator])`. The expression `args[accumulator]`
546 evaluates to a reference to the _accumulator_set_ that contains this `mean_accumulator`. It
547 also contains the `sum` and `count` accumulators, and we can access their results with the
548 extractors defined for those features: `sum` and `count`.
550 [note Accumulators that inherit from _accumulator_base_ get an empty `operator ()`, so
551 accumulators like `mean_accumulator` above need not define one.]
553 All the member functions that accept an argument pack have access to the enclosing
554 _accumulator_set_ via the `accumulator` key, including the constructor. The
555 accumulators within the set are constructed in an order determined by their interdependencies.
556 As a result, it is safe for an accumulator to access one on which it depends during construction.
558 [h3 Infix Notation and the Numeric Operators Sub-Library]
560 Although not necessary, it can be a good idea to put your accumulator implementations in
561 the `boost::accumulators::impl` namespace. This namespace pulls in any operators defined
562 in the `boost::numeric::operators` namespace with a using directive. The Numeric Operators
563 Sub-Library defines some additional overloads that will make your accumulators work with
564 all sorts of data types.
566 Consider `mean_accumulator` defined above. It divides the sum of the samples by the count.
567 The type of the count is `std::size_t`. What if the sample type doesn't define division by
568 `std::size_t`? That's the case for `std::complex<>`. You might think that if the sample type
569 is `std::complex<>`, the code would not work, but in fact it does. That's because
570 Numeric Operators Sub-Library defines an overloaded `operator/` for `std::complex<>`
571 and `std::size_t`. This operator is defined in the `boost::numeric::operators` namespace and
572 will be found within the `boost::accumulators::impl` namespace. That's why it's a good idea
573 to put your accumulators there.
575 [h3 Droppable Accumulators]
577 The term "droppable" refers to an accumulator that can be removed from the _accumulator_set_.
578 You can request that an accumulator be made droppable by using the _droppable_ class template.
580 // calculate sum and count, make sum droppable:
581 accumulator_set< double, features< tag::count, droppable<tag::sum> > > acc;
587 // drop the sum (sum is 5 here)
588 acc.drop<tag::sum>();
593 // This will display "3" and "5"
594 std::cout << count(acc) << ' ' << sum(acc);
596 Any accumulators that get added to an accumulator set in order to satisfy
597 dependencies on droppable accumulators are themselves droppable. Consider
598 the following accumulator:
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;
604 `mean` depends on `sum` and `count`. Since `mean` is droppable, so too is `count`.
605 However, we have explicitly requested that `sum` be not droppable, so it isn't. Had
606 we left `tag::sum` out of the above declaration, the `sum` accumulator would have
607 been implicitly droppable.
609 A droppable accumulator is reference counted, and is only really dropped after all the
610 accumulators that depend on it have been dropped. This can lead to some surprising
611 behavior in some situations.
613 // calculate sum and mean, make mean droppable.
614 accumulator_set< double, features< tag::sum, droppable<tag::mean> > > acc;
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>();
626 // add more data. Sum continues to accumulate!
629 // This will display "6 2 3"
630 std::cout << sum(acc) << ' '
634 Note that at the point at which `mean` is dropped, `sum` is 3, `count` is 2, and
635 therefore `mean` is 1.5. But since `sum` continues to accumulate even after `mean`
636 has been dropped, the value of `mean` continues to change. If you want to remember
637 the value of `mean` at the point it is dropped, you should save its value into
640 The following rules more precisely specify how droppable and non-droppable
641 accumulators behave within an accumulator set.
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
670 * Users are not allowed to drop a feature that is not user-specified and
673 And as an optimization:
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.
681 [section Defining a New Feature]
683 Once we have implemented an accumulator, we must define a feature for it so
684 that users can specify the feature when declaring an _accumulator_set_. We
685 typically put the features into a nested namespace, so that later we can
686 define an extractor of the same name. All features must satisfy the
687 [link accumulators.user_s_guide.the_accumulators_framework.concepts.feature_concept
688 Feature Concept]. Using _depends_on_ makes satisfying the concept simple.
689 Below is an example of a feature definition.
691 namespace boost { namespace accumulators { namespace tag {
693 struct mean // Features should inherit from
694 : depends_on< count, sum > // depends_on<> to specify dependencies
696 // Define a nested typedef called 'impl' that specifies which
697 // accumulator implements this feature.
698 typedef accumulators::impl::mean_accumulator< mpl::_1 > impl;
703 The only two things we must do to define the `mean` feature is to specify the
704 dependencies with _depends_on_ and define the nested `impl` typedef. Even features
705 that have no dependencies should inherit from _depends_on_. The nested `impl` type
706 must be an _mpl_lambda_expression_. The result of
707 `mpl::apply< impl, _sample_type_, _weight_type_ >::type` must be
708 be the type of the accumulator that implements this feature. The use of _mpl_
709 placeholders like `mpl::_1` make it especially easy to make a template such
710 as `mean_accumulator<>` an _mpl_lambda_expression_. Here, `mpl::_1` will be
711 replaced with the sample type. Had we used `mpl::_2`, it would have been replaced
712 with the weight type.
714 What about accumulator types that are not templates? If you have a `foo_accumulator`
715 which is a plain struct and not a template, you could turn it into an
716 _mpl_lambda_expression_ using `mpl::always<>`, like this:
718 // An MPL lambda expression that always evaluates to
720 typedef mpl::always< foo_accumulator > impl;
722 If you are ever unsure, or if you are not comfortable with MPL lambda expressions,
723 you could always define `impl` explicitly:
725 // Same as 'typedef mpl::always< foo_accumulator > impl;'
728 template< typename Sample, typename Weight >
731 typedef foo_accumulator type;
735 Here, `impl` is a binary [@../../libs/mpl/doc/refmanual/metafunction-class.html
736 MPL Metafunction Class], which is a kind of _mpl_lambda_expression_. The nested
737 `apply<>` template is part of the metafunction class protocol and tells MPL how
738 to build the accumulator type given the sample and weight types.
740 All features must also provide a nested `is_weight_accumulator` typedef. It must
741 be either `mpl::true_` or `mpl::false_`. _depends_on_ provides a default of
742 `mpl::false_` for all features that inherit from it, but that can be overridden
743 (or hidden, technically speaking) in the derived type. When the feature represents
744 an accumulation of information about the weights instead of the samples, we
745 can mark this feature as such with `typedef mpl::true_ is_weight_accumulator;`.
746 The weight accumulators are made external if the weight type is specified using
747 the _external_ template.
751 [section Defining a New Extractor]
753 Now that we have an accumulator and a feature, the only thing lacking is a way
754 to get results from the accumulator set. The Accumulators Framework provides the
755 _extractor_ class template to make it simple to define an extractor for your
756 feature. Here's an extractor for the `mean` feature we defined above:
759 namespace accumulators { // By convention, we put extractors
760 namespace extract { // in the 'extract' namespace
762 extractor< tag::mean > const mean = {}; // Simply define our extractor with
763 // our feature tag, like this.
765 using extract::mean; // Pull the extractor into the
766 // enclosing namespace.
769 Once defined, the `mean` extractor can be used to extract the result of the
770 `tag::mean` feature from an _accumulator_set_.
772 Parameterized features complicate this simple picture. Consider the `moment`
773 feature, for calculating the [^['N]]-th moment, where [^['N]] is specified as
774 a template parameter:
776 // An accumulator set for calculating the N-th moment, for N == 2 ...
777 accumulator_set< double, features< tag::moment<2> > > acc;
779 // ... add some data ...
781 // Display the 2nd moment ...
782 std::cout << "2nd moment is " << accumulators::moment<2>(acc) << std::endl;
784 In the expression `accumulators::moment<2>(acc)`, what is `moment`? It cannot be an object --
785 the syntax of C++ will not allow it. Clearly, if we want to provide this syntax,
786 we must make `moment` a function template. Here's what the definition of the
787 `moment` extractor looks like:
790 namespace accumulators { // By convention, we put extractors
791 namespace extract { // in the 'extract' namespace
793 template<int N, typename AccumulatorSet>
794 typename mpl::apply<AccumulatorSet, tag::moment<N> >::type::result_type
795 moment(AccumulatorSet const &acc)
797 return extract_result<tag::moment<N> >(acc);
801 using extract::moment; // Pull the extractor into the
802 // enclosing namespace.
805 The return type deserves some explanation. Every _accumulator_set_ type
806 is actually a unary [@../../libs/mpl/doc/refmanual/metafunction-class.html
807 MPL Metafunction Class]. When you `mpl::apply<>` an _accumulator_set_ and
808 a feature, the result is the type of the accumulator within the set that
809 implements that feature. And every accumulator provides a nested `result_type`
810 typedef that tells what its return type is. The extractor simply delegates
811 its work to the _extract_result_ function.
815 [section Controlling Dependencies]
817 The feature-based dependency resolution of the Accumulators Framework is
818 designed to allow multiple different implementation strategies for each
819 feature. For instance, two different accumulators may calculate the same
820 quantity with different rounding modes, or using different algorithms with
821 different size/speed tradeoffs. Other accumulators that depend on that
822 quantity shouldn't care how it's calculated. The Accumulators Framework
823 handles this by allowing several different accumulators satisfy the same
826 [*Aliasing feature dependencies with [^feature_of<>]]
828 Imagine that you would like to implement the hypothetical ['fubar] statistic,
829 and that you know two ways to calculate fubar on a bunch of samples: an
830 accurate but slow calculation and an approximate but fast calculation. You
831 might opt to make the accurate calculation the default, so you implement
832 two accumulators and call them `impl::fubar_impl` and `impl::fast_fubar_impl`.
833 You would also define the `tag::fubar` and `tag::fast_fubar` features as described
834 [link accumulators.user_s_guide.the_accumulators_framework.extending_the_accumulators_framework.defining_a_new_feature above].
835 Now, you would like to inform the Accumulators Framework that these two features
836 are the same from the point of view of dependency resolution. You can do that
837 with _feature_of_, as follows:
839 namespace boost { namespace accumulators
841 // For the purposes of feature-based dependency resolution,
842 // fast_fubar provides the same feature as fubar
844 struct feature_of<tag::fast_fubar>
845 : feature_of<tag::fubar>
850 The above code instructs the Accumulators Framework that, if another accumulator
851 in the set depends on the `tag::fubar` feature, the `tag::fast_fubar` feature
852 is an acceptable substitute.
854 [*Registering feature variants with [^as_feature<>]]
856 You may have noticed that some feature variants in the Accumulators Framework can be
857 specified with a nicer syntax. For instance, instead of `tag::mean` and `tag::immediate_mean`
858 you can specify them with `tag::mean(lazy)` and `tag::mean(immediate)` respectively.
859 These are merely aliases, but the syntax makes the relationship between the two clearer.
860 You can create these feature aliases with the _as_feature_ trait. Given the fubar example
861 above, you might decide to alias `tag::fubar(accurate)` with `tag::fubar` and
862 `tag::fubar(fast)` with `tag::fast_fubar`. You would do that as follows:
864 namespace boost { namespace accumulators
866 struct fast {}; // OK to leave these tags empty
870 struct as_feature<tag::fubar(accurate)>
872 typedef tag::fubar type;
876 struct as_feature<tag::fubar(fast)>
878 typedef tag::fast_fubar type;
882 Once you have done this, users of your fubar accumulator can request the `tag::fubar(fast)`
883 and `tag::fubar(accurate)` features when defining their `accumulator_set`s and get the correct
888 [section:operators_ex Specializing Numeric Operators]
890 This section describes how to adapt third-party numeric types to work with the Accumulator
893 Rather than relying on the built-in operators, the Accumulators Framework relies on functions
894 and operator overloads defined in the
895 [link accumulators.user_s_guide.the_accumulators_framework.numeric_operators_sub_library
896 Numeric Operators Sub-Library] for many of its numeric operations. This is so that it
897 is possible to assign non-standard meanings to arithmetic operations. For instance, when
898 calculating an average by dividing two integers, the standard integer division behavior
899 would be mathematically incorrect for most statistical quantities. So rather than use `x / y`,
900 the Accumulators Framework uses `numeric::fdiv(x, y)`, which does floating-point division
901 even if both `x` and `y` are integers.
903 Another example where the Numeric Operators Sub-Library is useful is when a type does not
904 define the operator overloads required to use it for some statistical calculations. For instance,
905 `std::vector<>` does not overload any arithmetic operators, yet it may be useful to use
906 `std::vector<>` as a sample or variate type. The Numeric Operators Sub-Library
907 defines the necessary operator overloads in the `boost::numeric::operators` namespace,
908 which is brought into scope by the Accumulators Framework with a using directive.
910 [*Numeric Function Objects and Tag Dispatching]
912 How are the numeric function object defined by the Numeric Operators Sub-Library made
913 to work with types such as `std::vector<>`? The free functions in the `boost::numeric` namespace
914 are implemented in terms of the function objects in the `boost::numeric::functional` namespace,
915 so to make `boost::numeric::fdiv()` do something sensible with a `std::vector<>`, for instance,
916 we'll need to partially specialize the `boost::numeric::functional::fdiv<>` function object.
918 The functional objects make use of a technique known as
919 [@http://www.boost.org/community/generic_programming.html#tag_dispatching ['tag dispatching]] to
920 select the proper implementation for the given operands. It works as follows:
922 namespace boost { namespace numeric { namespace functional
924 // Metafunction for looking up the tag associated with
925 // a given numeric type T.
929 // by default, all types have void as a tag type
933 // Forward declaration looks up the tag types of each operand
937 , typename LeftTag = typename tag<Left>::type
938 , typename RightTag = typename tag<Right>::type
943 If you have some user-defined type `MyDouble` for which you would like to customize the behavior
944 of `numeric::fdiv()`, you would specialize `numeric::functional::fdiv<>` by
945 first defining a tag type, as shown below:
947 namespace boost { namespace numeric { namespace functional
949 // Tag type for MyDouble
950 struct MyDoubleTag {};
952 // Specialize tag<> for MyDouble.
953 // This only needs to be done once.
957 typedef MyDoubleTag type;
960 // Specify how to divide a MyDouble by an integral count
961 template<typename Left, typename Right>
962 struct fdiv<Left, Right, MyDoubleTag, void>
964 // Define the type of the result
965 typedef ... result_type;
967 result_type operator()(Left & left, Right & right) const
974 Once you have done this, `numeric::fdiv()` will use your specialization
975 of `numeric::functional::fdiv<>` when the first argument is a `MyDouble`
976 object. All of the function objects in the Numeric Operators Sub-Library can
977 be customized in a similar fashion.
985 [h2 Accumulator Concept]
987 In the following table, `Acc` is the type of an accumulator, `acc` and `acc2` are objects of type
988 `Acc`, and `args` is the name of an argument pack from the _parameter_ library.
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`] []]
1003 [h2 Feature Concept]
1005 In the following table, `F` is the type of a feature and `S` is some scalar type.
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_`
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.]]
1028 [section The Statistical Accumulators Library]
1030 The Statistical Accumulators Library defines accumulators for incremental statistical
1031 computations. It is built on top of [link accumulators.user_s_guide.the_accumulators_framework
1032 The Accumulator Framework].
1034 [section:count count]
1036 The `count` feature is a simple counter that tracks the
1037 number of samples pushed into the accumulator set.
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)]]
1053 [def _COUNT_HPP_ [headerref boost/accumulators/statistics/count.hpp]]
1055 #include <_COUNT_HPP_>
1059 accumulator_set<int, features<tag::count> > acc;
1063 assert(3 == count(acc));
1067 * [classref boost::accumulators::impl::count_impl `count_impl`]
1071 [section:covariance covariance]
1073 The `covariance` feature is an iterative Monte Carlo estimator for the covariance.
1074 It is specified as `tag::covariance<_variate_type_, _variate_tag_>`.
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
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)]]
1093 [def _COVARIANCE_HPP_ [headerref boost/accumulators/statistics/covariance.hpp]]
1094 [def _COVARIATE_HPP_ [headerref boost/accumulators/statistics/variates/covariate.hpp]]
1096 #include <_COVARIANCE_HPP_>
1097 #include <_COVARIATE_HPP_>
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);
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]]
1116 [section:density density]
1118 The `tag::density` feature returns a histogram of the sample distribution. For more
1119 implementation details, see [classref boost::accumulators::impl::density_impl [^density_impl]].
1126 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
1127 , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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`]]
1142 [def _DENSITY_HPP_ [headerref boost/accumulators/statistics/density.hpp]]
1144 #include <_DENSITY_HPP_>
1148 Results from the `density` accumulator can only be extracted after the number of
1149 samples meets or exceeds the cache size.
1151 [/ TODO add example ]
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]]
1162 [section:error_of_mean error_of<mean>]
1164 The `error_of<mean>` feature calculates the error of the mean feature. It is equal to
1165 `sqrt(variance / (count - 1))`.
1169 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
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]]
1184 #include <_ERROR_OF_HPP_>
1185 #include <_ERROR_OF_MEAN_HPP_>
1189 accumulator_set<double, stats<tag::error_of<tag::mean> > > acc;
1193 assert(0.057735 == error_of<tag::mean>(acc));
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]]
1203 [section:extended_p_square extended_p_square]
1205 Multiple quantile estimation with the extended [^P^2] algorithm. For further
1206 details, see [classref boost::accumulators::impl::extended_p_square_impl [^extended_p_square_impl]].
1210 boost::iterator_range<
1211 _implementation_defined_
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)]]
1224 [def _EXTENDED_P_SQUARE_HPP_ [headerref boost/accumulators/statistics/extended_p_square.hpp]]
1226 #include <_EXTENDED_P_SQUARE_HPP_>
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);
1234 boost::lagged_fibonacci607 rng; // a random number generator
1235 for (int i=0; i<10000; ++i)
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);
1242 for (std::size_t i=3; i < probs.size(); ++i)
1244 BOOST_CHECK_CLOSE(extended_p_square(acc)[i], probs[i], 2);
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]]
1254 [section:extended_p_square_quantile extended_p_square_quantile ['and variants]]
1256 Quantile estimation using the extended [^P^2] algorithm for weighted and unweighted samples.
1257 By default, the calculation is linear and unweighted, but quadratic and weighted variants
1258 are also provided. For further implementation details, see
1259 [classref boost::accumulators::impl::extended_p_square_quantile_impl [^extended_p_square_quantile_impl]].
1261 All the variants share the `tag::quantile` feature and can be extracted using the `quantile()`
1266 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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.]]
1281 [def _EXTENDED_P_SQUARE_QUANTILE_HPP_ [headerref boost/accumulators/statistics/extended_p_square_quantile.hpp]]
1283 #include <_EXTENDED_P_SQUARE_QUANTILE_HPP_>
1287 typedef accumulator_set<double, stats<tag::extended_p_square_quantile> >
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;
1299 // a random number generator
1300 boost::lagged_fibonacci607 rng;
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);
1309 for (int i=0; i<10000; ++i)
1311 double sample = rng();
1314 acc_weighted(sample, weight = 1.);
1315 acc_weighted2(sample, weight = 1.);
1318 for (std::size_t i = 0; i < probs.size() - 1; ++i)
1321 quantile(acc, quantile_probability = 0.99025 + i*0.001)
1326 quantile(acc2, quantile_probability = 0.99025 + i*0.001)
1331 quantile(acc_weighted, quantile_probability = 0.99025 + i*0.001)
1336 quantile(acc_weighted2, quantile_probability = 0.99025 + i*0.001)
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]]
1350 [section:kurtosis kurtosis]
1352 The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the
1353 square of the 2nd central moment (the variance) of the samples, minus 3. The term [^-3] is added
1354 in order to ensure that the normal distribution has zero kurtosis. For more implementation
1355 details, see [classref boost::accumulators::impl::kurtosis_impl [^kurtosis_impl]]
1359 numeric::functional::fdiv<_sample_type_, _sample_type_>::result_type
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)]]
1371 [def _KURTOSIS_HPP_ [headerref boost/accumulators/statistics/kurtosis.hpp]]
1373 #include <_KURTOSIS_HPP_>
1377 accumulator_set<int, stats<tag::kurtosis > > acc;
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 );
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]]
1401 Calculates the maximum value of all the samples.
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)]]
1417 [def _MAX_HPP_ [headerref boost/accumulators/statistics/max.hpp]]
1419 #include <_MAX_HPP_>
1423 accumulator_set<int, stats<tag::max> > acc;
1426 BOOST_CHECK_EQUAL(1, (max)(acc));
1429 BOOST_CHECK_EQUAL(1, (max)(acc));
1432 BOOST_CHECK_EQUAL(2, (max)(acc));
1436 * [classref boost::accumulators::impl::max_impl [^max_impl]]
1440 [section:mean mean ['and variants]]
1442 Calculates the mean of samples, weights or variates. The calculation is either
1443 lazy (in the result extractor), or immediate (in the accumulator). The lazy implementation
1444 is the default. For more implementation details, see
1445 [classref boost::accumulators::impl::mean_impl [^mean_impl]] or.
1446 [classref boost::accumulators::impl::immediate_mean_impl [^immediate_mean_impl]]
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
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)]]
1469 [def _MEAN_HPP_ [headerref boost/accumulators/statistics/mean.hpp]]
1471 #include <_MEAN_HPP_>
1479 , tag::mean_of_weights
1480 , tag::mean_of_variates<int, tag::covariate1>
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);
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);
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);
1509 tag::mean(immediate)
1510 , tag::mean_of_weights(immediate)
1511 , tag::mean_of_variates<int, tag::covariate1>(immediate)
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);
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);
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);
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]]
1543 [section:median median ['and variants]]
1545 Median estimation based on the [^P^2] quantile estimator, the density estimator, or
1546 the [^P^2] cumulative distribution estimator. For more implementation details, see
1547 [classref boost::accumulators::impl::median_impl [^median_impl]],
1548 [classref boost::accumulators::impl::with_density_median_impl [^with_density_median_impl]],
1549 and [classref boost::accumulators::impl::with_p_square_cumulative_distribution_median_impl [^with_p_square_cumulative_distribution_median_impl]].
1551 The three median accumulators all satisfy the `tag::median` feature, and can all be
1552 extracted with the `median()` extractor.
1556 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
1572 [def _MEDIAN_HPP_ [headerref boost/accumulators/statistics/median.hpp]]
1574 #include <_MEDIAN_HPP_>
1578 // two random number generators
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);
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 );
1591 for (std::size_t i=0; i<100000; ++i)
1593 double sample = normal();
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.);
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]]
1616 Calculates the minimum value of all the samples.
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)]]
1632 [def _MIN_HPP_ [headerref boost/accumulators/statistics/min.hpp]]
1634 #include <_MIN_HPP_>
1638 accumulator_set<int, stats<tag::min> > acc;
1641 BOOST_CHECK_EQUAL(1, (min)(acc));
1644 BOOST_CHECK_EQUAL(0, (min)(acc));
1647 BOOST_CHECK_EQUAL(0, (min)(acc));
1651 * [classref boost::accumulators::impl::min_impl [^min_impl]]
1655 [section:moment moment]
1657 Calculates the N-th moment of the samples, which is defined as the sum of the N-th power of the
1658 samples over the count of samples.
1662 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
1674 [def _MOMENT_HPP_ [headerref boost/accumulators/statistics/moment.hpp]]
1676 #include <_MOMENT_HPP_>
1680 accumulator_set<int, stats<tag::moment<2> > > acc1;
1687 BOOST_CHECK_CLOSE(15., accumulators::moment<2>(acc1), 1e-5);
1689 accumulator_set<int, stats<tag::moment<5> > > acc2;
1695 // = 4424 / 4 = 1106
1697 BOOST_CHECK_CLOSE(1106., accumulators::moment<5>(acc2), 1e-5);
1701 * [classref boost::accumulators::impl::moment_impl [^moment_impl]]
1702 * [link accumulators.user_s_guide.the_statistical_accumulators_library.count [^count]]
1706 [section:p_square_cumulative_distribution p_square_cumulative_distribution]
1708 Histogram calculation of the cumulative distribution with the [^P^2] algorithm.
1709 For more implementation details, see
1710 [classref boost::accumulators::impl::p_square_cumulative_distribution_impl [^p_square_cumulative_distribution_impl]]
1717 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
1718 , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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`]]
1733 [def _P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_ [headerref boost/accumulators/statistics/p_square_cumul_dist.hpp]]
1735 #include <_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_>
1742 typedef accumulator_set<double, stats<tag::p_square_cumulative_distribution> > accumulator_t;
1744 accumulator_t acc(tag::p_square_cumulative_distribution::num_cells = 100);
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);
1751 for (std::size_t i=0; i<100000; ++i)
1756 typedef iterator_range<std::vector<std::pair<double, double> >::iterator > histogram_type;
1757 histogram_type histogram = p_square_cumulative_distribution(acc);
1759 for (std::size_t i = 0; i < histogram.size(); ++i)
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 );
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]]
1773 [section:p_square_quantile p_square_quantile ['and variants]]
1775 Single quantile estimation with the [^P^2] algorithm. For more implementation details, see
1776 [classref boost::accumulators::impl::p_square_quantile_impl [^p_square_quantile_impl]]
1780 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
1794 [def _P_SQUARE_QUANTILE_HPP_ [headerref boost/accumulators/statistics/p_square_quantile.hpp]]
1796 #include <_P_SQUARE_QUANTILE_HPP_>
1800 typedef accumulator_set<double, stats<tag::p_square_quantile> > accumulator_t;
1805 // a random number generator
1806 boost::lagged_fibonacci607 rng;
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);
1818 for (int i=0; i<100000; ++i)
1820 double sample = rng();
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 );
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]]
1849 [section:peaks_over_threshold peaks_over_threshold ['and variants]]
1851 Peaks Over Threshold method for quantile and tail mean estimation. For implementation
1852 details, see [classref boost::accumulators::impl::peaks_over_threshold_impl [^peaks_over_threshold_impl]]
1853 and [classref boost::accumulators::impl::peaks_over_threshold_prob_impl [^peaks_over_threshold_prob_impl]].
1855 Both `tag::peaks_over_threshold` and `tag::peaks_over_threshold_prob<>` satisfy the `tag::abstract_peaks_over_threshold`
1856 feature, and can be extracted with the `peaks_over_threshold()` extractor. The result is a 3-tuple representing
1857 the fit parameters `u_bar`, `beta_bar` and `xi_hat`.
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
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]]
1880 [def _PEAKS_OVER_THRESHOLD_HPP_ [headerref boost/accumulators/statistics/peaks_over_threshold.hpp]]
1882 #include <_PEAKS_OVER_THRESHOLD_HPP_>
1886 See example for [link accumulators.user_s_guide.the_statistical_accumulators_library.pot_quantile [^pot_quantile]].
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]]
1899 [section:pot_quantile pot_quantile ['and variants]]
1901 Quantile estimation based on Peaks over Threshold method (for both left and right tails). For
1902 implementation details, see [classref boost::accumulators::impl::pot_quantile_impl [^pot_quantile_impl]].
1904 Both `tag::pot_quantile<_left_or_right_>` and `tag::pot_quantile_prob<_left_or_right_>` satisfy the
1905 `tag::quantile` feature and can be extracted using the `quantile()` extractor.
1909 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
1924 [def _POT_QUANTILE_HPP_ [headerref boost/accumulators/statistics/pot_quantile.hpp]]
1926 #include <_POT_QUANTILE_HPP_>
1931 double epsilon = 1.;
1933 double alpha = 0.999;
1934 double threshold_probability = 0.99;
1935 double threshold = 3.;
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);
1944 accumulator_set<double, stats<tag::pot_quantile<right>(with_threshold_value)> > acc1(
1945 tag::peaks_over_threshold::threshold_value = threshold
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
1952 threshold_probability = 0.995;
1955 accumulator_set<double, stats<tag::pot_quantile<right>(with_threshold_value)> > acc3(
1956 tag::peaks_over_threshold::threshold_value = threshold
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
1963 for (std::size_t i = 0; i < 100000; ++i)
1965 double sample = normal();
1970 for (std::size_t i = 0; i < 100000; ++i)
1972 double sample = exponential();
1977 BOOST_CHECK_CLOSE( quantile(acc1, quantile_probability = alpha), 3.090232, epsilon );
1978 BOOST_CHECK_CLOSE( quantile(acc2, quantile_probability = alpha), 3.090232, epsilon );
1980 BOOST_CHECK_CLOSE( quantile(acc3, quantile_probability = alpha), 6.908, epsilon );
1981 BOOST_CHECK_CLOSE( quantile(acc4, quantile_probability = alpha), 6.908, epsilon );
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]]
1990 [section:pot_tail_mean pot_tail_mean]
1992 Estimation of the (coherent) tail mean based on the peaks over threshold method (for both left and right tails).
1993 For implementation details, see [classref boost::accumulators::impl::pot_tail_mean_impl [^pot_tail_mean_impl]].
1995 Both `tag::pot_tail_mean<_left_or_right_>` and `tag::pot_tail_mean_prob<_left_or_right_>` satisfy the
1996 `tag::tail_mean` feature and can be extracted using the `tail_mean()` extractor.
2000 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
2017 [def _POT_TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/pot_tail_mean.hpp]]
2019 #include <_POT_TAIL_MEAN_HPP_>
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]]
2033 [section:rolling_count rolling_count]
2035 The rolling count is the current number of elements in the rolling window.
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)]]
2049 [def _ROLLING_COUNT_HPP_ [headerref boost/accumulators/statistics/rolling_count.hpp]]
2051 #include <_ROLLING_COUNT_HPP_>
2055 accumulator_set<int, stats<tag::rolling_count> > acc(tag::rolling_window::window_size = 3);
2057 BOOST_CHECK_EQUAL(0u, rolling_count(acc));
2060 BOOST_CHECK_EQUAL(1u, rolling_count(acc));
2063 BOOST_CHECK_EQUAL(2u, rolling_count(acc));
2066 BOOST_CHECK_EQUAL(3u, rolling_count(acc));
2069 BOOST_CHECK_EQUAL(3u, rolling_count(acc));
2072 BOOST_CHECK_EQUAL(3u, rolling_count(acc));
2076 * [classref boost::accumulators::impl::rolling_count_impl [^rolling_count_impl]]
2080 [section:rolling_sum rolling_sum]
2082 The rolling sum is the sum of the last /N/ samples.
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)]]
2096 [def _ROLLING_SUM_HPP_ [headerref boost/accumulators/statistics/rolling_sum.hpp]]
2098 #include <_ROLLING_SUM_HPP_>
2102 accumulator_set<int, stats<tag::rolling_sum> > acc(tag::rolling_window::window_size = 3);
2104 BOOST_CHECK_EQUAL(0, rolling_sum(acc));
2107 BOOST_CHECK_EQUAL(1, rolling_sum(acc));
2110 BOOST_CHECK_EQUAL(3, rolling_sum(acc));
2113 BOOST_CHECK_EQUAL(6, rolling_sum(acc));
2116 BOOST_CHECK_EQUAL(9, rolling_sum(acc));
2119 BOOST_CHECK_EQUAL(12, rolling_sum(acc));
2123 * [classref boost::accumulators::impl::rolling_sum_impl [^rolling_sum_impl]]
2127 [section:rolling_mean rolling_mean]
2129 The rolling mean is the mean over the last /N/ samples. It is computed by dividing
2130 the rolling sum by the rolling count.
2132 Lazy or iterative calculation of the mean over the last /N/ samples. The lazy calculation is associated with the `tag::lazy_rolling_mean`
2133 feature, and the iterative calculation (which is the default) with the `tag::immediate_rolling_mean` feature. Both can be extracted
2134 using the `tag::rolling_mean()` extractor. For more implementation details, see
2135 [classref boost::accumulators::impl::lazy_rolling_mean_impl [^lazy_rolling_mean_impl]] and
2136 [classref boost::accumulators::impl::immediate_rolling_mean_impl [^immediate_rolling_mean_impl]]
2140 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
2154 [def _ROLLING_MEAN_HPP_ [headerref boost/accumulators/statistics/rolling_mean.hpp]]
2156 #include <_ROLLING_MEAN_HPP_>
2160 accumulator_set<int, stats<tag::rolling_mean> > acc(tag::rolling_window::window_size = 5);
2166 BOOST_CHECK_CLOSE( rolling_mean(acc), 2.0, 1e-6 );
2173 BOOST_CHECK_CLOSE( rolling_mean(acc), 5.0, 1e-6 );
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]]
2184 [section:rolling_moment rolling_moment]
2186 rolling_moment<M> calculates the /M/-th moment of the samples, which is defined as the sum of the /M/-th power of the samples over the count of samples, over the last /N/ samples.
2190 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
2202 [def _ROLLING_MOMENT_HPP_ [headerref boost/accumulators/statistics/rolling_moment.hpp]]
2204 #include <_ROLLING_MOMENT_HPP_>
2208 accumulator_set<int, stats<tag::rolling_moment<2> > > acc(tag::rolling_window::window_size = 3);
2213 BOOST_CHECK_CLOSE( rolling_moment<2>(acc), (4.0 + 16.0)/2, 1e-5 );
2218 BOOST_CHECK_CLOSE( rolling_moment<2>(acc), (16.0 + 25.0 + 36.0)/3, 1e-5 );
2222 * [classref boost::accumulators::impl::rolling_moment_impl [^rolling_moment_impl]]
2226 [section:rolling_variance rolling_variance]
2228 Lazy or iterative calculation of the variance over the last /N/ samples. The lazy calculation is associated with the `tag::lazy_rolling_variance`
2229 feature, and the iterative calculation with the `tag::immediate_rolling_variance` feature. Both can be extracted using the `tag::rolling_variance()` extractor.
2230 For more implementation details, see
2231 [classref boost::accumulators::impl::lazy_rolling_variance_impl [^lazy_rolling_variance_impl]] and
2232 [classref boost::accumulators::impl::immediate_rolling_variance_impl [^immediate_rolling_variance_impl]]
2236 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
2250 [def _ROLLING_VARIANCE_HPP_ [headerref boost/accumulators/statistics/rolling_variance.hpp]]
2252 #include <_ROLLING_VARIANCE_HPP_>
2256 accumulator_set<double, stats<tag::rolling_variance> > acc(tag::rolling_window::window_size = 4);
2260 BOOST_CHECK_CLOSE( rolling_variance(acc), 0.0, 1e-10 ); // variance is not defined for a single sample
2265 BOOST_CHECK_CLOSE( rolling_variance(acc), 1.21, 1e-10 ); // variance over samples 1-3
2272 BOOST_CHECK_CLOSE( rolling_variance(acc), 8.41666666666667, 1e-10 ); // variance over samples 4-7
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]]
2286 [section:skewness skewness]
2288 The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the [^3/2]-th power
2289 of the 2nd central moment (the variance) of the samples 3. For implementation details, see
2290 [classref boost::accumulators::impl::skewness_impl [^skewness_impl]].
2294 numeric::functional::fdiv<_sample_type_, _sample_type_>::result_type
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)]]
2306 [def _SKEWNESS_HPP_ [headerref boost/accumulators/statistics/skewness.hpp]]
2308 #include <_SKEWNESS_HPP_>
2312 accumulator_set<int, stats<tag::skewness > > acc2;
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 );
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]]
2333 [section:sum sum ['and variants]]
2335 For summing the samples, weights or variates. The default implementation uses the standard sum operation,
2336 but variants using the Kahan summation algorithm are also provided.
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)]]
2360 [def _SUM_HPP_ [headerref boost/accumulators/statistics/sum.hpp]]
2361 [def _SUM_KAHAN_HPP_ [headerref boost/accumulators/statistics/sum_kahan.hpp]]
2363 #include <_SUM_HPP_>
2364 #include <_SUM_KAHAN_HPP_>
2372 , tag::sum_of_weights
2373 , tag::sum_of_variates<int, tag::covariate1>
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));
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));
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));
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) {
2399 BOOST_CHECK_EQUAL(1.0f, sum_kahan(acc));
2403 * [classref boost::accumulators::impl::sum_impl [^sum_impl]]
2404 * [classref boost::accumulators::impl::sum_kahan_impl [^sum_kahan_impl]]
2410 Tracks the largest or smallest [^N] values. `tag::tail<right>` tracks the largest [^N],
2411 and `tag::tail<left>` tracks the smallest. The parameter [^N] is specified with the
2412 `tag::tail<_left_or_right_>::cache_size` initialization parameter. For implementation details, see
2413 [classref boost::accumulators::impl::tail_impl [^tail_impl]].
2415 Both `tag::tail<left>` and `tag::tail<right>` satisfy the `tag::abstract_tail` feature and
2416 can be extracted with the `tail()` extractor.
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
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]]
2439 [def _TAIL_HPP_ [headerref boost/accumulators/statistics/tail.hpp]]
2441 #include <_TAIL_HPP_>
2445 See the Example for [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_variate [^tail_variate]].
2449 * [classref boost::accumulators::impl::tail_impl [^tail_impl]]
2450 * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail_variate [^tail_variate]]
2454 [section:coherent_tail_mean coherent_tail_mean]
2456 Estimation of the coherent tail mean based on order statistics (for both left and right tails).
2457 The left coherent tail mean feature is `tag::coherent_tail_mean<left>`, and the right coherent
2458 tail mean feature is `tag::coherent_tail_mean<right>`. They both share the `tag::tail_mean` feature
2459 and can be extracted with the `tail_mean()` extractor. For more implementation details, see
2460 [classref boost::accumulators::impl::coherent_tail_mean_impl [^coherent_tail_mean_impl]]
2464 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
2476 [def _TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/tail_mean.hpp]]
2478 #include <_TAIL_MEAN_HPP_>
2483 [link accumulators.user_s_guide.the_statistical_accumulators_library.non_coherent_tail_mean [^non_coherent_tail_mean]].
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]]
2496 [section:non_coherent_tail_mean non_coherent_tail_mean]
2498 Estimation of the (non-coherent) tail mean based on order statistics (for both left and right tails).
2499 The left non-coherent tail mean feature is `tag::non_coherent_tail_mean<left>`, and the right non-choherent
2500 tail mean feature is `tag::non_coherent_tail_mean<right>`. They both share the `tag::abstract_non_coherent_tail_mean`
2501 feature and can be extracted with the `non_coherent_tail_mean()` extractor. For more implementation details, see
2502 [classref boost::accumulators::impl::non_coherent_tail_mean_impl [^non_coherent_tail_mean_impl]]
2506 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
2518 [def _TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/tail_mean.hpp]]
2520 #include <_TAIL_MEAN_HPP_>
2527 std::size_t n = 100000; // number of MC steps
2528 std::size_t c = 10000; // cache size
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;
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 );
2540 // a random number generator
2541 boost::lagged_fibonacci607 rng;
2543 for (std::size_t i = 0; i < n; ++i)
2545 double sample = rng();
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 );
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]]
2578 [section:tail_quantile tail_quantile]
2580 Tail quantile estimation based on order statistics (for both left and right tails).
2581 The left tail quantile feature is `tag::tail_quantile<left>`, and the right
2582 tail quantile feature is `tag::tail_quantile<right>`. They both share the `tag::quantile`
2583 feature and can be extracted with the `quantile()` extractor. For more implementation details, see
2584 [classref boost::accumulators::impl::tail_quantile_impl [^tail_quantile_impl]]
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]]
2600 [def _TAIL_QUANTILE_HPP_ [headerref boost/accumulators/statistics/tail_quantile.hpp]]
2602 #include <_TAIL_QUANTILE_HPP_>
2609 std::size_t n = 100000; // number of MC steps
2610 std::size_t c = 10000; // cache size
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;
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 );
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);
2625 for (std::size_t i = 0; i < n; ++i)
2627 double sample1 = rng();
2628 double sample2 = normal();
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 );
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 );
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]]
2659 [section:tail_variate tail_variate]
2661 Tracks the covariates of largest or smallest [^N] samples.
2662 `tag::tail_variate<_variate_type_, _variate_tag_, right>` tracks the covariate associated with
2663 _variate_tag_ for the largest [^N], and `tag::tail_variate<_variate_type_, _variate_tag_, left>`
2664 for the smallest. The parameter [^N] is specified with the `tag::tail<_left_or_right_>::cache_size`
2665 initialization parameter. For implementation details, see
2666 [classref boost::accumulators::impl::tail_variate_impl [^tail_variate_impl]].
2668 Both `tag::tail_variate<_variate_type_, _variate_tag_, right>` and
2669 `tag::tail_variate<_variate_type_, _variate_tag_, left>` satisfy the `tag::abstract_tail_variate` feature
2670 and can be extracted with the `tail_variate()` extractor.
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
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]]
2693 [def _TAIL_VARIATE_HPP_ [headerref boost/accumulators/statistics/tail_variate.hpp]]
2695 #include <_TAIL_VARIATE_HPP_>
2699 accumulator_set<int, stats<tag::tail_variate<int, tag::covariate1, right> > > acc(
2700 tag::tail<right>::cache_size = 4
2703 acc(8, covariate1 = 3);
2704 CHECK_RANGE_EQUAL(tail(acc), {8});
2705 CHECK_RANGE_EQUAL(tail_variate(acc), {3});
2707 acc(16, covariate1 = 1);
2708 CHECK_RANGE_EQUAL(tail(acc), {16, 8});
2709 CHECK_RANGE_EQUAL(tail_variate(acc), {1, 3});
2711 acc(12, covariate1 = 4);
2712 CHECK_RANGE_EQUAL(tail(acc), {16, 12, 8});
2713 CHECK_RANGE_EQUAL(tail_variate(acc), {1, 4, 3});
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});
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});
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});
2729 * [classref boost::accumulators::impl::tail_variate_impl [^tail_variate_impl]]
2730 * [link accumulators.user_s_guide.the_statistical_accumulators_library.tail [^tail]]
2734 [section:tail_variate_means tail_variate_means ['and variants]]
2736 Estimation of the absolute and relative tail variate means (for both left and right tails).
2737 The absolute tail variate means has the feature
2738 `tag::absolute_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`
2739 and the relative tail variate mean has the feature
2740 `tag::relative_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`. All
2741 absolute tail variate mean features share the `tag::abstract_absolute_tail_variate_means`
2742 feature and can be extracted with the `tail_variate_means()` extractor. All the
2743 relative tail variate mean features share the `tag::abstract_relative_tail_variate_means`
2744 feature and can be extracted with the `relative_tail_variate_means()` extractor.
2746 For more implementation details, see
2747 [classref boost::accumulators::impl::tail_variate_means_impl [^tail_variate_means_impl]]
2751 boost::iterator_range<
2753 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
2769 [def _TAIL_VARIATE_MEANS_HPP_ [headerref boost/accumulators/statistics/tail_variate_means.hpp]]
2771 #include <_TAIL_VARIATE_MEANS_HPP_>
2775 std::size_t c = 5; // cache size
2777 typedef double variate_type;
2778 typedef std::vector<variate_type> variate_set_type;
2780 typedef accumulator_set<double, stats<
2781 tag::tail_variate_means<right, variate_set_type, tag::covariate1>(relative)>, tag::tail<right> >
2784 typedef accumulator_set<double, stats<
2785 tag::tail_variate_means<right, variate_set_type, tag::covariate1>(absolute)>, tag::tail<right> >
2788 typedef accumulator_set<double, stats<
2789 tag::tail_variate_means<left, variate_set_type, tag::covariate1>(relative)>, tag::tail<left> >
2792 typedef accumulator_set<double, stats<
2793 tag::tail_variate_means<left, variate_set_type, tag::covariate1>(absolute)>, tag::tail<left> >
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 );
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));
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);
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);
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);
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);
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
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
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
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
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]]
2885 [section:variance variance ['and variants]]
2887 Lazy or iterative calculation of the variance. The lazy calculation is associated with the `tag::lazy_variance`
2888 feature, and the iterative calculation with the `tag::variance` feature. Both can be extracted
2889 using the `tag::variance()` extractor. For more implementation details, see
2890 [classref boost::accumulators::impl::lazy_variance_impl [^lazy_variance_impl]] and
2891 [classref boost::accumulators::impl::variance_impl [^variance_impl]]
2895 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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)]]
2909 [def _VARIANCE_HPP_ [headerref boost/accumulators/statistics/variance.hpp]]
2911 #include <_VARIANCE_HPP_>
2916 accumulator_set<int, stats<tag::variance(lazy)> > acc1;
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);
2929 // immediate variance
2930 accumulator_set<int, stats<tag::variance> > acc2;
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);
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]]
2952 [section:weighted_covariance weighted_covariance]
2954 An iterative Monte Carlo estimator for the weighted covariance. The feature is specified as
2955 `tag::weighted_covariance<_variate_type_, _variate_tag_>` and is extracted with the `weighted_variate()`
2956 extractor. For more implementation details, see
2957 [classref boost::accumulators::impl::weighted_covariance_impl [^weighted_covariance_impl]]
2961 numeric::functional::outer_product<
2962 numeric::functional::multiplies<
2964 , numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
2966 , numeric::functional::multiplies<
2968 , numeric::functional::fdiv<_variate_type_, std::size_t>::result_type
2972 [[Depends On] [`count` \n
2975 `weighted_mean_of_variates<_variate_type_, _variate_tag_>`]]
2976 [[Variants] [`abstract_weighted_covariance`]]
2977 [[Initialization Parameters] [['none]]]
2978 [[Accumulator Parameters] [`weight` \n
2980 [[Extractor Parameters] [['none]]]
2981 [[Accumulator Complexity] [O(1)]]
2982 [[Extractor Complexity] [O(1)]]
2986 [def _WEIGHTED_COVARIANCE_HPP_ [headerref boost/accumulators/statistics/weighted_covariance.hpp]]
2988 #include <_WEIGHTED_COVARIANCE_HPP_>
2992 accumulator_set<double, stats<tag::weighted_covariance<double, tag::covariate1> >, double > acc;
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.);
2999 double epsilon = 1e-6;
3000 BOOST_CHECK_CLOSE(weighted_covariance(acc), -2.39, epsilon);
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]]
3011 [section:weighted_density weighted_density]
3013 The `tag::weighted_density` feature returns a histogram of the weighted sample distribution. For more
3014 implementation details, see [classref boost::accumulators::impl::weighted_density_impl [^weighted_density_impl]].
3021 numeric::functional::fdiv<_weight_type_, std::size_t>::result_type
3022 , numeric::functional::fdiv<_weight_type_, std::size_t>::result_type
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`]]
3037 [def _WEIGHTED_DENSITY_HPP_ [headerref boost/accumulators/statistics/weighted_density.hpp]]
3039 #include <_WEIGHTED_DENSITY_HPP_>
3041 [/ TODO add example ]
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]]
3053 [section:weighted_extended_p_square weighted_extended_p_square]
3055 Multiple quantile estimation with the extended [^P^2] algorithm for weighted samples. For further
3056 details, see [classref boost::accumulators::impl::weighted_extended_p_square_impl [^weighted_extended_p_square_impl]].
3060 boost::iterator_range<
3061 _implementation_defined_
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)]]
3074 [def _WEIGHTED_EXTENDED_P_SQUARE_HPP_ [headerref boost/accumulators/statistics/weighted_extended_p_square.hpp]]
3076 #include <_WEIGHTED_EXTENDED_P_SQUARE_HPP_>
3080 typedef accumulator_set<double, stats<tag::weighted_extended_p_square>, double> accumulator_t;
3085 // some random number generators
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);
3094 std::vector<double> probs_uniform, probs_normal1, probs_normal2, probs_normal_exact1, probs_normal_exact2;
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));
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));
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));
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);
3113 for (std::size_t i = 0; i < 100000; ++i)
3115 acc_uniform(rng(), weight = 1.);
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)));
3123 // check for uniform distribution
3124 for (std::size_t i = 0; i < probs_uniform.size(); ++i)
3126 BOOST_CHECK_CLOSE(weighted_extended_p_square(acc_uniform)[i], probs_uniform[i], epsilon);
3129 // check for standard normal distribution
3130 for (std::size_t i = 0; i < probs_normal1.size(); ++i)
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);
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]]
3144 [section:weighted_kurtosis weighted_kurtosis]
3146 The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the
3147 square of the 2nd central moment (the variance) of the samples, minus 3. The term [^-3] is added
3148 in order to ensure that the normal distribution has zero kurtosis. For more implementation
3149 details, see [classref boost::accumulators::impl::weighted_kurtosis_impl [^weighted_kurtosis_impl]]
3153 numeric::functional::fdiv<
3154 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
3155 , numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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)]]
3168 [def _WEIGHTED_KURTOSIS_HPP_ [headerref boost/accumulators/statistics/weighted_kurtosis.hpp]]
3170 #include <_WEIGHTED_KURTOSIS_HPP_>
3174 accumulator_set<int, stats<tag::weighted_kurtosis>, int > acc2;
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);
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 );
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]]
3196 [section:weighted_mean weighted_mean ['and variants]]
3198 Calculates the weighted mean of samples or variates. The calculation is either
3199 lazy (in the result extractor), or immediate (in the accumulator). The lazy implementation
3200 is the default. For more implementation details, see
3201 [classref boost::accumulators::impl::weighted_mean_impl [^weighted_mean_impl]] or.
3202 [classref boost::accumulators::impl::immediate_weighted_mean_impl [^immediate_weighted_mean_impl]]
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)]]
3221 [def _WEIGHTED_MEAN_HPP_ [headerref boost/accumulators/statistics/weighted_mean.hpp]]
3223 #include <_WEIGHTED_MEAN_HPP_>
3231 , tag::weighted_mean_of_variates<int, tag::covariate1>
3236 acc(10, weight = 2, covariate1 = 7); // 20
3237 BOOST_CHECK_EQUAL(2, sum_of_weights(acc)); //
3239 acc(6, weight = 3, covariate1 = 8); // 18
3240 BOOST_CHECK_EQUAL(5, sum_of_weights(acc)); //
3242 acc(4, weight = 4, covariate1 = 9); // 16
3243 BOOST_CHECK_EQUAL(9, sum_of_weights(acc)); //
3245 acc(6, weight = 5, covariate1 = 6); //+ 30
3246 BOOST_CHECK_EQUAL(14, sum_of_weights(acc)); //
3249 BOOST_CHECK_EQUAL(6., weighted_mean(acc));
3250 BOOST_CHECK_EQUAL(52./7., (accumulators::weighted_mean_of_variates<int, tag::covariate1>(acc)));
3255 tag::weighted_mean(immediate)
3256 , tag::weighted_mean_of_variates<int, tag::covariate1>(immediate)
3261 acc2(10, weight = 2, covariate1 = 7); // 20
3262 BOOST_CHECK_EQUAL(2, sum_of_weights(acc2)); //
3264 acc2(6, weight = 3, covariate1 = 8); // 18
3265 BOOST_CHECK_EQUAL(5, sum_of_weights(acc2)); //
3267 acc2(4, weight = 4, covariate1 = 9); // 16
3268 BOOST_CHECK_EQUAL(9, sum_of_weights(acc2)); //
3270 acc2(6, weight = 5, covariate1 = 6); //+ 30
3271 BOOST_CHECK_EQUAL(14, sum_of_weights(acc2)); //
3274 BOOST_CHECK_EQUAL(6., weighted_mean(acc2));
3275 BOOST_CHECK_EQUAL(52./7., (accumulators::weighted_mean_of_variates<int, tag::covariate1>(acc2)));
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]]
3286 [section:weighted_median weighted_median ['and variants]]
3288 Median estimation for weighted samples based on the [^P^2] quantile estimator, the density estimator, or
3289 the [^P^2] cumulative distribution estimator. For more implementation details, see
3290 [classref boost::accumulators::impl::weighted_median_impl [^weighted_median_impl]],
3291 [classref boost::accumulators::impl::with_weighted_density_median_impl [^with_weighted_density_median_impl]],
3292 and [classref boost::accumulators::impl::with_weighted_p_square_cumulative_distribution_median_impl [^with_weighted_p_square_cumulative_distribution_median_impl]].
3294 The three median accumulators all satisfy the `tag::weighted_median` feature, and can all be
3295 extracted with the `weighted_median()` extractor.
3299 numeric::functional::fdiv<_sample_type_, std::size_t>::result_type
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]]
3315 [def _WEIGHTED_MEDIAN_HPP_ [headerref boost/accumulators/statistics/weighted_median.hpp]]
3317 #include <_WEIGHTED_MEDIAN_HPP_>
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
3324 // two random number generators
3326 double sigma_narrow = 0.01;
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);
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 );
3338 for (std::size_t i=0; i<100000; ++i)
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 )));
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);
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]]
3361 [section:weighted_moment weighted_moment]
3363 Calculates the N-th moment of the weighted samples, which is defined as the sum of the weighted N-th
3364 power of the samples over the sum of the weights.
3368 numeric::functional::fdiv<
3369 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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)]]
3383 [def _WEIGHTED_MOMENT_HPP_ [headerref boost/accumulators/statistics/weighted_moment.hpp]]
3385 #include <_WEIGHTED_MOMENT_HPP_>
3389 accumulator_set<double, stats<tag::weighted_moment<2> >, double> acc2;
3390 accumulator_set<double, stats<tag::weighted_moment<7> >, double> acc7;
3392 acc2(2.1, weight = 0.7);
3393 acc2(2.7, weight = 1.4);
3394 acc2(1.8, weight = 0.9);
3396 acc7(2.1, weight = 0.7);
3397 acc7(2.7, weight = 1.4);
3398 acc7(1.8, weight = 0.9);
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);
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]]
3411 [section:weighted_p_square_cumulative_distribution weighted_p_square_cumulative_distribution]
3413 Histogram calculation of the cumulative distribution with the [^P^2] algorithm for weighted samples.
3414 For more implementation details, see
3415 [classref boost::accumulators::impl::weighted_p_square_cumulative_distribution_impl [^weighted_p_square_cumulative_distribution_impl]]
3422 numeric::functional::fdiv<weighted_sample, std::size_t>::result_type
3423 , numeric::functional::fdiv<weighted_sample, std::size_t>::result_type
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`]]
3439 [def _WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_ [headerref boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp]]
3441 #include <_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_>
3448 typedef accumulator_set<double, stats<tag::weighted_p_square_cumulative_distribution>, double > accumulator_t;
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);
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);
3462 for (std::size_t i=0; i<100000; ++i)
3464 double sample = normal_upper();
3465 acc_upper(sample, weight = std::exp(-mu_upper * (sample - 0.5 * mu_upper)));
3468 for (std::size_t i=0; i<100000; ++i)
3470 double sample = normal_lower();
3471 acc_lower(sample, weight = std::exp(-mu_lower * (sample - 0.5 * mu_lower)));
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);
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
3482 for (std::size_t i = 0; i < histogram_upper.size(); ++i)
3484 // problem with small results: epsilon is relative (in percent), not absolute!
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 );
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]]
3502 [section:weighted_p_square_quantile weighted_p_square_quantile ['and variants]]
3504 Single quantile estimation with the [^P^2] algorithm. For more implementation details, see
3505 [classref boost::accumulators::impl::weighted_p_square_quantile_impl [^weighted_p_square_quantile_impl]]
3509 numeric::functional::fdiv<
3510 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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)]]
3526 [def _WEIGHTED_P_SQUARE_QUANTILE_HPP_ [headerref boost/accumulators/statistics/weighted_p_square_quantile.hpp]]
3528 #include <_WEIGHTED_P_SQUARE_QUANTILE_HPP_>
3532 typedef accumulator_set<double, stats<tag::weighted_p_square_quantile>, double> accumulator_t;
3537 // some random number generators
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);
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);
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);
3563 for (std::size_t i=0; i<100000; ++i)
3565 double sample = rng();
3566 acc0(sample, weight = 1.);
3567 acc1(sample, weight = 1.);
3568 acc2(sample, weight = 1.);
3569 acc3(sample, weight = 1.);
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)));
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 );
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 );
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]]
3601 [section:weighted_peaks_over_threshold weighted_peaks_over_threshold ['and variants]]
3603 Weighted peaks over threshold method for weighted quantile and weighted tail mean estimation.
3604 For more implementation details,
3605 see [classref boost::accumulators::impl::weighted_peaks_over_threshold_impl [^weighted_peaks_over_threshold_impl]]
3606 and [classref boost::accumulators::impl::weighted_peaks_over_threshold_prob_impl [^weighted_peaks_over_threshold_prob_impl]].
3608 Both `tag::weighted_peaks_over_threshold<_left_or_right_>` and
3609 `tag::weighted_peaks_over_threshold_prob<_left_or_right_>` satisfy the
3610 `tag::weighted_peaks_over_threshold<_left_or_right_>` feature and can be extracted using the
3611 `weighted_peaks_over_threshold()` extractor.
3614 [[Result Type] [`tuple<float_type, float_type, float_type>` where `float_type` is
3616 numeric::functional::fdiv<
3617 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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)]]
3634 [def _WEIGHTED_PEAKS_OVER_THRESHOLD_HPP_ [headerref boost/accumulators/statistics/weighted_peaks_over_threshold.hpp]]
3636 #include <_WEIGHTED_PEAKS_OVER_THRESHOLD_HPP_>
3638 [/ TODO Add example]
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]]
3649 [section:weighted_skewness weighted_skewness]
3651 The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the [^3/2]-th power
3652 of the 2nd central moment (the variance) of the samples 3. The skewness estimator for weighted samples
3653 is formally identical to the estimator for unweighted samples, except that the weighted counterparts of
3654 all measures it depends on are to be taken.
3656 For implementation details, see
3657 [classref boost::accumulators::impl::weighted_skewness_impl [^weighted_skewness_impl]].
3661 numeric::functional::fdiv<
3662 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
3663 , numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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)]]
3676 [def _WEIGHTED_SKEWNESS_HPP_ [headerref boost/accumulators/statistics/weighted_skewness.hpp]]
3678 #include <_WEIGHTED_SKEWNESS_HPP_>
3682 accumulator_set<int, stats<tag::weighted_skewness>, int > acc2;
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);
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 );
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]]
3703 [section:weighted_sum weighted_sum ['and variants]]
3705 For summing the weighted samples or variates. All of the `tag::weighted_sum_of_variates<>` features
3706 can be extracted with the `weighted_sum_of_variates()` extractor. Variants that implement the Kahan
3707 summation algorithm are also provided.
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)]]
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]]
3731 #include <_WEIGHTED_SUM_HPP_>
3732 #include <_WEIGHTED_SUM_KAHAN_HPP_>
3737 accumulator_set<int, stats<tag::weighted_sum, tag::weighted_sum_of_variates<int, tag::covariate1> >, int> acc;
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));
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));
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));
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);
3757 BOOST_CHECK_EQUAL(1.0f, weighted_sum_kahan(acc));
3761 * [classref boost::accumulators::impl::weighted_sum_impl [^weighted_sum_impl]]
3762 * [classref boost::accumulators::impl::weighted_sum_impl [^weighted_sum_kahan_impl]]
3766 [section:non_coherent_weighted_tail_mean non_coherent_weighted_tail_mean]
3768 Estimation of the (non-coherent) weighted tail mean based on order statistics (for both left and right tails).
3769 The left non-coherent weighted tail mean feature is `tag::non_coherent_weighted_tail_mean<left>`, and the right
3770 non-choherent weighted tail mean feature is `tag::non_coherent_weighted_tail_mean<right>`. They both share the
3771 `tag::abstract_non_coherent_tail_mean` feature with the unweighted non-coherent tail mean accumulators and can
3772 be extracted with either the `non_coherent_tail_mean()` or the `non_coherent_weighted_tail_mean()` extractors.
3773 For more implementation details, see
3774 [classref boost::accumulators::impl::non_coherent_weighted_tail_mean_impl [^non_coherent_weighted_tail_mean_impl]].
3778 numeric::functional::fdiv<
3779 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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]]
3793 [def _WEIGHTED_TAIL_MEAN_HPP_ [headerref boost/accumulators/statistics/weighted_tail_mean.hpp]]
3795 #include <_WEIGHTED_TAIL_MEAN_HPP_>
3802 std::size_t n = 100000; // number of MC steps
3803 std::size_t c = 25000; // cache size
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 );
3810 // random number generators
3811 boost::lagged_fibonacci607 rng;
3813 for (std::size_t i = 0; i < n; ++i)
3815 double smpl = std::sqrt(rng());
3816 acc0(smpl, weight = 1./smpl);
3819 for (std::size_t i = 0; i < n; ++i)
3821 double smpl = rng();
3822 acc1(smpl*smpl, weight = smpl);
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 );
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]]
3843 [section:weighted_tail_quantile weighted_tail_quantile]
3845 Tail quantile estimation based on order statistics of weighted samples (for both left
3846 and right tails). The left weighted tail quantile feature is `tag::weighted_tail_quantile<left>`,
3847 and the right weighted tail quantile feature is `tag::weighted_tail_quantile<right>`. They both
3848 share the `tag::quantile` feature with the unweighted tail quantile accumulators and can be
3849 extracted with either the `quantile()` or the `weighted_tail_quantile()` extractors. For more
3850 implementation details, see
3851 [classref boost::accumulators::impl::weighted_tail_quantile_impl [^weighted_tail_quantile_impl]]
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]]
3867 [def _WEIGHTED_TAIL_QUANTILE_HPP_ [headerref boost/accumulators/statistics/weighted_tail_quantile.hpp]]
3869 #include <_WEIGHTED_TAIL_QUANTILE_HPP_>
3876 std::size_t n = 100000; // number of MC steps
3877 std::size_t c = 20000; // cache size
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);
3887 accumulator_set<double, stats<tag::weighted_tail_quantile<right> >, double>
3888 acc1(right_tail_cache_size = c);
3890 accumulator_set<double, stats<tag::weighted_tail_quantile<left> >, double>
3891 acc2(left_tail_cache_size = c);
3893 for (std::size_t i = 0; i < n; ++i)
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)));
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 );
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]]
3915 [section:weighted_tail_variate_means weighted_tail_variate_means ['and variants]]
3917 Estimation of the absolute and relative weighted tail variate means (for both left and right tails)
3918 The absolute weighted tail variate means has the feature
3919 `tag::absolute_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`
3920 and the relative weighted tail variate mean has the feature
3921 `tag::relative_weighted_tail_variate_means<_left_or_right_, _variate_type_, _variate_tag_>`. All
3922 absolute weighted tail variate mean features share the `tag::abstract_absolute_tail_variate_means`
3923 feature with their unweighted variants and can be extracted with the `tail_variate_means()` and
3924 `weighted_tail_variate_means()` extractors. All the relative weighted tail variate mean features
3925 share the `tag::abstract_relative_tail_variate_means` feature with their unweighted variants
3926 and can be extracted with either the `relative_tail_variate_means()` or
3927 `relative_weighted_tail_variate_means()` extractors.
3929 For more implementation details, see
3930 [classref boost::accumulators::impl::weighted_tail_variate_means_impl [^weighted_tail_variate_means_impl]]
3934 boost::iterator_range<
3935 numeric::functional::fdiv<
3936 numeric::functional::multiplies<_variate_type_, _weight_type_>::result_type
3938 >::result_type::iterator
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]]
3954 [def _WEIGHTED_TAIL_VARIATE_MEANS_HPP_ [headerref boost/accumulators/statistics/weighted_tail_variate_means.hpp]]
3956 #include <_WEIGHTED_TAIL_VARIATE_MEANS_HPP_>
3960 std::size_t c = 5; // cache size
3962 typedef double variate_type;
3963 typedef std::vector<variate_type> variate_set_type;
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 );
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));
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);
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);
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);
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);
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) );
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 );
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) );
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 );
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]]
4059 [section:weighted_variance weighted_variance ['and variants]]
4061 Lazy or iterative calculation of the weighted variance. The lazy calculation is associated with the `tag::lazy_weighted_variance`
4062 feature, and the iterative calculation with the `tag::weighted_variance` feature. Both can be extracted
4063 using the `tag::weighted_variance()` extractor. For more implementation details, see
4064 [classref boost::accumulators::impl::lazy_weighted_variance_impl [^lazy_weighted_variance_impl]] and
4065 [classref boost::accumulators::impl::weighted_variance_impl [^weighted_variance_impl]]
4069 numeric::functional::fdiv<
4070 numeric::functional::multiplies<_sample_type_, _weight_type_>::result_type
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)]]
4086 [def _WEIGHTED_VARIANCE_HPP_ [headerref boost/accumulators/statistics/weighted_variance.hpp]]
4088 #include <_WEIGHTED_VARIANCE_HPP_>
4092 // lazy weighted_variance
4093 accumulator_set<int, stats<tag::weighted_variance(lazy)>, int> acc1;
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
4101 // weighted_mean = (2+6+3+16+5) / (2+3+1+4+1) = 32 / 11 = 2.9090909090909090909090909090909
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);
4108 // immediate weighted_variance
4109 accumulator_set<int, stats<tag::weighted_variance>, int> acc2;
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);
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);
4121 // check lazy and immediate variance with random numbers
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);
4128 accumulator_set<double, stats<tag::weighted_variance>, double > acc_lazy;
4129 accumulator_set<double, stats<tag::weighted_variance(immediate)>, double > acc_immediate;
4131 for (std::size_t i=0; i<10000; ++i)
4133 double value = normal();
4134 acc_lazy(value, weight = rng());
4135 acc_immediate(value, weight = rng());
4138 BOOST_CHECK_CLOSE(1., weighted_variance(acc_lazy), 1.);
4139 BOOST_CHECK_CLOSE(1., weighted_variance(acc_immediate), 1.);
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]]
4155 [section Acknowledgements]
4157 Boost.Accumulators represents the efforts of many individuals. I would like to thank
4158 Daniel Egloff of _ZKB_ for helping to conceive the library and realize its
4159 implementation. I would also like to thank David Abrahams and Matthias Troyer for
4160 their key contributions to the design of the library. Many thanks are due to Michael
4161 Gauckler and Olivier Gygi, who, along with Daniel Egloff, implemented many of the
4162 statistical accumulators.
4164 I would also like to thank Simon West for all his assistance maintaining
4167 Finally, I would like to thank _ZKB_ for sponsoring the work on Boost.Accumulators
4168 and graciously donating it to the community.
4174 [xinclude accdoc.xml]
4176 [xinclude statsdoc.xml]
4178 [xinclude opdoc.xml]