Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // weighted_sum_kahan.hpp Chris@16: // Chris@16: // Copyright 2011 Simon West. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_SUM_KAHAN_HPP_EAN_11_05_2011 Chris@16: #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_SUM_KAHAN_HPP_EAN_11_05_2011 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@16: Chris@16: namespace impl Chris@16: { Chris@16: #if _MSC_VER > 1400 Chris@16: # pragma float_control(push) Chris@16: # pragma float_control(precise, on) Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // weighted_sum_kahan_impl Chris@16: template Chris@16: struct weighted_sum_kahan_impl Chris@16: : accumulator_base Chris@16: { Chris@16: typedef typename numeric::functional::multiplies::result_type weighted_sample; Chris@16: Chris@16: // for boost::result_of Chris@16: typedef weighted_sample result_type; Chris@16: Chris@16: template Chris@16: weighted_sum_kahan_impl(Args const &args) Chris@16: : weighted_sum_( Chris@16: args[parameter::keyword::get() | Sample()] * numeric::one::value), Chris@16: compensation(boost::numeric_cast(0.0)) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: void Chris@16: #if BOOST_ACCUMULATORS_GCC_VERSION > 40305 Chris@16: __attribute__((__optimize__("no-associative-math"))) Chris@16: #endif Chris@16: operator ()(Args const &args) Chris@16: { Chris@16: const weighted_sample myTmp1 = args[parameter::keyword::get()] * args[weight] - this->compensation; Chris@16: const weighted_sample myTmp2 = this->weighted_sum_ + myTmp1; Chris@16: this->compensation = (myTmp2 - this->weighted_sum_) - myTmp1; Chris@16: this->weighted_sum_ = myTmp2; Chris@16: Chris@16: } Chris@16: Chris@16: result_type result(dont_care) const Chris@16: { Chris@16: return this->weighted_sum_; Chris@16: } Chris@16: Chris@16: private: Chris@16: weighted_sample weighted_sum_; Chris@16: weighted_sample compensation; Chris@16: }; Chris@16: Chris@16: #if _MSC_VER > 1400 Chris@16: # pragma float_control(pop) Chris@16: #endif Chris@16: Chris@16: } // namespace impl Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tag::weighted_sum_kahan Chris@16: // tag::weighted_sum_of_variates_kahan Chris@16: // Chris@16: namespace tag Chris@16: { Chris@16: struct weighted_sum_kahan Chris@16: : depends_on<> Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: typedef accumulators::impl::weighted_sum_kahan_impl impl; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct weighted_sum_of_variates_kahan Chris@16: : depends_on<> Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: typedef accumulators::impl::weighted_sum_kahan_impl impl; Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // extract::weighted_sum_kahan Chris@16: // extract::weighted_sum_of_variates_kahan Chris@16: // Chris@16: namespace extract Chris@16: { Chris@16: extractor const weighted_sum_kahan = {}; Chris@16: extractor const weighted_sum_of_variates_kahan = {}; Chris@16: Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_sum_kahan) Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_sum_of_variates_kahan) Chris@16: } Chris@16: Chris@16: using extract::weighted_sum_kahan; Chris@16: using extract::weighted_sum_of_variates_kahan; Chris@16: Chris@16: // weighted_sum(kahan) -> weighted_sum_kahan Chris@16: template<> Chris@16: struct as_feature Chris@16: { Chris@16: typedef tag::weighted_sum_kahan type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of Chris@16: { Chris@16: }; Chris@16: Chris@16: }} // namespace boost::accumulators Chris@16: Chris@16: #endif