Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // 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_COVARIANCE_HPP_DE_01_01_2006 Chris@16: #define BOOST_ACCUMULATORS_STATISTICS_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 Chris@16: Chris@16: namespace boost { namespace numeric Chris@16: { Chris@16: namespace functional Chris@16: { Chris@16: struct std_vector_tag; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // functional::outer_product Chris@16: template Chris@16: struct outer_product_base Chris@16: : functional::multiplies Chris@16: {}; Chris@16: Chris@16: template::type, typename RightTag = typename tag::type> Chris@16: struct outer_product Chris@16: : outer_product_base Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct outer_product Chris@16: : std::binary_function< Chris@16: Left Chris@16: , Right Chris@16: , ublas::matrix< Chris@16: typename functional::multiplies< Chris@16: typename Left::value_type Chris@16: , typename Right::value_type Chris@16: >::result_type Chris@16: > Chris@16: > Chris@16: { Chris@16: typedef Chris@16: ublas::matrix< Chris@16: typename functional::multiplies< Chris@16: typename Left::value_type Chris@16: , typename Right::value_type Chris@16: >::result_type Chris@16: > Chris@16: result_type; Chris@16: Chris@16: result_type Chris@16: operator ()(Left & left, Right & right) const Chris@16: { Chris@16: std::size_t left_size = left.size(); Chris@16: std::size_t right_size = right.size(); Chris@16: result_type result(left_size, right_size); Chris@16: for (std::size_t i = 0; i < left_size; ++i) Chris@16: for (std::size_t j = 0; j < right_size; ++j) Chris@16: result(i,j) = numeric::multiplies(left[i], right[j]); Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: namespace op Chris@16: { Chris@16: struct outer_product Chris@16: : boost::detail::function2, functional::tag<_2> > > Chris@16: {}; Chris@16: } Chris@16: Chris@16: namespace Chris@16: { Chris@16: op::outer_product const &outer_product = boost::detail::pod_singleton::instance; Chris@16: } Chris@16: Chris@16: }} Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@16: Chris@16: namespace impl Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // covariance_impl Chris@16: // Chris@16: /** Chris@16: @brief Covariance Estimator Chris@16: Chris@16: An iterative Monte Carlo estimator for the covariance \f$\mathrm{Cov}(X,X')\f$, where \f$X\f$ is a sample Chris@16: and \f$X'\f$ is a variate, is given by: Chris@16: Chris@16: \f[ Chris@16: \hat{c}_n = \frac{n-1}{n} \hat{c}_{n-1} + \frac{1}{n-1}(X_n - \hat{\mu}_n)(X_n' - \hat{\mu}_n'),\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 means of the samples and variates. Chris@16: */ Chris@16: template Chris@16: struct covariance_impl Chris@16: : accumulator_base Chris@16: { Chris@16: typedef typename numeric::functional::fdiv::result_type sample_type; Chris@16: typedef typename numeric::functional::fdiv::result_type 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: 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::fdiv(args[parameter::keyword::get() | VariateType()], (std::size_t)1) 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_mean_of_variates = {}; Chris@16: Chris@16: this->cov_ = this->cov_*(cnt-1.)/cnt Chris@16: + numeric::outer_product( Chris@16: some_mean_of_variates(args) - args[parameter::keyword::get()] Chris@16: , mean(args) - args[sample] Chris@16: ) / (cnt-1.); 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::covariance Chris@16: // Chris@16: namespace tag Chris@16: { Chris@16: template Chris@16: struct covariance Chris@16: : depends_on > Chris@16: { Chris@16: typedef accumulators::impl::covariance_impl impl; Chris@16: }; Chris@16: Chris@16: struct abstract_covariance Chris@16: : depends_on<> Chris@16: { Chris@16: }; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // extract::covariance Chris@16: // Chris@16: namespace extract Chris@16: { Chris@16: extractor const covariance = {}; Chris@16: Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(covariance) Chris@16: } Chris@16: Chris@16: using extract::covariance; Chris@16: Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of Chris@16: { Chris@16: }; Chris@16: Chris@16: // So that covariance can be automatically substituted with Chris@16: // weighted_covariance when the weight parameter is non-void. Chris@16: template Chris@16: struct as_weighted_feature > Chris@16: { Chris@16: typedef tag::weighted_covariance type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of > Chris@16: {}; Chris@16: Chris@16: }} // namespace boost::accumulators Chris@16: Chris@16: #endif