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