root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / accumulators / statistics / sum_kahan.hpp @ 2486
History  View  Annotate  Download (4.8 kB)
1 
///////////////////////////////////////////////////////////////////////////////


2 
// sum_kahan.hpp

3 
//

4 
// Copyright 2010 Gaetano Mendola, 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_SUM_KAHAN_HPP_EAN_26_07_2010

9 
#define BOOST_ACCUMULATORS_STATISTICS_SUM_KAHAN_HPP_EAN_26_07_2010

10  
11 
#include <boost/accumulators/framework/accumulator_base.hpp> 
12 
#include <boost/accumulators/framework/parameters/sample.hpp> 
13 
#include <boost/accumulators/statistics_fwd.hpp> 
14 
#include <boost/accumulators/statistics/sum.hpp> 
15 
#include <boost/accumulators/statistics/weighted_sum_kahan.hpp> 
16 
#include <boost/numeric/conversion/cast.hpp> 
17  
18 
namespace boost { namespace accumulators 
19 
{ 
20  
21 
namespace impl

22 
{ 
23  
24 
#if _MSC_VER > 1400 
25 
# pragma float_control(push)

26 
# pragma float_control(precise, on)

27 
#endif

28  
29 
template<typename Sample, typename Tag> 
30 
struct sum_kahan_impl

31 
: accumulator_base 
32 
{ 
33 
typedef Sample result_type;

34  
35 
////////////////////////////////////////////////////////////////////////////

36 
// sum_kahan_impl

37 
/**

38 
@brief Kahan summation algorithm

39 

40 
The Kahan summation algorithm reduces the numerical error obtained with standard

41 
sequential sum.

42 

43 
*/

44 
template<typename Args> 
45 
sum_kahan_impl(Args const & args)

46 
: sum(args[parameter::keyword<Tag>::get()  Sample()]), 
47 
compensation(boost::numeric_cast<Sample>(0.0)) 
48 
{ 
49 
} 
50  
51 
template<typename Args> 
52 
void

53 
#if BOOST_ACCUMULATORS_GCC_VERSION > 40305 
54 
__attribute__((__optimize__("noassociativemath")))

55 
#endif

56 
operator ()(Args const & args) 
57 
{ 
58 
const Sample myTmp1 = args[parameter::keyword<Tag>::get()]  this>compensation; 
59 
const Sample myTmp2 = this>sum + myTmp1; 
60 
this>compensation = (myTmp2  this>sum)  myTmp1; 
61 
this>sum = myTmp2;

62 
} 
63  
64 
result_type result(dont_care) const

65 
{ 
66 
return this>sum; 
67 
} 
68  
69 
private:

70 
Sample sum; 
71 
Sample compensation; 
72 
}; 
73  
74 
#if _MSC_VER > 1400 
75 
# pragma float_control(pop)

76 
#endif

77  
78 
} // namespace impl

79  
80 
///////////////////////////////////////////////////////////////////////////////

81 
// tag::sum_kahan

82 
// tag::sum_of_weights_kahan

83 
// tag::sum_of_variates_kahan

84 
//

85 
namespace tag

86 
{ 
87  
88 
struct sum_kahan

89 
: depends_on<> 
90 
{ 
91 
/// INTERNAL ONLY

92 
///

93 
typedef impl::sum_kahan_impl< mpl::_1, tag::sample > impl;

94 
}; 
95  
96 
struct sum_of_weights_kahan

97 
: depends_on<> 
98 
{ 
99 
typedef mpl::true_ is_weight_accumulator;

100 
/// INTERNAL ONLY

101 
///

102 
typedef accumulators::impl::sum_kahan_impl<mpl::_2, tag::weight> impl;

103 
}; 
104  
105 
template<typename VariateType, typename VariateTag> 
106 
struct sum_of_variates_kahan

107 
: depends_on<> 
108 
{ 
109 
/// INTERNAL ONLY

110 
///

111 
typedef mpl::always<accumulators::impl::sum_kahan_impl<VariateType, VariateTag> > impl;

112 
}; 
113  
114 
} // namespace tag

115  
116 
///////////////////////////////////////////////////////////////////////////////

117 
// extract::sum_kahan

118 
// extract::sum_of_weights_kahan

119 
// extract::sum_of_variates_kahan

120 
//

121 
namespace extract

122 
{ 
123 
extractor<tag::sum_kahan> const sum_kahan = {};

124 
extractor<tag::sum_of_weights_kahan> const sum_of_weights_kahan = {};

125 
extractor<tag::abstract_sum_of_variates> const sum_of_variates_kahan = {};

126  
127 
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_kahan) 
128 
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_of_weights_kahan) 
129 
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_of_variates_kahan) 
130 
} // namespace extract

131  
132 
using extract::sum_kahan;

133 
using extract::sum_of_weights_kahan;

134 
using extract::sum_of_variates_kahan;

135  
136 
// sum(kahan) > sum_kahan

137 
template<>

138 
struct as_feature<tag::sum(kahan)>

139 
{ 
140 
typedef tag::sum_kahan type;

141 
}; 
142  
143 
// sum_of_weights(kahan) > sum_of_weights_kahan

144 
template<>

145 
struct as_feature<tag::sum_of_weights(kahan)>

146 
{ 
147 
typedef tag::sum_of_weights_kahan type;

148 
}; 
149  
150 
// So that sum_kahan can be automatically substituted with

151 
// weighted_sum_kahan when the weight parameter is nonvoid.

152 
template<>

153 
struct as_weighted_feature<tag::sum_kahan>

154 
{ 
155 
typedef tag::weighted_sum_kahan type;

156 
}; 
157  
158 
template<>

159 
struct feature_of<tag::weighted_sum_kahan>

160 
: feature_of<tag::sum> 
161 
{}; 
162  
163 
// for the purposes of featurebased dependency resolution,

164 
// sum_kahan provides the same feature as sum

165 
template<>

166 
struct feature_of<tag::sum_kahan>

167 
: feature_of<tag::sum> 
168 
{ 
169 
}; 
170  
171 
// for the purposes of featurebased dependency resolution,

172 
// sum_of_weights_kahan provides the same feature as sum_of_weights

173 
template<>

174 
struct feature_of<tag::sum_of_weights_kahan>

175 
: feature_of<tag::sum_of_weights> 
176 
{ 
177 
}; 
178  
179 
template<typename VariateType, typename VariateTag> 
180 
struct feature_of<tag::sum_of_variates_kahan<VariateType, VariateTag> >

181 
: feature_of<tag::abstract_sum_of_variates> 
182 
{ 
183 
}; 
184  
185 
}} // namespace boost::accumulators

186  
187 
#endif

188 