Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:22

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // weighted_variance.hpp
0003 //
0004 //  Copyright 2005 Daniel Egloff, Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_VARIANCE_HPP_EAN_28_10_2005
0009 #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_VARIANCE_HPP_EAN_28_10_2005
0010 
0011 #include <boost/mpl/placeholders.hpp>
0012 #include <boost/accumulators/framework/accumulator_base.hpp>
0013 #include <boost/accumulators/framework/extractor.hpp>
0014 #include <boost/accumulators/numeric/functional.hpp>
0015 #include <boost/accumulators/framework/parameters/sample.hpp>
0016 #include <boost/accumulators/framework/depends_on.hpp>
0017 #include <boost/accumulators/statistics_fwd.hpp>
0018 #include <boost/accumulators/statistics/count.hpp>
0019 #include <boost/accumulators/statistics/variance.hpp>
0020 #include <boost/accumulators/statistics/weighted_sum.hpp>
0021 #include <boost/accumulators/statistics/weighted_mean.hpp>
0022 #include <boost/accumulators/statistics/weighted_moment.hpp>
0023 
0024 namespace boost { namespace accumulators
0025 {
0026 
0027 namespace impl
0028 {
0029     //! Lazy calculation of variance of weighted samples.
0030     /*!
0031         The default implementation of the variance of weighted samples is based on the second moment
0032         \f$\widehat{m}_n^{(2)}\f$ (weighted_moment<2>) and the mean\f$ \hat{\mu}_n\f$ (weighted_mean):
0033         \f[
0034             \hat{\sigma}_n^2 = \widehat{m}_n^{(2)}-\hat{\mu}_n^2,
0035         \f]
0036         where \f$n\f$ is the number of samples.
0037     */
0038     template<typename Sample, typename Weight, typename MeanFeature>
0039     struct lazy_weighted_variance_impl
0040       : accumulator_base
0041     {
0042         typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
0043         // for boost::result_of
0044         typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
0045 
0046         lazy_weighted_variance_impl(dont_care) {}
0047 
0048         template<typename Args>
0049         result_type result(Args const &args) const
0050         {
0051             extractor<MeanFeature> const some_mean = {};
0052             result_type tmp = some_mean(args);
0053             return accumulators::weighted_moment<2>(args) - tmp * tmp;
0054         }
0055     };
0056 
0057     //! Iterative calculation of variance of weighted samples.
0058     /*!
0059         Iterative calculation of variance of weighted samples:
0060         \f[
0061             \hat{\sigma}_n^2 =
0062                 \frac{\bar{w}_n - w_n}{\bar{w}_n}\hat{\sigma}_{n - 1}^2
0063               + \frac{w_n}{\bar{w}_n - w_n}\left(X_n - \hat{\mu}_n\right)^2
0064             ,\quad n\ge2,\quad\hat{\sigma}_0^2 = 0.
0065         \f]
0066         where \f$\bar{w}_n\f$ is the sum of the \f$n\f$ weights \f$w_i\f$ and \f$\hat{\mu}_n\f$
0067         the estimate of the mean of the weighted samples. Note that the sample variance is not defined for
0068         \f$n <= 1\f$.
0069     */
0070     template<typename Sample, typename Weight, typename MeanFeature, typename Tag>
0071     struct weighted_variance_impl
0072       : accumulator_base
0073     {
0074         typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
0075         // for boost::result_of
0076         typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
0077 
0078         template<typename Args>
0079         weighted_variance_impl(Args const &args)
0080           : weighted_variance(numeric::fdiv(args[sample | Sample()], numeric::one<Weight>::value))
0081         {
0082         }
0083 
0084         template<typename Args>
0085         void operator ()(Args const &args)
0086         {
0087             std::size_t cnt = count(args);
0088 
0089             if(cnt > 1)
0090             {
0091                 extractor<MeanFeature> const some_mean = {};
0092 
0093                 result_type tmp = args[parameter::keyword<Tag>::get()] - some_mean(args);
0094 
0095                 this->weighted_variance =
0096                     numeric::fdiv(this->weighted_variance * (sum_of_weights(args) - args[weight]), sum_of_weights(args))
0097                   + numeric::fdiv(tmp * tmp * args[weight], sum_of_weights(args) - args[weight] );
0098             }
0099         }
0100 
0101         result_type result(dont_care) const
0102         {
0103             return this->weighted_variance;
0104         }
0105 
0106         // make this accumulator serializeable
0107         template<class Archive>
0108         void serialize(Archive & ar, const unsigned int file_version)
0109         {
0110             ar & weighted_variance;
0111         }
0112 
0113     private:
0114         result_type weighted_variance;
0115     };
0116 
0117 } // namespace impl
0118 
0119 ///////////////////////////////////////////////////////////////////////////////
0120 // tag::weighted_variance
0121 // tag::immediate_weighted_variance
0122 //
0123 namespace tag
0124 {
0125     struct lazy_weighted_variance
0126       : depends_on<weighted_moment<2>, weighted_mean>
0127     {
0128         /// INTERNAL ONLY
0129         ///
0130         typedef accumulators::impl::lazy_weighted_variance_impl<mpl::_1, mpl::_2, weighted_mean> impl;
0131     };
0132 
0133     struct weighted_variance
0134       : depends_on<count, immediate_weighted_mean>
0135     {
0136         /// INTERNAL ONLY
0137         ///
0138         typedef accumulators::impl::weighted_variance_impl<mpl::_1, mpl::_2, immediate_weighted_mean, sample> impl;
0139     };
0140 }
0141 
0142 ///////////////////////////////////////////////////////////////////////////////
0143 // extract::weighted_variance
0144 // extract::immediate_weighted_variance
0145 //
0146 namespace extract
0147 {
0148     extractor<tag::lazy_weighted_variance> const lazy_weighted_variance = {};
0149     extractor<tag::weighted_variance> const weighted_variance = {};
0150 
0151     BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_weighted_variance)
0152     BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_variance)
0153 }
0154 
0155 using extract::lazy_weighted_variance;
0156 using extract::weighted_variance;
0157 
0158 // weighted_variance(lazy) -> lazy_weighted_variance
0159 template<>
0160 struct as_feature<tag::weighted_variance(lazy)>
0161 {
0162     typedef tag::lazy_weighted_variance type;
0163 };
0164 
0165 // weighted_variance(immediate) -> weighted_variance
0166 template<>
0167 struct as_feature<tag::weighted_variance(immediate)>
0168 {
0169     typedef tag::weighted_variance type;
0170 };
0171 
0172 ////////////////////////////////////////////////////////////////////////////
0173 //// droppable_accumulator<weighted_variance_impl>
0174 ////  need to specialize droppable lazy weighted_variance to cache the result at the
0175 ////  point the accumulator is dropped.
0176 ///// INTERNAL ONLY
0177 /////
0178 //template<typename Sample, typename Weight, typename MeanFeature>
0179 //struct droppable_accumulator<impl::weighted_variance_impl<Sample, Weight, MeanFeature> >
0180 //  : droppable_accumulator_base<
0181 //        with_cached_result<impl::weighted_variance_impl<Sample, Weight, MeanFeature> >
0182 //    >
0183 //{
0184 //    template<typename Args>
0185 //    droppable_accumulator(Args const &args)
0186 //      : droppable_accumulator::base(args)
0187 //    {
0188 //    }
0189 //};
0190 
0191 }} // namespace boost::accumulators
0192 
0193 #endif