1 | Index: boost/accumulators/statistics/sum_kahan.hpp
|
---|
2 | ===================================================================
|
---|
3 | --- boost/accumulators/statistics/sum_kahan.hpp (revision 0)
|
---|
4 | +++ boost/accumulators/statistics/sum_kahan.hpp (revision 0)
|
---|
5 | @@ -0,0 +1,91 @@
|
---|
6 | +///////////////////////////////////////////////////////////////////////////////
|
---|
7 | +// sum_kahan.hpp
|
---|
8 | +//
|
---|
9 | +// Copyright 2010 Gaetano Mendola. Distributed under the Boost
|
---|
10 | +// Software License, Version 1.0. (See accompanying file
|
---|
11 | +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
---|
12 | +
|
---|
13 | +#ifndef BOOST_ACCUMULATORS_STATISTICS_SUM_KAHAN_HPP_EAN_26_07_2010
|
---|
14 | +#define BOOST_ACCUMULATORS_STATISTICS_SUM_KAHAN_HPP_EAN_26_07_2010
|
---|
15 | +
|
---|
16 | +#include <boost/accumulators/framework/accumulator_base.hpp>
|
---|
17 | +#include <boost/accumulators/framework/parameters/sample.hpp>
|
---|
18 | +#include <boost/numeric/conversion/cast.hpp>
|
---|
19 | +
|
---|
20 | +namespace boost { namespace accumulators
|
---|
21 | +{
|
---|
22 | +
|
---|
23 | +namespace impl
|
---|
24 | +{
|
---|
25 | +
|
---|
26 | +template<typename Sample>
|
---|
27 | +struct sum_kahan_impl
|
---|
28 | + : accumulator_base
|
---|
29 | +{
|
---|
30 | + typedef Sample result_type;
|
---|
31 | +
|
---|
32 | + ////////////////////////////////////////////////////////////////////////////
|
---|
33 | + // sum_kahan_impl
|
---|
34 | + /**
|
---|
35 | + @brief Kahan summation algorithm
|
---|
36 | +
|
---|
37 | + Kahan algorithm reduces the numerical error obtained with standard
|
---|
38 | + sequential sum.
|
---|
39 | +
|
---|
40 | + */
|
---|
41 | + template<typename Args>
|
---|
42 | + sum_kahan_impl(Args const & args)
|
---|
43 | + : sum(args[sample | Sample()]),
|
---|
44 | + compensation(boost::numeric_cast<Sample>(0.0))
|
---|
45 | + {
|
---|
46 | + }
|
---|
47 | +
|
---|
48 | + template<typename Args>
|
---|
49 | + void operator ()(Args const & args)
|
---|
50 | + {
|
---|
51 | + const Sample myTmp1 = args[sample] - this->compensation;
|
---|
52 | + const Sample myTmp2 = this->sum + myTmp1;
|
---|
53 | + this->compensation = (myTmp2 - this->sum) - myTmp1;
|
---|
54 | + this->sum = myTmp2;
|
---|
55 | + }
|
---|
56 | +
|
---|
57 | + result_type result(dont_care) const
|
---|
58 | + {
|
---|
59 | + return this->sum;
|
---|
60 | + }
|
---|
61 | +private:
|
---|
62 | + Sample sum;
|
---|
63 | + Sample compensation;
|
---|
64 | +};
|
---|
65 | +
|
---|
66 | +} // namespace impl
|
---|
67 | +
|
---|
68 | +///////////////////////////////////////////////////////////////////////////////
|
---|
69 | +// tag::sum_kahan
|
---|
70 | +namespace tag
|
---|
71 | +{
|
---|
72 | +
|
---|
73 | + struct sum_kahan
|
---|
74 | + : depends_on<>
|
---|
75 | + {
|
---|
76 | + /// INTERNAL ONLY
|
---|
77 | + ///
|
---|
78 | + typedef impl::sum_kahan_impl< mpl::_1 > impl;
|
---|
79 | + };
|
---|
80 | +} // namespace tag
|
---|
81 | +
|
---|
82 | +///////////////////////////////////////////////////////////////////////////////
|
---|
83 | +// extract::sum_kahan
|
---|
84 | +namespace extract
|
---|
85 | +{
|
---|
86 | + extractor<tag::sum_kahan> const sum_kahan = {};
|
---|
87 | +
|
---|
88 | + BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_kahan)
|
---|
89 | +} // namespace extract
|
---|
90 | +
|
---|
91 | +using extract::sum_kahan;
|
---|
92 | +
|
---|
93 | +}} // namespace boost::accumulators
|
---|
94 | +
|
---|
95 | +#endif
|
---|
96 | +
|
---|
97 | Index: libs/accumulators/test/sum_kahan.cpp
|
---|
98 | ===================================================================
|
---|
99 | --- libs/accumulators/test/sum_kahan.cpp (revision 0)
|
---|
100 | +++ libs/accumulators/test/sum_kahan.cpp (revision 0)
|
---|
101 | @@ -0,0 +1,41 @@
|
---|
102 | +// (C) Copyright Gaetano Mendola 2010.
|
---|
103 | +// Use, modification and distribution are subject to the
|
---|
104 | +// Boost Software License, Version 1.0. (See accompanying file
|
---|
105 | +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
---|
106 | +
|
---|
107 | +#include <boost/test/unit_test.hpp>
|
---|
108 | +#include <boost/accumulators/accumulators.hpp>
|
---|
109 | +#include <boost/accumulators/statistics/stats.hpp>
|
---|
110 | +#include <boost/accumulators/statistics/sum_kahan.hpp>
|
---|
111 | +
|
---|
112 | +using namespace boost;
|
---|
113 | +using namespace unit_test;
|
---|
114 | +using namespace accumulators;
|
---|
115 | +
|
---|
116 | +///////////////////////////////////////////////////////////////////////////////
|
---|
117 | +// test_stat
|
---|
118 | +//
|
---|
119 | +void test_stat()
|
---|
120 | +{
|
---|
121 | + accumulator_set<float, stats<tag::sum_kahan> > acc;
|
---|
122 | +
|
---|
123 | + BOOST_CHECK_EQUAL(0.0f, sum_kahan(acc));
|
---|
124 | +
|
---|
125 | + for (size_t i = 0; i < 1e6; ++i) {
|
---|
126 | + acc(1e-6f);
|
---|
127 | + }
|
---|
128 | +
|
---|
129 | + BOOST_CHECK_EQUAL(1.0f, sum_kahan(acc));
|
---|
130 | +}
|
---|
131 | +
|
---|
132 | +///////////////////////////////////////////////////////////////////////////////
|
---|
133 | +// init_unit_test_suite
|
---|
134 | +//
|
---|
135 | +test_suite* init_unit_test_suite( int argc, char* argv[] )
|
---|
136 | +{
|
---|
137 | + test_suite *test = BOOST_TEST_SUITE("sum kahan test");
|
---|
138 | +
|
---|
139 | + test->add(BOOST_TEST_CASE(&test_stat));
|
---|
140 | +
|
---|
141 | + return test;
|
---|
142 | +}
|
---|
143 | Index: libs/accumulators/test/Jamfile.v2
|
---|
144 | ===================================================================
|
---|
145 | --- libs/accumulators/test/Jamfile.v2 (revision 64372)
|
---|
146 | +++ libs/accumulators/test/Jamfile.v2 (working copy)
|
---|
147 | @@ -50,6 +50,7 @@
|
---|
148 | [ run rolling_mean.cpp ]
|
---|
149 | [ run skewness.cpp ]
|
---|
150 | [ run sum.cpp ]
|
---|
151 | + [ run sum_kahan.cpp ]
|
---|
152 | [ run tail.cpp ]
|
---|
153 | [ run tail_mean.cpp ]
|
---|
154 | [ run tail_quantile.cpp ]
|
---|