wilson_interval.hpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2022 Jay Gohil, Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_HISTOGRAM_UTILITY_WILSON_INTERVAL_HPP
  7. #define BOOST_HISTOGRAM_UTILITY_WILSON_INTERVAL_HPP
  8. #include <boost/histogram/fwd.hpp>
  9. #include <boost/histogram/utility/binomial_proportion_interval.hpp>
  10. #include <cmath>
  11. #include <utility>
  12. namespace boost {
  13. namespace histogram {
  14. namespace utility {
  15. /**
  16. Wilson interval.
  17. The Wilson score interval is simple to compute, has good coverage. Intervals are
  18. automatically bounded between 0 and 1 and never empty. The interval is asymmetric.
  19. Wilson, E. B. (1927). "Probable inference, the law of succession, and statistical
  20. inference". Journal of the American Statistical Association. 22 (158): 209-212.
  21. doi:10.1080/01621459.1927.10502953. JSTOR 2276774.
  22. The coverage probability for a random ensemble of fractions is close to the nominal
  23. value. Unlike the Clopper-Pearson interval, the Wilson score interval is not
  24. conservative. For some values of the fractions, the interval undercovers and overcovers
  25. for neighboring values. This is a shared property of all alternatives to the
  26. Clopper-Pearson interval.
  27. The Wilson score intervals is widely recommended for general use in the literature. For
  28. a review of the literature, see R. D. Cousins, K. E. Hymes, J. Tucker, Nucl. Instrum.
  29. Meth. A 612 (2010) 388-398.
  30. */
  31. template <class ValueType>
  32. class wilson_interval : public binomial_proportion_interval<ValueType> {
  33. public:
  34. using value_type = typename wilson_interval::value_type;
  35. using interval_type = typename wilson_interval::interval_type;
  36. /** Construct Wilson interval computer.
  37. @param d Number of standard deviations for the interval. The default value 1
  38. corresponds to a confidence level of 68 %. Both `deviation` and `confidence_level`
  39. objects can be used to initialize the interval.
  40. */
  41. explicit wilson_interval(deviation d = deviation{1.0}) noexcept
  42. : z_{static_cast<value_type>(d)} {}
  43. using binomial_proportion_interval<ValueType>::operator();
  44. /** Compute interval for given number of successes and failures.
  45. @param successes Number of successful trials.
  46. @param failures Number of failed trials.
  47. */
  48. interval_type operator()(value_type successes, value_type failures) const noexcept {
  49. // See https://en.wikipedia.org/wiki/
  50. // Binomial_proportion_confidence_interval
  51. // #Wilson_score_interval
  52. // We make sure calculation is done in single precision if value_type is float
  53. // by converting all literals to value_type. Double literals in the equation
  54. // would turn intermediate values to double.
  55. const value_type half{0.5}, quarter{0.25}, zsq{z_ * z_};
  56. const value_type total = successes + failures;
  57. const value_type minv = 1 / (total + zsq);
  58. const value_type t1 = (successes + half * zsq) * minv;
  59. const value_type t2 =
  60. z_ * minv * std::sqrt(successes * failures / total + quarter * zsq);
  61. return {t1 - t2, t1 + t2};
  62. }
  63. private:
  64. value_type z_;
  65. };
  66. } // namespace utility
  67. } // namespace histogram
  68. } // namespace boost
  69. #endif