File indexing completed on 2025-01-18 09:28:19
0001
0002
0003
0004
0005
0006
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
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
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
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
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
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 }
0167
0168
0169
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
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
0205
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 }}
0218
0219 #endif