]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // weighted_sum_kahan.hpp | |
3 | // | |
4 | // Copyright 2011 Simon West. Distributed under the Boost | |
5 | // Software License, Version 1.0. (See accompanying file | |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_SUM_KAHAN_HPP_EAN_11_05_2011 | |
9 | #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_SUM_KAHAN_HPP_EAN_11_05_2011 | |
10 | ||
11 | #include <boost/mpl/placeholders.hpp> | |
12 | #include <boost/accumulators/framework/accumulator_base.hpp> | |
13 | #include <boost/accumulators/framework/extractor.hpp> | |
14 | #include <boost/accumulators/numeric/functional.hpp> | |
15 | #include <boost/accumulators/framework/parameters/sample.hpp> | |
16 | #include <boost/accumulators/framework/parameters/weight.hpp> | |
17 | #include <boost/accumulators/framework/accumulators/external_accumulator.hpp> | |
18 | #include <boost/accumulators/framework/depends_on.hpp> | |
19 | #include <boost/accumulators/statistics_fwd.hpp> | |
20 | #include <boost/accumulators/statistics/weighted_sum.hpp> | |
21 | #include <boost/numeric/conversion/cast.hpp> | |
22 | ||
23 | namespace boost { namespace accumulators | |
24 | { | |
25 | ||
26 | namespace impl | |
27 | { | |
28 | #if _MSC_VER > 1400 | |
29 | # pragma float_control(push) | |
30 | # pragma float_control(precise, on) | |
31 | #endif | |
32 | ||
33 | /////////////////////////////////////////////////////////////////////////////// | |
34 | // weighted_sum_kahan_impl | |
35 | template<typename Sample, typename Weight, typename Tag> | |
36 | struct weighted_sum_kahan_impl | |
37 | : accumulator_base | |
38 | { | |
39 | typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample; | |
40 | ||
41 | // for boost::result_of | |
42 | typedef weighted_sample result_type; | |
43 | ||
44 | template<typename Args> | |
45 | weighted_sum_kahan_impl(Args const &args) | |
46 | : weighted_sum_( | |
47 | args[parameter::keyword<Tag>::get() | Sample()] * numeric::one<Weight>::value), | |
48 | compensation(boost::numeric_cast<weighted_sample>(0.0)) | |
49 | { | |
50 | } | |
51 | ||
52 | template<typename Args> | |
53 | void | |
54 | #if BOOST_ACCUMULATORS_GCC_VERSION > 40305 | |
55 | __attribute__((__optimize__("no-associative-math"))) | |
56 | #endif | |
57 | operator ()(Args const &args) | |
58 | { | |
59 | const weighted_sample myTmp1 = args[parameter::keyword<Tag>::get()] * args[weight] - this->compensation; | |
60 | const weighted_sample myTmp2 = this->weighted_sum_ + myTmp1; | |
61 | this->compensation = (myTmp2 - this->weighted_sum_) - myTmp1; | |
62 | this->weighted_sum_ = myTmp2; | |
63 | ||
64 | } | |
65 | ||
66 | result_type result(dont_care) const | |
67 | { | |
68 | return this->weighted_sum_; | |
69 | } | |
70 | ||
92f5a8d4 TL |
71 | // make this accumulator serializeable |
72 | template<class Archive> | |
73 | void serialize(Archive & ar, const unsigned int file_version) | |
74 | { | |
75 | ar & weighted_sum_; | |
76 | ar & compensation; | |
77 | } | |
78 | ||
7c673cae FG |
79 | private: |
80 | weighted_sample weighted_sum_; | |
81 | weighted_sample compensation; | |
82 | }; | |
83 | ||
84 | #if _MSC_VER > 1400 | |
85 | # pragma float_control(pop) | |
86 | #endif | |
87 | ||
88 | } // namespace impl | |
89 | ||
90 | /////////////////////////////////////////////////////////////////////////////// | |
91 | // tag::weighted_sum_kahan | |
92 | // tag::weighted_sum_of_variates_kahan | |
93 | // | |
94 | namespace tag | |
95 | { | |
96 | struct weighted_sum_kahan | |
97 | : depends_on<> | |
98 | { | |
99 | /// INTERNAL ONLY | |
100 | /// | |
101 | typedef accumulators::impl::weighted_sum_kahan_impl<mpl::_1, mpl::_2, tag::sample> impl; | |
102 | }; | |
103 | ||
104 | template<typename VariateType, typename VariateTag> | |
105 | struct weighted_sum_of_variates_kahan | |
106 | : depends_on<> | |
107 | { | |
108 | /// INTERNAL ONLY | |
109 | /// | |
110 | typedef accumulators::impl::weighted_sum_kahan_impl<VariateType, mpl::_2, VariateTag> impl; | |
111 | }; | |
112 | ||
113 | } | |
114 | ||
115 | /////////////////////////////////////////////////////////////////////////////// | |
116 | // extract::weighted_sum_kahan | |
117 | // extract::weighted_sum_of_variates_kahan | |
118 | // | |
119 | namespace extract | |
120 | { | |
121 | extractor<tag::weighted_sum_kahan> const weighted_sum_kahan = {}; | |
122 | extractor<tag::abstract_weighted_sum_of_variates> const weighted_sum_of_variates_kahan = {}; | |
123 | ||
124 | BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_sum_kahan) | |
125 | BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_sum_of_variates_kahan) | |
126 | } | |
127 | ||
128 | using extract::weighted_sum_kahan; | |
129 | using extract::weighted_sum_of_variates_kahan; | |
130 | ||
131 | // weighted_sum(kahan) -> weighted_sum_kahan | |
132 | template<> | |
133 | struct as_feature<tag::weighted_sum(kahan)> | |
134 | { | |
135 | typedef tag::weighted_sum_kahan type; | |
136 | }; | |
137 | ||
138 | template<typename VariateType, typename VariateTag> | |
139 | struct feature_of<tag::weighted_sum_of_variates_kahan<VariateType, VariateTag> > | |
140 | : feature_of<tag::abstract_weighted_sum_of_variates> | |
141 | { | |
142 | }; | |
143 | ||
144 | }} // namespace boost::accumulators | |
145 | ||
146 | #endif |