Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // weighted_covariance.hpp Chris@16: // Chris@16: // Copyright 2006 Daniel Egloff, Olivier Gygi. 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_COVARIANCE_HPP_DE_01_01_2006 Chris@16: #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_COVARIANCE_HPP_DE_01_01_2006 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: #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 // for numeric::outer_product() and type traits Chris@16: #include Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@16: Chris@16: namespace impl Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // weighted_covariance_impl Chris@16: // Chris@16: /** Chris@16: @brief Weighted Covariance Estimator Chris@16: Chris@16: An iterative Monte Carlo estimator for the weighted covariance \f$\mathrm{Cov}(X,X')\f$, where \f$X\f$ is a sample Chris@16: and \f$X'\f$ a variate, is given by: Chris@16: Chris@16: \f[ Chris@16: \hat{c}_n = \frac{\bar{w}_n-w_n}{\bar{w}_n} \hat{c}_{n-1} + \frac{w_n}{\bar{w}_n-w_n}(X_n - \hat{\mu}_n)(X_n' - \hat{\mu}_n'), Chris@16: \quad n\ge2,\quad\hat{c}_1 = 0, Chris@16: \f] Chris@16: Chris@16: \f$\hat{\mu}_n\f$ and \f$\hat{\mu}_n'\f$ being the weighted means of the samples and variates and Chris@16: \f$\bar{w}_n\f$ the sum of the \f$n\f$ first weights \f$w_i\f$. Chris@16: */ Chris@16: template Chris@16: struct weighted_covariance_impl Chris@16: : accumulator_base Chris@16: { Chris@16: typedef typename numeric::functional::multiplies::result_type>::result_type weighted_sample_type; Chris@16: typedef typename numeric::functional::multiplies::result_type>::result_type weighted_variate_type; Chris@16: // for boost::result_of Chris@16: typedef typename numeric::functional::outer_product::result_type result_type; Chris@16: Chris@16: template Chris@16: weighted_covariance_impl(Args const &args) Chris@16: : cov_( Chris@16: numeric::outer_product( Chris@16: numeric::fdiv(args[sample | Sample()], (std::size_t)1) Chris@16: * numeric::one::value Chris@16: , numeric::fdiv(args[parameter::keyword::get() | VariateType()], (std::size_t)1) Chris@16: * numeric::one::value Chris@16: ) Chris@16: ) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: void operator ()(Args const &args) Chris@16: { Chris@16: std::size_t cnt = count(args); Chris@16: Chris@16: if (cnt > 1) Chris@16: { Chris@16: extractor > const some_weighted_mean_of_variates = {}; Chris@16: Chris@16: this->cov_ = this->cov_ * (sum_of_weights(args) - args[weight]) / sum_of_weights(args) Chris@16: + numeric::outer_product( Chris@16: some_weighted_mean_of_variates(args) - args[parameter::keyword::get()] Chris@16: , weighted_mean(args) - args[sample] Chris@16: ) * args[weight] / (sum_of_weights(args) - args[weight]); Chris@16: } Chris@16: } Chris@16: Chris@16: result_type result(dont_care) const Chris@16: { Chris@16: return this->cov_; Chris@16: } Chris@16: Chris@16: private: Chris@16: result_type cov_; Chris@16: }; Chris@16: Chris@16: } // namespace impl Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tag::weighted_covariance Chris@16: // Chris@16: namespace tag Chris@16: { Chris@16: template Chris@16: struct weighted_covariance Chris@16: : depends_on > Chris@16: { Chris@16: typedef accumulators::impl::weighted_covariance_impl impl; Chris@16: }; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // extract::weighted_covariance Chris@16: // Chris@16: namespace extract Chris@16: { Chris@16: extractor const weighted_covariance = {}; Chris@16: Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_covariance) Chris@16: } Chris@16: Chris@16: using extract::weighted_covariance; Chris@16: Chris@16: }} // namespace boost::accumulators Chris@16: Chris@16: #endif