Statistics
| Revision:

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__("no-associative-math")))
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 non-void.
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 feature-based 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 feature-based 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