• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* chi_squared_test.hpp header file
2  *
3  * Copyright Steven Watanabe 2010
4  * Distributed under the Boost Software License, Version 1.0. (See
5  * accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  * $Id$
9  *
10  */
11 
12 #ifndef BOOST_RANDOM_TEST_CHI_SQUARED_TEST_HPP_INCLUDED
13 #define BOOST_RANDOM_TEST_CHI_SQUARED_TEST_HPP_INCLUDED
14 
15 #include <vector>
16 
17 #include <boost/math/special_functions/pow.hpp>
18 #include <boost/math/distributions/chi_squared.hpp>
19 
20 // This only works for discrete distributions with fixed
21 // upper and lower bounds.
22 
23 template<class IntType>
24 struct chi_squared_collector {
25 
26     static const IntType cutoff = 5;
27 
chi_squared_collectorchi_squared_collector28     chi_squared_collector()
29       : chi_squared(0),
30         variables(0),
31         prev_actual(0),
32         prev_expected(0),
33         current_actual(0),
34         current_expected(0)
35     {}
36 
operator ()chi_squared_collector37     void operator()(IntType actual, double expected) {
38         current_actual += actual;
39         current_expected += expected;
40 
41         if(current_expected >= cutoff) {
42             if(prev_expected != 0) {
43                 update(prev_actual, prev_expected);
44             }
45             prev_actual = current_actual;
46             prev_expected = current_expected;
47 
48             current_actual = 0;
49             current_expected = 0;
50         }
51     }
52 
updatechi_squared_collector53     void update(IntType actual, double expected) {
54         chi_squared += boost::math::pow<2>(actual - expected) / expected;
55         ++variables;
56     }
57 
cdfchi_squared_collector58     double cdf() {
59         if(prev_expected != 0) {
60             update(prev_actual + current_actual, prev_expected + current_expected);
61             prev_actual = 0;
62             prev_expected = 0;
63             current_actual = 0;
64             current_expected = 0;
65         }
66         if(variables <= 1) {
67             return 0;
68         } else {
69             return boost::math::cdf(boost::math::chi_squared(static_cast<double>(variables - 1)), chi_squared);
70         }
71     }
72 
73     double chi_squared;
74     std::size_t variables;
75 
76     IntType prev_actual;
77     double prev_expected;
78 
79     IntType current_actual;
80     double current_expected;
81 };
82 
83 template<class IntType>
chi_squared_test(const std::vector<IntType> & results,const std::vector<double> & probabilities,IntType iterations)84 double chi_squared_test(const std::vector<IntType>& results, const std::vector<double>& probabilities, IntType iterations) {
85     chi_squared_collector<IntType> calc;
86     for(std::size_t i = 0; i < results.size(); ++i) {
87         calc(results[i], iterations * probabilities[i]);
88     }
89     return calc.cdf();
90 }
91 
92 #endif
93