Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / math / test / test_chi_squared.cpp
1 // test_chi_squared.cpp
2
3 // Copyright Paul A. Bristow 2006.
4 // Copyright John Maddock 2007.
5
6 // Use, modification and distribution are subject to the
7 // Boost Software License, Version 1.0.
8 // (See accompanying file LICENSE_1_0.txt
9 // or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifdef _MSC_VER
12 #  pragma warning(disable: 4100) // unreferenced formal parameter.
13 // Seems an entirely spurious warning - formal parameter T IS used - get error if /* T */
14 //#  pragma warning(disable: 4535) // calling _set_se_translator() requires /EHa (in Boost.test)
15 // Enable C++ Exceptions Yes With SEH Exceptions (/EHa) prevents warning 4535.
16 #  pragma warning(disable: 4127) // conditional expression is constant
17 #endif
18
19 #include <boost/math/tools/test.hpp> // for real_concept
20 #include <boost/math/concepts/real_concept.hpp> // for real_concept
21 using ::boost::math::concepts::real_concept;
22
23 #include <boost/math/distributions/chi_squared.hpp> // for chi_squared_distribution
24 #include <boost/math/distributions/non_central_chi_squared.hpp> // for chi_squared_distribution
25 using boost::math::chi_squared_distribution;
26 using boost::math::chi_squared;
27
28 #define BOOST_TEST_MAIN
29 #include <boost/test/unit_test.hpp> // for test_main
30 #include <boost/test/tools/floating_point_comparison.hpp> // for BOOST_CHECK_CLOSE
31
32 #include "test_out_of_range.hpp"
33
34 #include <iostream>
35 using std::cout;
36 using std::endl;
37 #include <limits>
38 using std::numeric_limits;
39
40 template <class RealType>
41 RealType naive_pdf(RealType df, RealType x)
42 {
43    using namespace std; // For ADL of std functions.
44    RealType e = log(x) * ((df / 2) - 1) - (x / 2) - boost::math::lgamma(df/2);
45    e -= log(static_cast<RealType>(2)) * df / 2;
46    return exp(e);
47 }
48
49 template <class RealType>
50 void test_spot(
51      RealType df,    // Degrees of freedom
52      RealType cs,    // Chi Square statistic
53      RealType P,     // CDF
54      RealType Q,     // Complement of CDF
55      RealType tol)   // Test tolerance
56 {
57    boost::math::chi_squared_distribution<RealType> dist(df);
58    BOOST_CHECK_CLOSE(
59       cdf(dist, cs), P, tol);
60    BOOST_CHECK_CLOSE(
61       pdf(dist, cs), naive_pdf(dist.degrees_of_freedom(), cs), tol);
62    if((P < 0.99) && (Q < 0.99))
63    {
64       //
65       // We can only check this if P is not too close to 1,
66       // so that we can guarantee Q is free of error:
67       //
68       BOOST_CHECK_CLOSE(
69          cdf(complement(dist, cs)), Q, tol);
70       BOOST_CHECK_CLOSE(
71             quantile(dist, P), cs, tol);
72       BOOST_CHECK_CLOSE(
73             quantile(complement(dist, Q)), cs, tol);
74    }
75
76    boost::math::non_central_chi_squared_distribution<RealType> dist2(df, 0);
77    BOOST_CHECK_CLOSE(
78       cdf(dist2, cs), P, tol);
79    BOOST_CHECK_CLOSE(
80       pdf(dist2, cs), naive_pdf(dist2.degrees_of_freedom(), cs), tol);
81    if((P < 0.99) && (Q < 0.99))
82    {
83       //
84       // We can only check this if P is not too close to 1,
85       // so that we can guarantee Q is free of error:
86       //
87       BOOST_CHECK_CLOSE(
88          cdf(complement(dist2, cs)), Q, tol);
89       BOOST_CHECK_CLOSE(
90          quantile(dist2, P), cs, tol);
91       BOOST_CHECK_CLOSE(
92          quantile(complement(dist2, Q)), cs, tol);
93    }
94 }
95
96 //
97 // This test data is taken from the tables of upper and lower
98 // critical values of the Chi Squared distribution available
99 // at http://www.itl.nist.gov/div898/handbook/eda/section3/eda3674.htm
100 //
101 double q[] = { 0.10, 0.05, 0.025, 0.01, 0.001 };
102 double upper_critical_values[][6] = {
103   { 1,         2.706,    3.841,    5.024,    6.635,   10.828 },
104   { 2,         4.605,    5.991,    7.378,    9.210,   13.816 },
105   { 3,         6.251,    7.815,    9.348,   11.345,   16.266 },
106   { 4,         7.779,    9.488,   11.143,   13.277,   18.467 },
107   { 5,         9.236,   11.070,   12.833,   15.086,   20.515 },
108   { 6,        10.645,   12.592,   14.449,   16.812,   22.458 },
109   { 7,        12.017,   14.067,   16.013,   18.475,   24.322 },
110   { 8,        13.362,   15.507,   17.535,   20.090,   26.125 },
111   { 9,        14.684,   16.919,   19.023,   21.666,   27.877 },
112  { 10,        15.987,   18.307,   20.483,   23.209,   29.588 },
113  { 11,        17.275,   19.675,   21.920,   24.725,   31.264 },
114  { 12,        18.549,   21.026,   23.337,   26.217,   32.910 },
115  { 13,        19.812,   22.362,   24.736,   27.688,   34.528 },
116  { 14,        21.064,   23.685,   26.119,   29.141,   36.123 },
117  { 15,        22.307,   24.996,   27.488,   30.578,   37.697 },
118  { 16,        23.542,   26.296,   28.845,   32.000,   39.252 },
119  { 17,        24.769,   27.587,   30.191,   33.409,   40.790 },
120  { 18,        25.989,   28.869,   31.526,   34.805,   42.312 },
121  { 19,        27.204,   30.144,   32.852,   36.191,   43.820 },
122  { 20,        28.412,   31.410,   34.170,   37.566,   45.315 },
123  { 21,        29.615,   32.671,   35.479,   38.932,   46.797 },
124  { 22,        30.813,   33.924,   36.781,   40.289,   48.268 },
125  { 23,        32.007,   35.172,   38.076,   41.638,   49.728 },
126  { 24,        33.196,   36.415,   39.364,   42.980,   51.179 },
127  { 25,        34.382,   37.652,   40.646,   44.314,   52.620 },
128  { 26,        35.563,   38.885,   41.923,   45.642,   54.052 },
129  { 27,        36.741,   40.113,   43.195,   46.963,   55.476 },
130  { 28,        37.916,   41.337,   44.461,   48.278,   56.892 },
131  { 29,        39.087,   42.557,   45.722,   49.588,   58.301 },
132  { 30,        40.256,   43.773,   46.979,   50.892,   59.703 },
133  { 31,        41.422,   44.985,   48.232,   52.191,   61.098 },
134  { 32,        42.585,   46.194,   49.480,   53.486,   62.487 },
135  { 33,        43.745,   47.400,   50.725,   54.776,   63.870 },
136  { 34,        44.903,   48.602,   51.966,   56.061,   65.247 },
137  { 35,        46.059,   49.802,   53.203,   57.342,   66.619 },
138  { 36,        47.212,   50.998,   54.437,   58.619,   67.985 },
139  { 37,        48.363,   52.192,   55.668,   59.893,   69.347 },
140  { 38,        49.513,   53.384,   56.896,   61.162,   70.703 },
141  { 39,        50.660,   54.572,   58.120,   62.428,   72.055 },
142  { 40,        51.805,   55.758,   59.342,   63.691,   73.402 },
143  { 41,        52.949,   56.942,   60.561,   64.950,   74.745 },
144  { 42,        54.090,   58.124,   61.777,   66.206,   76.084 },
145  { 43,        55.230,   59.304,   62.990,   67.459,   77.419 },
146  { 44,        56.369,   60.481,   64.201,   68.710,   78.750 },
147  { 45,        57.505,   61.656,   65.410,   69.957,   80.077 },
148  { 46,        58.641,   62.830,   66.617,   71.201,   81.400 },
149  { 47,        59.774,   64.001,   67.821,   72.443,   82.720 },
150  { 48,        60.907,   65.171,   69.023,   73.683,   84.037 },
151  { 49,        62.038,   66.339,   70.222,   74.919,   85.351 },
152  { 50,        63.167,   67.505,   71.420,   76.154,   86.661 },
153  { 51,        64.295,   68.669,   72.616,   77.386,   87.968 },
154  { 52,        65.422,   69.832,   73.810,   78.616,   89.272 },
155  { 53,        66.548,   70.993,   75.002,   79.843,   90.573 },
156  { 54,        67.673,   72.153,   76.192,   81.069,   91.872 },
157  { 55,        68.796,   73.311,   77.380,   82.292,   93.168 },
158  { 56,        69.919,   74.468,   78.567,   83.513,   94.461 },
159  { 57,        71.040,   75.624,   79.752,   84.733,   95.751 },
160  { 58,        72.160,   76.778,   80.936,   85.950,   97.039 },
161  { 59,        73.279,   77.931,   82.117,   87.166,   98.324 },
162  { 60,        74.397,   79.082,   83.298,   88.379,   99.607 },
163  { 61,        75.514,   80.232,   84.476,   89.591,  100.888 },
164  { 62,        76.630,   81.381,   85.654,   90.802,  102.166 },
165  { 63,        77.745,   82.529,   86.830,   92.010,  103.442 },
166  { 64,        78.860,   83.675,   88.004,   93.217,  104.716 },
167  { 65,        79.973,   84.821,   89.177,   94.422,  105.988 },
168  { 66,        81.085,   85.965,   90.349,   95.626,  107.258 },
169  { 67,        82.197,   87.108,   91.519,   96.828,  108.526 },
170  { 68,        83.308,   88.250,   92.689,   98.028,  109.791 },
171  { 69,        84.418,   89.391,   93.856,   99.228,  111.055 },
172  { 70,        85.527,   90.531,   95.023,  100.425,  112.317 },
173  { 71,        86.635,   91.670,   96.189,  101.621,  113.577 },
174  { 72,        87.743,   92.808,   97.353,  102.816,  114.835 },
175  { 73,        88.850,   93.945,   98.516,  104.010,  116.092 },
176  { 74,        89.956,   95.081,   99.678,  105.202,  117.346 },
177  { 75,        91.061,   96.217,  100.839,  106.393,  118.599 },
178  { 76,        92.166,   97.351,  101.999,  107.583,  119.850 },
179  { 77,        93.270,   98.484,  103.158,  108.771,  121.100 },
180  { 78,        94.374,   99.617,  104.316,  109.958,  122.348 },
181  { 79,        95.476,  100.749,  105.473,  111.144,  123.594 },
182  { 80,        96.578,  101.879,  106.629,  112.329,  124.839 },
183  { 81,        97.680,  103.010,  107.783,  113.512,  126.083 },
184  { 82,        98.780,  104.139,  108.937,  114.695,  127.324 },
185  { 83,        99.880,  105.267,  110.090,  115.876,  128.565 },
186  { 84,       100.980,  106.395,  111.242,  117.057,  129.804 },
187  { 85,       102.079,  107.522,  112.393,  118.236,  131.041 },
188  { 86,       103.177,  108.648,  113.544,  119.414,  132.277 },
189  { 87,       104.275,  109.773,  114.693,  120.591,  133.512 },
190  { 88,       105.372,  110.898,  115.841,  121.767,  134.746 },
191  { 89,       106.469,  112.022,  116.989,  122.942,  135.978 },
192  { 90,       107.565,  113.145,  118.136,  124.116,  137.208 },
193  { 91,       108.661,  114.268,  119.282,  125.289,  138.438 },
194  { 92,       109.756,  115.390,  120.427,  126.462,  139.666 },
195  { 93,       110.850,  116.511,  121.571,  127.633,  140.893 },
196  { 94,       111.944,  117.632,  122.715,  128.803,  142.119 },
197  { 95,       113.038,  118.752,  123.858,  129.973,  143.344 },
198  { 96,       114.131,  119.871,  125.000,  131.141,  144.567 },
199  { 97,       115.223,  120.990,  126.141,  132.309,  145.789 },
200  { 98,       116.315,  122.108,  127.282,  133.476,  147.010 },
201  { 99,       117.407,  123.225,  128.422,  134.642,  148.230 },
202  { 100,       118.498,  124.342,  129.561,  135.807,  149.449 },
203  {100,       118.498,  124.342,  129.561,  135.807,  149.449 }
204 };
205
206 double lower_critical_values[][6] = {
207    /*
208    These have fewer than 4 significant digits, leave them out
209    of the tests for now:
210      1.,         .016,     .004,     .001,     .000,     .000,
211      2.,         .211,     .103,     .051,     .020,     .002,
212      3.,         .584,     .352,     .216,     .115,     .024,
213      4.,        1.064,     .711,     .484,     .297,     .091,
214      5.,        1.610,    1.145,     .831,     .554,     .210,
215      6.,        2.204,    1.635,    1.237,     .872,     .381,
216      7.,        2.833,    2.167,    1.690,    1.239,     .598,
217      8.,        3.490,    2.733,    2.180,    1.646,     .857,
218      */
219      { 9.,        4.168,    3.325,    2.700,    2.088,    1.152 },
220     { 10.,        4.865,    3.940,    3.247,    2.558,    1.479 },
221     { 11.,        5.578,    4.575,    3.816,    3.053,    1.834 },
222     { 12.,        6.304,    5.226,    4.404,    3.571,    2.214 },
223     { 13.,        7.042,    5.892,    5.009,    4.107,    2.617 },
224     { 14.,        7.790,    6.571,    5.629,    4.660,    3.041 },
225     { 15.,        8.547,    7.261,    6.262,    5.229,    3.483 },
226     { 16.,        9.312,    7.962,    6.908,    5.812,    3.942 },
227     { 17.,       10.085,    8.672,    7.564,    6.408,    4.416 },
228     { 18.,       10.865,    9.390,    8.231,    7.015,    4.905 },
229     { 19.,       11.651,   10.117,    8.907,    7.633,    5.407 },
230     { 20.,       12.443,   10.851,    9.591,    8.260,    5.921 },
231     { 21.,       13.240,   11.591,   10.283,    8.897,    6.447 },
232     { 22.,       14.041,   12.338,   10.982,    9.542,    6.983 },
233     { 23.,       14.848,   13.091,   11.689,   10.196,    7.529 },
234     { 24.,       15.659,   13.848,   12.401,   10.856,    8.085 },
235     { 25.,       16.473,   14.611,   13.120,   11.524,    8.649 },
236     { 26.,       17.292,   15.379,   13.844,   12.198,    9.222 },
237     { 27.,       18.114,   16.151,   14.573,   12.879,    9.803 },
238     { 28.,       18.939,   16.928,   15.308,   13.565,   10.391 },
239     { 29.,       19.768,   17.708,   16.047,   14.256,   10.986 },
240     { 30.,       20.599,   18.493,   16.791,   14.953,   11.588 },
241     { 31.,       21.434,   19.281,   17.539,   15.655,   12.196 },
242     { 32.,       22.271,   20.072,   18.291,   16.362,   12.811 },
243     { 33.,       23.110,   20.867,   19.047,   17.074,   13.431 },
244     { 34.,       23.952,   21.664,   19.806,   17.789,   14.057 },
245     { 35.,       24.797,   22.465,   20.569,   18.509,   14.688 },
246     { 36.,       25.643,   23.269,   21.336,   19.233,   15.324 },
247     { 37.,       26.492,   24.075,   22.106,   19.960,   15.965 },
248     { 38.,       27.343,   24.884,   22.878,   20.691,   16.611 },
249     { 39.,       28.196,   25.695,   23.654,   21.426,   17.262 },
250     { 40.,       29.051,   26.509,   24.433,   22.164,   17.916 },
251     { 41.,       29.907,   27.326,   25.215,   22.906,   18.575 },
252     { 42.,       30.765,   28.144,   25.999,   23.650,   19.239 },
253     { 43.,       31.625,   28.965,   26.785,   24.398,   19.906 },
254     { 44.,       32.487,   29.787,   27.575,   25.148,   20.576 },
255     { 45.,       33.350,   30.612,   28.366,   25.901,   21.251 },
256     { 46.,       34.215,   31.439,   29.160,   26.657,   21.929 },
257     { 47.,       35.081,   32.268,   29.956,   27.416,   22.610 },
258     { 48.,       35.949,   33.098,   30.755,   28.177,   23.295 },
259     { 49.,       36.818,   33.930,   31.555,   28.941,   23.983 },
260     { 50.,       37.689,   34.764,   32.357,   29.707,   24.674 },
261     { 51.,       38.560,   35.600,   33.162,   30.475,   25.368 },
262     { 52.,       39.433,   36.437,   33.968,   31.246,   26.065 },
263     { 53.,       40.308,   37.276,   34.776,   32.018,   26.765 },
264     { 54.,       41.183,   38.116,   35.586,   32.793,   27.468 },
265     { 55.,       42.060,   38.958,   36.398,   33.570,   28.173 },
266     { 56.,       42.937,   39.801,   37.212,   34.350,   28.881 },
267     { 57.,       43.816,   40.646,   38.027,   35.131,   29.592 },
268     { 58.,       44.696,   41.492,   38.844,   35.913,   30.305 },
269     { 59.,       45.577,   42.339,   39.662,   36.698,   31.020 },
270     { 60.,       46.459,   43.188,   40.482,   37.485,   31.738 },
271     { 61.,       47.342,   44.038,   41.303,   38.273,   32.459 },
272     { 62.,       48.226,   44.889,   42.126,   39.063,   33.181 },
273     { 63.,       49.111,   45.741,   42.950,   39.855,   33.906 },
274     { 64.,       49.996,   46.595,   43.776,   40.649,   34.633 },
275     { 65.,       50.883,   47.450,   44.603,   41.444,   35.362 },
276     { 66.,       51.770,   48.305,   45.431,   42.240,   36.093 },
277     { 67.,       52.659,   49.162,   46.261,   43.038,   36.826 },
278     { 68.,       53.548,   50.020,   47.092,   43.838,   37.561 },
279     { 69.,       54.438,   50.879,   47.924,   44.639,   38.298 },
280     { 70.,       55.329,   51.739,   48.758,   45.442,   39.036 },
281     { 71.,       56.221,   52.600,   49.592,   46.246,   39.777 },
282     { 72.,       57.113,   53.462,   50.428,   47.051,   40.519 },
283     { 73.,       58.006,   54.325,   51.265,   47.858,   41.264 },
284     { 74.,       58.900,   55.189,   52.103,   48.666,   42.010 },
285     { 75.,       59.795,   56.054,   52.942,   49.475,   42.757 },
286     { 76.,       60.690,   56.920,   53.782,   50.286,   43.507 },
287     { 77.,       61.586,   57.786,   54.623,   51.097,   44.258 },
288     { 78.,       62.483,   58.654,   55.466,   51.910,   45.010 },
289     { 79.,       63.380,   59.522,   56.309,   52.725,   45.764 },
290     { 80.,       64.278,   60.391,   57.153,   53.540,   46.520 },
291     { 81.,       65.176,   61.261,   57.998,   54.357,   47.277 },
292     { 82.,       66.076,   62.132,   58.845,   55.174,   48.036 },
293     { 83.,       66.976,   63.004,   59.692,   55.993,   48.796 },
294     { 84.,       67.876,   63.876,   60.540,   56.813,   49.557 },
295     { 85.,       68.777,   64.749,   61.389,   57.634,   50.320 },
296     { 86.,       69.679,   65.623,   62.239,   58.456,   51.085 },
297     { 87.,       70.581,   66.498,   63.089,   59.279,   51.850 },
298     { 88.,       71.484,   67.373,   63.941,   60.103,   52.617 },
299     { 89.,       72.387,   68.249,   64.793,   60.928,   53.386 },
300     { 90.,       73.291,   69.126,   65.647,   61.754,   54.155 },
301     { 91.,       74.196,   70.003,   66.501,   62.581,   54.926 },
302     { 92.,       75.100,   70.882,   67.356,   63.409,   55.698 },
303     { 93.,       76.006,   71.760,   68.211,   64.238,   56.472 },
304     { 94.,       76.912,   72.640,   69.068,   65.068,   57.246 },
305     { 95.,       77.818,   73.520,   69.925,   65.898,   58.022 },
306     { 96.,       78.725,   74.401,   70.783,   66.730,   58.799 },
307     { 97.,       79.633,   75.282,   71.642,   67.562,   59.577 },
308     { 98.,       80.541,   76.164,   72.501,   68.396,   60.356 },
309     { 99.,       81.449,   77.046,   73.361,   69.230,   61.137 },
310     {100.,       82.358,   77.929,   74.222,   70.065,   61.918 }
311 };
312
313 template <class RealType> // Any floating-point type RealType.
314 void test_spots(RealType T)
315 {
316   // Basic sanity checks, test data is to three decimal places only
317   // so set tolerance to 0.001 expressed as a persentage.
318
319   RealType tolerance = 0.001f * 100;
320
321   cout << "Tolerance for type " << typeid(T).name()  << " is " << tolerance << " %" << endl;
322
323   using boost::math::chi_squared_distribution;
324   using  ::boost::math::chi_squared;
325   using  ::boost::math::cdf;
326   using  ::boost::math::pdf;
327
328   for(unsigned i = 0; i < sizeof(upper_critical_values) / sizeof(upper_critical_values[0]); ++i)
329   {
330      test_spot(
331         static_cast<RealType>(upper_critical_values[i][0]),   // degrees of freedom
332         static_cast<RealType>(upper_critical_values[i][1]),   // Chi Squared statistic
333         static_cast<RealType>(1 - q[0]),       // Probability of result (CDF), P
334         static_cast<RealType>(q[0]),           // Q = 1 - P
335         tolerance);
336      test_spot(
337         static_cast<RealType>(upper_critical_values[i][0]),   // degrees of freedom
338         static_cast<RealType>(upper_critical_values[i][2]),   // Chi Squared statistic
339         static_cast<RealType>(1 - q[1]),       // Probability of result (CDF), P
340         static_cast<RealType>(q[1]),           // Q = 1 - P
341         tolerance);
342      test_spot(
343         static_cast<RealType>(upper_critical_values[i][0]),   // degrees of freedom
344         static_cast<RealType>(upper_critical_values[i][3]),   // Chi Squared statistic
345         static_cast<RealType>(1 - q[2]),       // Probability of result (CDF), P
346         static_cast<RealType>(q[2]),           // Q = 1 - P
347         tolerance);
348      test_spot(
349         static_cast<RealType>(upper_critical_values[i][0]),   // degrees of freedom
350         static_cast<RealType>(upper_critical_values[i][4]),   // Chi Squared statistic
351         static_cast<RealType>(1 - q[3]),       // Probability of result (CDF), P
352         static_cast<RealType>(q[3]),           // Q = 1 - P
353         tolerance);
354      test_spot(
355         static_cast<RealType>(upper_critical_values[i][0]),   // degrees of freedom
356         static_cast<RealType>(upper_critical_values[i][5]),   // Chi Squared statistic
357         static_cast<RealType>(1 - q[4]),       // Probability of result (CDF), P
358         static_cast<RealType>(q[4]),           // Q = 1 - P
359         tolerance);
360   }
361
362   for(unsigned i = 0; i < sizeof(lower_critical_values) / sizeof(lower_critical_values[0]); ++i)
363   {
364      test_spot(
365         static_cast<RealType>(lower_critical_values[i][0]),   // degrees of freedom
366         static_cast<RealType>(lower_critical_values[i][1]),   // Chi Squared statistic
367         static_cast<RealType>(q[0]),       // Probability of result (CDF), P
368         static_cast<RealType>(1 - q[0]),           // Q = 1 - P
369         tolerance);
370      test_spot(
371         static_cast<RealType>(lower_critical_values[i][0]),   // degrees of freedom
372         static_cast<RealType>(lower_critical_values[i][2]),   // Chi Squared statistic
373         static_cast<RealType>(q[1]),       // Probability of result (CDF), P
374         static_cast<RealType>(1 - q[1]),           // Q = 1 - P
375         tolerance);
376      test_spot(
377         static_cast<RealType>(lower_critical_values[i][0]),   // degrees of freedom
378         static_cast<RealType>(lower_critical_values[i][3]),   // Chi Squared statistic
379         static_cast<RealType>(q[2]),       // Probability of result (CDF), P
380         static_cast<RealType>(1 - q[2]),           // Q = 1 - P
381         tolerance);
382      test_spot(
383         static_cast<RealType>(lower_critical_values[i][0]),   // degrees of freedom
384         static_cast<RealType>(lower_critical_values[i][4]),   // Chi Squared statistic
385         static_cast<RealType>(q[3]),       // Probability of result (CDF), P
386         static_cast<RealType>(1 - q[3]),           // Q = 1 - P
387         tolerance);
388      test_spot(
389         static_cast<RealType>(lower_critical_values[i][0]),   // degrees of freedom
390         static_cast<RealType>(lower_critical_values[i][5]),   // Chi Squared statistic
391         static_cast<RealType>(q[4]),       // Probability of result (CDF), P
392         static_cast<RealType>(1 - q[4]),           // Q = 1 - P
393         tolerance);
394   }
395
396     RealType tol2 = boost::math::tools::epsilon<RealType>() * 5 * 100; // 5 eps as a percentage
397     chi_squared_distribution<RealType> dist(static_cast<RealType>(8));
398     RealType x = 7;
399     using namespace std; // ADL of std names.
400     // mean:
401     BOOST_CHECK_CLOSE(
402        mean(dist)
403        , static_cast<RealType>(8), tol2);
404     // variance:
405     BOOST_CHECK_CLOSE(
406        variance(dist)
407        , static_cast<RealType>(16), tol2);
408     // std deviation:
409     BOOST_CHECK_CLOSE(
410        standard_deviation(dist)
411        , static_cast<RealType>(4), tol2);
412     // hazard:
413     BOOST_CHECK_CLOSE(
414        hazard(dist, x)
415        , pdf(dist, x) / cdf(complement(dist, x)), tol2);
416     // cumulative hazard:
417     BOOST_CHECK_CLOSE(
418        chf(dist, x)
419        , -log(cdf(complement(dist, x))), tol2);
420     // coefficient_of_variation:
421     BOOST_CHECK_CLOSE(
422        coefficient_of_variation(dist)
423        , standard_deviation(dist) / mean(dist), tol2);
424     // mode:
425     BOOST_CHECK_CLOSE(
426        mode(dist)
427        , static_cast<RealType>(6), tol2);
428
429     BOOST_CHECK_CLOSE(
430        median(dist), 
431        quantile(
432           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
433           static_cast<RealType>(0.5)), static_cast<RealType>(tol2));
434     // skewness:
435     BOOST_CHECK_CLOSE(
436        skewness(dist)
437        , static_cast<RealType>(1), tol2);
438     // kurtosis:
439     BOOST_CHECK_CLOSE(
440        kurtosis(dist)
441        , static_cast<RealType>(4.5), tol2);
442     // kurtosis excess:
443     BOOST_CHECK_CLOSE(
444        kurtosis_excess(dist)
445        , static_cast<RealType>(1.5), tol2);
446     // special cases:
447     BOOST_MATH_CHECK_THROW(
448        pdf(
449           chi_squared_distribution<RealType>(static_cast<RealType>(1)),
450           static_cast<RealType>(0)), std::overflow_error
451        );
452     BOOST_CHECK_EQUAL(
453        pdf(chi_squared_distribution<RealType>(2), static_cast<RealType>(0))
454        , static_cast<RealType>(0.5f));
455     BOOST_CHECK_EQUAL(
456        pdf(chi_squared_distribution<RealType>(3), static_cast<RealType>(0))
457        , static_cast<RealType>(0.0f));
458     BOOST_CHECK_EQUAL(
459        cdf(chi_squared_distribution<RealType>(1), static_cast<RealType>(0))
460        , static_cast<RealType>(0.0f));
461     BOOST_CHECK_EQUAL(
462        cdf(chi_squared_distribution<RealType>(2), static_cast<RealType>(0))
463        , static_cast<RealType>(0.0f));
464     BOOST_CHECK_EQUAL(
465        cdf(chi_squared_distribution<RealType>(3), static_cast<RealType>(0))
466        , static_cast<RealType>(0.0f));
467     BOOST_CHECK_EQUAL(
468        cdf(complement(chi_squared_distribution<RealType>(1), static_cast<RealType>(0)))
469        , static_cast<RealType>(1));
470     BOOST_CHECK_EQUAL(
471        cdf(complement(chi_squared_distribution<RealType>(2), static_cast<RealType>(0)))
472        , static_cast<RealType>(1));
473     BOOST_CHECK_EQUAL(
474        cdf(complement(chi_squared_distribution<RealType>(3), static_cast<RealType>(0)))
475        , static_cast<RealType>(1));
476
477     BOOST_MATH_CHECK_THROW(
478        pdf(
479           chi_squared_distribution<RealType>(static_cast<RealType>(-1)),
480           static_cast<RealType>(1)), std::domain_error
481        );
482     BOOST_MATH_CHECK_THROW(
483        pdf(
484           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
485           static_cast<RealType>(-1)), std::domain_error
486        );
487     BOOST_MATH_CHECK_THROW(
488        cdf(
489           chi_squared_distribution<RealType>(static_cast<RealType>(-1)),
490           static_cast<RealType>(1)), std::domain_error
491        );
492     BOOST_MATH_CHECK_THROW(
493        cdf(
494           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
495           static_cast<RealType>(-1)), std::domain_error
496        );
497     BOOST_MATH_CHECK_THROW(
498        cdf(complement(
499           chi_squared_distribution<RealType>(static_cast<RealType>(-1)),
500           static_cast<RealType>(1))), std::domain_error
501        );
502     BOOST_MATH_CHECK_THROW(
503        cdf(complement(
504           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
505           static_cast<RealType>(-1))), std::domain_error
506        );
507     BOOST_MATH_CHECK_THROW(
508        quantile(
509           chi_squared_distribution<RealType>(static_cast<RealType>(-1)),
510           static_cast<RealType>(0.5)), std::domain_error
511        );
512     BOOST_MATH_CHECK_THROW(
513        quantile(
514           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
515           static_cast<RealType>(-1)), std::domain_error
516        );
517     BOOST_MATH_CHECK_THROW(
518        quantile(
519           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
520           static_cast<RealType>(1.1)), std::domain_error
521        );
522     BOOST_MATH_CHECK_THROW(
523        quantile(complement(
524           chi_squared_distribution<RealType>(static_cast<RealType>(-1)),
525           static_cast<RealType>(0.5))), std::domain_error
526        );
527     BOOST_MATH_CHECK_THROW(
528        quantile(complement(
529           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
530           static_cast<RealType>(-1))), std::domain_error
531        );
532     BOOST_MATH_CHECK_THROW(
533        quantile(complement(
534           chi_squared_distribution<RealType>(static_cast<RealType>(8)),
535           static_cast<RealType>(1.1))), std::domain_error
536        );
537
538     // This first test value is taken from an example here:
539     // http://www.itl.nist.gov/div898/handbook/prc/section2/prc232.htm
540     // Subsequent tests just test our empirically generated values, they
541     // catch regressions, but otherwise aren't worth much.
542     BOOST_CHECK_EQUAL(
543        ceil(chi_squared_distribution<RealType>::find_degrees_of_freedom(
544          55, 0.05f, 0.01f, 100)), static_cast<RealType>(170));
545     BOOST_CHECK_EQUAL(
546        ceil(chi_squared_distribution<RealType>::find_degrees_of_freedom(
547          10, 0.05f, 0.01f, 100)), static_cast<RealType>(3493));
548     BOOST_CHECK_EQUAL(
549        ceil(chi_squared_distribution<RealType>::find_degrees_of_freedom(
550          -55, 0.05f, 0.01f, 100)), static_cast<RealType>(49));
551     BOOST_CHECK_EQUAL(
552        ceil(chi_squared_distribution<RealType>::find_degrees_of_freedom(
553          -10, 0.05f, 0.01f, 100)), static_cast<RealType>(2826));
554
555     check_out_of_range<boost::math::chi_squared_distribution<RealType> >(1); // (All) valid constructor parameter values.
556
557 } // template <class RealType>void test_spots(RealType)
558
559 BOOST_AUTO_TEST_CASE( test_main )
560 {
561   BOOST_MATH_CONTROL_FP;
562   // Check that can generate chi_squared distribution using the two convenience methods:
563   chi_squared_distribution<> mychisqr(8);
564   chi_squared mychisqr2(8);
565
566   // Basic sanity-check spot values.
567
568   // (Parameter value, arbitrarily zero, only communicates the floating point type).
569   test_spots(0.0F); // Test float.
570   test_spots(0.0); // Test double.
571 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
572   test_spots(0.0L); // Test long double.
573 #if !defined(BOOST_MATH_NO_REAL_CONCEPT_TESTS)
574   test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
575 #endif
576 #endif
577 } // BOOST_AUTO_TEST_CASE( test_main )
578
579 /*
580
581 Output:
582
583 Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_chi_squared.exe"
584   Running 1 test case...
585   Tolerance for type float is 0.1 %
586   Tolerance for type double is 0.1 %
587   Tolerance for type long double is 0.1 %
588   Tolerance for type class boost::math::concepts::real_concept is 0.1 %
589
590
591 */
592
593
594