Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // covariance.hpp
0003 //
0004 //  Copyright 2006 Daniel Egloff, Olivier Gygi. 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_COVARIANCE_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_COVARIANCE_HPP_DE_01_01_2006
0010 
0011 #include <vector>
0012 #include <limits>
0013 #include <numeric>
0014 #include <functional>
0015 #include <complex>
0016 #include <boost/mpl/assert.hpp>
0017 #include <boost/mpl/bool.hpp>
0018 #include <boost/range.hpp>
0019 #include <boost/parameter/keyword.hpp>
0020 #include <boost/mpl/placeholders.hpp>
0021 #include <boost/numeric/ublas/io.hpp>
0022 #include <boost/numeric/ublas/matrix.hpp>
0023 #include <boost/type_traits/is_scalar.hpp>
0024 #include <boost/type_traits/is_same.hpp>
0025 #include <boost/accumulators/framework/accumulator_base.hpp>
0026 #include <boost/accumulators/framework/extractor.hpp>
0027 #include <boost/accumulators/numeric/functional.hpp>
0028 #include <boost/accumulators/framework/parameters/sample.hpp>
0029 #include <boost/accumulators/statistics_fwd.hpp>
0030 #include <boost/accumulators/statistics/count.hpp>
0031 #include <boost/accumulators/statistics/mean.hpp>
0032 
0033 namespace boost { namespace numeric
0034 {
0035     namespace functional
0036     {
0037         struct std_vector_tag;
0038 
0039         ///////////////////////////////////////////////////////////////////////////////
0040         // functional::outer_product
0041         template<typename Left, typename Right, typename EnableIf = void>
0042         struct outer_product_base
0043           : functional::multiplies<Left, Right>
0044         {};
0045 
0046         template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
0047         struct outer_product
0048           : outer_product_base<Left, Right, void>
0049         {};
0050 
0051         template<typename Left, typename Right>
0052         struct outer_product<Left, Right, std_vector_tag, std_vector_tag>
0053         {
0054             typedef Left first_argument_type;
0055             typedef Right second_argument_type;
0056             typedef
0057                 ublas::matrix<
0058                     typename functional::multiplies<
0059                         typename Left::value_type
0060                       , typename Right::value_type
0061                     >::result_type
0062                 >
0063             result_type;
0064 
0065             result_type
0066             operator ()(Left & left, Right & right) const
0067             {
0068                 std::size_t left_size = left.size();
0069                 std::size_t right_size = right.size();
0070                 result_type result(left_size, right_size);
0071                 for (std::size_t i = 0; i < left_size; ++i)
0072                     for (std::size_t j = 0; j < right_size; ++j)
0073                         result(i,j) = numeric::multiplies(left[i], right[j]);
0074                 return result;
0075             }
0076         };
0077     }
0078 
0079     namespace op
0080     {
0081         struct outer_product
0082           : boost::detail::function2<functional::outer_product<_1, _2, functional::tag<_1>, functional::tag<_2> > >
0083         {};
0084     }
0085 
0086     namespace
0087     {
0088         op::outer_product const &outer_product = boost::detail::pod_singleton<op::outer_product>::instance;
0089     }
0090 
0091 }}
0092 
0093 namespace boost { namespace accumulators
0094 {
0095 
0096 namespace impl
0097 {
0098     ///////////////////////////////////////////////////////////////////////////////
0099     // covariance_impl
0100     //
0101     /**
0102         @brief Covariance Estimator
0103 
0104         An iterative Monte Carlo estimator for the covariance \f$\mathrm{Cov}(X,X')\f$, where \f$X\f$ is a sample
0105         and \f$X'\f$ is a variate, is given by:
0106 
0107         \f[
0108             \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,
0109         \f]
0110 
0111         \f$\hat{\mu}_n\f$ and \f$\hat{\mu}_n'\f$ being the means of the samples and variates.
0112     */
0113     template<typename Sample, typename VariateType, typename VariateTag>
0114     struct covariance_impl
0115       : accumulator_base
0116     {
0117         typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type sample_type;
0118         typedef typename numeric::functional::fdiv<VariateType, std::size_t>::result_type variate_type;
0119         // for boost::result_of
0120         typedef typename numeric::functional::outer_product<sample_type, variate_type>::result_type result_type;
0121 
0122         template<typename Args>
0123         covariance_impl(Args const &args)
0124           : cov_(
0125                 numeric::outer_product(
0126                     numeric::fdiv(args[sample | Sample()], (std::size_t)1)
0127                   , numeric::fdiv(args[parameter::keyword<VariateTag>::get() | VariateType()], (std::size_t)1)
0128                 )
0129             )
0130         {
0131         }
0132 
0133         template<typename Args>
0134         void operator ()(Args const &args)
0135         {
0136             std::size_t cnt = count(args);
0137 
0138             if (cnt > 1)
0139             {
0140                 extractor<tag::mean_of_variates<VariateType, VariateTag> > const some_mean_of_variates = {};
0141 
0142                 this->cov_ = this->cov_*(cnt-1.)/cnt
0143                            + numeric::outer_product(
0144                                  some_mean_of_variates(args) - args[parameter::keyword<VariateTag>::get()]
0145                                , mean(args) - args[sample]
0146                              ) / (cnt-1.);
0147             }
0148         }
0149 
0150         result_type result(dont_care) const
0151         {
0152             return this->cov_;
0153         }
0154 
0155         // make this accumulator serializeable
0156         template<class Archive>
0157         void serialize(Archive & ar, const unsigned int file_version)
0158         { 
0159             ar & cov_;
0160         }
0161 
0162     private:
0163         result_type cov_;
0164     };
0165 
0166 } // namespace impl
0167 
0168 ///////////////////////////////////////////////////////////////////////////////
0169 // tag::covariance
0170 //
0171 namespace tag
0172 {
0173     template<typename VariateType, typename VariateTag>
0174     struct covariance
0175       : depends_on<count, mean, mean_of_variates<VariateType, VariateTag> >
0176     {
0177         typedef accumulators::impl::covariance_impl<mpl::_1, VariateType, VariateTag> impl;
0178     };
0179 
0180     struct abstract_covariance
0181       : depends_on<>
0182     {
0183     };
0184 }
0185 
0186 ///////////////////////////////////////////////////////////////////////////////
0187 // extract::covariance
0188 //
0189 namespace extract
0190 {
0191     extractor<tag::abstract_covariance> const covariance = {};
0192 
0193     BOOST_ACCUMULATORS_IGNORE_GLOBAL(covariance)
0194 }
0195 
0196 using extract::covariance;
0197 
0198 template<typename VariateType, typename VariateTag>
0199 struct feature_of<tag::covariance<VariateType, VariateTag> >
0200   : feature_of<tag::abstract_covariance>
0201 {
0202 };
0203 
0204 // So that covariance can be automatically substituted with
0205 // weighted_covariance when the weight parameter is non-void.
0206 template<typename VariateType, typename VariateTag>
0207 struct as_weighted_feature<tag::covariance<VariateType, VariateTag> >
0208 {
0209     typedef tag::weighted_covariance<VariateType, VariateTag> type;
0210 };
0211 
0212 template<typename VariateType, typename VariateTag>
0213 struct feature_of<tag::weighted_covariance<VariateType, VariateTag> >
0214   : feature_of<tag::covariance<VariateType, VariateTag> >
0215 {};
0216 
0217 }} // namespace boost::accumulators
0218 
0219 #endif