annotate DEPENDENCIES/generic/include/boost/accumulators/statistics/extended_p_square_quantile.hpp @ 91:e2e7672ea759

Some absolute paths
author Chris Cannam
date Tue, 14 Apr 2015 11:32:55 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 // extended_p_square_quantile.hpp
Chris@16 3 //
Chris@16 4 // Copyright 2005 Daniel Egloff. Distributed under the Boost
Chris@16 5 // Software License, Version 1.0. (See accompanying file
Chris@16 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 #ifndef BOOST_ACCUMULATORS_STATISTICS_EXTENDED_SINGLE_QUANTILE_HPP_DE_01_01_2006
Chris@16 9 #define BOOST_ACCUMULATORS_STATISTICS_EXTENDED_SINGLE_QUANTILE_HPP_DE_01_01_2006
Chris@16 10
Chris@16 11 #include <vector>
Chris@16 12 #include <functional>
Chris@16 13 #include <boost/throw_exception.hpp>
Chris@16 14 #include <boost/range/begin.hpp>
Chris@16 15 #include <boost/range/end.hpp>
Chris@16 16 #include <boost/range/iterator_range.hpp>
Chris@16 17 #include <boost/iterator/transform_iterator.hpp>
Chris@16 18 #include <boost/iterator/counting_iterator.hpp>
Chris@16 19 #include <boost/iterator/permutation_iterator.hpp>
Chris@16 20 #include <boost/parameter/keyword.hpp>
Chris@16 21 #include <boost/mpl/placeholders.hpp>
Chris@16 22 #include <boost/type_traits/is_same.hpp>
Chris@16 23 #include <boost/accumulators/framework/accumulator_base.hpp>
Chris@16 24 #include <boost/accumulators/framework/extractor.hpp>
Chris@16 25 #include <boost/accumulators/numeric/functional.hpp>
Chris@16 26 #include <boost/accumulators/framework/parameters/sample.hpp>
Chris@16 27 #include <boost/accumulators/framework/depends_on.hpp>
Chris@16 28 #include <boost/accumulators/statistics_fwd.hpp>
Chris@16 29 #include <boost/accumulators/statistics/count.hpp>
Chris@16 30 #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
Chris@16 31 #include <boost/accumulators/statistics/extended_p_square.hpp>
Chris@16 32 #include <boost/accumulators/statistics/weighted_extended_p_square.hpp>
Chris@16 33 #include <boost/accumulators/statistics/times2_iterator.hpp>
Chris@16 34
Chris@16 35 #ifdef _MSC_VER
Chris@16 36 # pragma warning(push)
Chris@16 37 # pragma warning(disable: 4127) // conditional expression is constant
Chris@16 38 #endif
Chris@16 39
Chris@16 40 namespace boost { namespace accumulators
Chris@16 41 {
Chris@16 42
Chris@16 43 namespace impl
Chris@16 44 {
Chris@16 45 ///////////////////////////////////////////////////////////////////////////////
Chris@16 46 // extended_p_square_quantile_impl
Chris@16 47 // single quantile estimation
Chris@16 48 /**
Chris@16 49 @brief Quantile estimation using the extended \f$P^2\f$ algorithm for weighted and unweighted samples
Chris@16 50
Chris@16 51 Uses the quantile estimates calculated by the extended \f$P^2\f$ algorithm to compute
Chris@16 52 intermediate quantile estimates by means of quadratic interpolation.
Chris@16 53
Chris@16 54 @param quantile_probability The probability of the quantile to be estimated.
Chris@16 55 */
Chris@16 56 template<typename Sample, typename Impl1, typename Impl2> // Impl1: weighted/unweighted // Impl2: linear/quadratic
Chris@16 57 struct extended_p_square_quantile_impl
Chris@16 58 : accumulator_base
Chris@16 59 {
Chris@16 60 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
Chris@16 61 typedef std::vector<float_type> array_type;
Chris@16 62 typedef iterator_range<
Chris@16 63 detail::lvalue_index_iterator<
Chris@16 64 permutation_iterator<
Chris@16 65 typename array_type::const_iterator
Chris@16 66 , detail::times2_iterator
Chris@16 67 >
Chris@16 68 >
Chris@16 69 > range_type;
Chris@16 70 // for boost::result_of
Chris@16 71 typedef float_type result_type;
Chris@16 72
Chris@16 73 template<typename Args>
Chris@16 74 extended_p_square_quantile_impl(Args const &args)
Chris@16 75 : probabilities(
Chris@16 76 boost::begin(args[extended_p_square_probabilities])
Chris@16 77 , boost::end(args[extended_p_square_probabilities])
Chris@16 78 )
Chris@16 79 {
Chris@16 80 }
Chris@16 81
Chris@16 82 template<typename Args>
Chris@16 83 result_type result(Args const &args) const
Chris@16 84 {
Chris@16 85 typedef
Chris@16 86 typename mpl::if_<
Chris@16 87 is_same<Impl1, weighted>
Chris@16 88 , tag::weighted_extended_p_square
Chris@16 89 , tag::extended_p_square
Chris@16 90 >::type
Chris@16 91 extended_p_square_tag;
Chris@16 92
Chris@16 93 extractor<extended_p_square_tag> const some_extended_p_square = {};
Chris@16 94
Chris@16 95 array_type heights(some_extended_p_square(args).size());
Chris@16 96 std::copy(some_extended_p_square(args).begin(), some_extended_p_square(args).end(), heights.begin());
Chris@16 97
Chris@16 98 this->probability = args[quantile_probability];
Chris@16 99
Chris@16 100 typename array_type::const_iterator iter_probs = std::lower_bound(this->probabilities.begin(), this->probabilities.end(), this->probability);
Chris@16 101 std::size_t dist = std::distance(this->probabilities.begin(), iter_probs);
Chris@16 102 typename array_type::const_iterator iter_heights = heights.begin() + dist;
Chris@16 103
Chris@16 104 // If this->probability is not in a valid range return NaN or throw exception
Chris@16 105 if (this->probability < *this->probabilities.begin() || this->probability > *(this->probabilities.end() - 1))
Chris@16 106 {
Chris@16 107 if (std::numeric_limits<result_type>::has_quiet_NaN)
Chris@16 108 {
Chris@16 109 return std::numeric_limits<result_type>::quiet_NaN();
Chris@16 110 }
Chris@16 111 else
Chris@16 112 {
Chris@16 113 std::ostringstream msg;
Chris@16 114 msg << "probability = " << this->probability << " is not in valid range (";
Chris@16 115 msg << *this->probabilities.begin() << ", " << *(this->probabilities.end() - 1) << ")";
Chris@16 116 boost::throw_exception(std::runtime_error(msg.str()));
Chris@16 117 return Sample(0);
Chris@16 118 }
Chris@16 119
Chris@16 120 }
Chris@16 121
Chris@16 122 if (*iter_probs == this->probability)
Chris@16 123 {
Chris@16 124 return heights[dist];
Chris@16 125 }
Chris@16 126 else
Chris@16 127 {
Chris@16 128 result_type res;
Chris@16 129
Chris@16 130 if (is_same<Impl2, linear>::value)
Chris@16 131 {
Chris@16 132 /////////////////////////////////////////////////////////////////////////////////
Chris@16 133 // LINEAR INTERPOLATION
Chris@16 134 //
Chris@16 135 float_type p1 = *iter_probs;
Chris@16 136 float_type p0 = *(iter_probs - 1);
Chris@16 137 float_type h1 = *iter_heights;
Chris@16 138 float_type h0 = *(iter_heights - 1);
Chris@16 139
Chris@16 140 float_type a = numeric::fdiv(h1 - h0, p1 - p0);
Chris@16 141 float_type b = h1 - p1 * a;
Chris@16 142
Chris@16 143 res = a * this->probability + b;
Chris@16 144 }
Chris@16 145 else
Chris@16 146 {
Chris@16 147 /////////////////////////////////////////////////////////////////////////////////
Chris@16 148 // QUADRATIC INTERPOLATION
Chris@16 149 //
Chris@16 150 float_type p0, p1, p2;
Chris@16 151 float_type h0, h1, h2;
Chris@16 152
Chris@16 153 if ( (dist == 1 || *iter_probs - this->probability <= this->probability - *(iter_probs - 1) ) && dist != this->probabilities.size() - 1 )
Chris@16 154 {
Chris@16 155 p0 = *(iter_probs - 1);
Chris@16 156 p1 = *iter_probs;
Chris@16 157 p2 = *(iter_probs + 1);
Chris@16 158 h0 = *(iter_heights - 1);
Chris@16 159 h1 = *iter_heights;
Chris@16 160 h2 = *(iter_heights + 1);
Chris@16 161 }
Chris@16 162 else
Chris@16 163 {
Chris@16 164 p0 = *(iter_probs - 2);
Chris@16 165 p1 = *(iter_probs - 1);
Chris@16 166 p2 = *iter_probs;
Chris@16 167 h0 = *(iter_heights - 2);
Chris@16 168 h1 = *(iter_heights - 1);
Chris@16 169 h2 = *iter_heights;
Chris@16 170 }
Chris@16 171
Chris@16 172 float_type hp21 = numeric::fdiv(h2 - h1, p2 - p1);
Chris@16 173 float_type hp10 = numeric::fdiv(h1 - h0, p1 - p0);
Chris@16 174 float_type p21 = numeric::fdiv(p2 * p2 - p1 * p1, p2 - p1);
Chris@16 175 float_type p10 = numeric::fdiv(p1 * p1 - p0 * p0, p1 - p0);
Chris@16 176
Chris@16 177 float_type a = numeric::fdiv(hp21 - hp10, p21 - p10);
Chris@16 178 float_type b = hp21 - a * p21;
Chris@16 179 float_type c = h2 - a * p2 * p2 - b * p2;
Chris@16 180
Chris@16 181 res = a * this->probability * this-> probability + b * this->probability + c;
Chris@16 182 }
Chris@16 183
Chris@16 184 return res;
Chris@16 185 }
Chris@16 186
Chris@16 187 }
Chris@16 188 private:
Chris@16 189
Chris@16 190 array_type probabilities;
Chris@16 191 mutable float_type probability;
Chris@16 192
Chris@16 193 };
Chris@16 194
Chris@16 195 } // namespace impl
Chris@16 196
Chris@16 197 ///////////////////////////////////////////////////////////////////////////////
Chris@16 198 // tag::extended_p_square_quantile
Chris@16 199 //
Chris@16 200 namespace tag
Chris@16 201 {
Chris@16 202 struct extended_p_square_quantile
Chris@16 203 : depends_on<extended_p_square>
Chris@16 204 {
Chris@16 205 typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, unweighted, linear> impl;
Chris@16 206 };
Chris@16 207 struct extended_p_square_quantile_quadratic
Chris@16 208 : depends_on<extended_p_square>
Chris@16 209 {
Chris@16 210 typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, unweighted, quadratic> impl;
Chris@16 211 };
Chris@16 212 struct weighted_extended_p_square_quantile
Chris@16 213 : depends_on<weighted_extended_p_square>
Chris@16 214 {
Chris@16 215 typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, weighted, linear> impl;
Chris@16 216 };
Chris@16 217 struct weighted_extended_p_square_quantile_quadratic
Chris@16 218 : depends_on<weighted_extended_p_square>
Chris@16 219 {
Chris@16 220 typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, weighted, quadratic> impl;
Chris@16 221 };
Chris@16 222 }
Chris@16 223
Chris@16 224 ///////////////////////////////////////////////////////////////////////////////
Chris@16 225 // extract::extended_p_square_quantile
Chris@16 226 // extract::weighted_extended_p_square_quantile
Chris@16 227 //
Chris@16 228 namespace extract
Chris@16 229 {
Chris@16 230 extractor<tag::extended_p_square_quantile> const extended_p_square_quantile = {};
Chris@16 231 extractor<tag::extended_p_square_quantile_quadratic> const extended_p_square_quantile_quadratic = {};
Chris@16 232 extractor<tag::weighted_extended_p_square_quantile> const weighted_extended_p_square_quantile = {};
Chris@16 233 extractor<tag::weighted_extended_p_square_quantile_quadratic> const weighted_extended_p_square_quantile_quadratic = {};
Chris@16 234
Chris@16 235 BOOST_ACCUMULATORS_IGNORE_GLOBAL(extended_p_square_quantile)
Chris@16 236 BOOST_ACCUMULATORS_IGNORE_GLOBAL(extended_p_square_quantile_quadratic)
Chris@16 237 BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_extended_p_square_quantile)
Chris@16 238 BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_extended_p_square_quantile_quadratic)
Chris@16 239 }
Chris@16 240
Chris@16 241 using extract::extended_p_square_quantile;
Chris@16 242 using extract::extended_p_square_quantile_quadratic;
Chris@16 243 using extract::weighted_extended_p_square_quantile;
Chris@16 244 using extract::weighted_extended_p_square_quantile_quadratic;
Chris@16 245
Chris@16 246 // extended_p_square_quantile(linear) -> extended_p_square_quantile
Chris@16 247 template<>
Chris@16 248 struct as_feature<tag::extended_p_square_quantile(linear)>
Chris@16 249 {
Chris@16 250 typedef tag::extended_p_square_quantile type;
Chris@16 251 };
Chris@16 252
Chris@16 253 // extended_p_square_quantile(quadratic) -> extended_p_square_quantile_quadratic
Chris@16 254 template<>
Chris@16 255 struct as_feature<tag::extended_p_square_quantile(quadratic)>
Chris@16 256 {
Chris@16 257 typedef tag::extended_p_square_quantile_quadratic type;
Chris@16 258 };
Chris@16 259
Chris@16 260 // weighted_extended_p_square_quantile(linear) -> weighted_extended_p_square_quantile
Chris@16 261 template<>
Chris@16 262 struct as_feature<tag::weighted_extended_p_square_quantile(linear)>
Chris@16 263 {
Chris@16 264 typedef tag::weighted_extended_p_square_quantile type;
Chris@16 265 };
Chris@16 266
Chris@16 267 // weighted_extended_p_square_quantile(quadratic) -> weighted_extended_p_square_quantile_quadratic
Chris@16 268 template<>
Chris@16 269 struct as_feature<tag::weighted_extended_p_square_quantile(quadratic)>
Chris@16 270 {
Chris@16 271 typedef tag::weighted_extended_p_square_quantile_quadratic type;
Chris@16 272 };
Chris@16 273
Chris@16 274 // for the purposes of feature-based dependency resolution,
Chris@16 275 // extended_p_square_quantile and weighted_extended_p_square_quantile
Chris@16 276 // provide the same feature as quantile
Chris@16 277 template<>
Chris@16 278 struct feature_of<tag::extended_p_square_quantile>
Chris@16 279 : feature_of<tag::quantile>
Chris@16 280 {
Chris@16 281 };
Chris@16 282 template<>
Chris@16 283 struct feature_of<tag::extended_p_square_quantile_quadratic>
Chris@16 284 : feature_of<tag::quantile>
Chris@16 285 {
Chris@16 286 };
Chris@16 287 // So that extended_p_square_quantile can be automatically substituted with
Chris@16 288 // weighted_extended_p_square_quantile when the weight parameter is non-void
Chris@16 289 template<>
Chris@16 290 struct as_weighted_feature<tag::extended_p_square_quantile>
Chris@16 291 {
Chris@16 292 typedef tag::weighted_extended_p_square_quantile type;
Chris@16 293 };
Chris@16 294
Chris@16 295 template<>
Chris@16 296 struct feature_of<tag::weighted_extended_p_square_quantile>
Chris@16 297 : feature_of<tag::extended_p_square_quantile>
Chris@16 298 {
Chris@16 299 };
Chris@16 300
Chris@16 301 // So that extended_p_square_quantile_quadratic can be automatically substituted with
Chris@16 302 // weighted_extended_p_square_quantile_quadratic when the weight parameter is non-void
Chris@16 303 template<>
Chris@16 304 struct as_weighted_feature<tag::extended_p_square_quantile_quadratic>
Chris@16 305 {
Chris@16 306 typedef tag::weighted_extended_p_square_quantile_quadratic type;
Chris@16 307 };
Chris@16 308 template<>
Chris@16 309 struct feature_of<tag::weighted_extended_p_square_quantile_quadratic>
Chris@16 310 : feature_of<tag::extended_p_square_quantile_quadratic>
Chris@16 311 {
Chris@16 312 };
Chris@16 313
Chris@16 314 }} // namespace boost::accumulators
Chris@16 315
Chris@16 316 #ifdef _MSC_VER
Chris@16 317 # pragma warning(pop)
Chris@16 318 #endif
Chris@16 319
Chris@16 320 #endif