]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | /* |
2 | * Copyright Nick Thompson, 2019 | |
1e59de90 | 3 | * Copyright Matt Borland, 2021 |
92f5a8d4 TL |
4 | * Use, modification and distribution are subject to the |
5 | * Boost Software License, Version 1.0. (See accompanying file | |
6 | * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | */ | |
8 | ||
9 | #include "math_unit_test.hpp" | |
10 | #include <vector> | |
11 | #include <random> | |
1e59de90 TL |
12 | #include <utility> |
13 | #include <boost/math/tools/config.hpp> | |
92f5a8d4 TL |
14 | #include <boost/math/statistics/univariate_statistics.hpp> |
15 | #include <boost/math/statistics/t_test.hpp> | |
1e59de90 | 16 | #include <boost/multiprecision/cpp_bin_float.hpp> |
92f5a8d4 TL |
17 | |
18 | template<typename Real> | |
19 | void test_exact_mean() | |
20 | { | |
21 | // Of course this test seems obvious, but just for the sake of comfort, here's the Mathematica to demo this test: | |
22 | // data3 = RandomReal[NormalDistribution[], 1024]; | |
23 | // NumberForm[TTest[data3, Mean[data3], "TestStatistic"], 16] | |
24 | // NumberForm[TTest[data3, Mean[data3], "PValue"], 16] | |
25 | std::mt19937 gen{5125122}; | |
26 | std::normal_distribution<Real> dis{0,3}; | |
27 | std::vector<Real> v(1024); | |
28 | for (auto & x : v) { | |
29 | x = dis(gen); | |
30 | } | |
31 | ||
32 | Real mu = boost::math::statistics::mean(v); | |
33 | ||
1e59de90 TL |
34 | std::pair<Real, Real> temp = boost::math::statistics::one_sample_t_test(v, mu); |
35 | Real computed_statistic = std::get<0>(temp); | |
36 | Real computed_pvalue = std::get<1>(temp); | |
92f5a8d4 TL |
37 | |
38 | CHECK_MOLLIFIED_CLOSE(Real(0), computed_statistic, 10*std::numeric_limits<Real>::epsilon()); | |
39 | CHECK_ULP_CLOSE(Real(1), computed_pvalue, 9); | |
40 | } | |
41 | ||
1e59de90 TL |
42 | template<typename Real> |
43 | void test_multiprecision_exact_mean() | |
44 | { | |
45 | std::mt19937 gen{5125122}; | |
46 | std::normal_distribution<long double> dis{0,3}; | |
47 | std::vector<Real> v(1024); | |
48 | for (auto & x : v) { | |
49 | x = dis(gen); | |
50 | } | |
51 | ||
52 | Real mu = boost::math::statistics::mean(v); | |
53 | ||
54 | std::pair<Real, Real> temp = boost::math::statistics::one_sample_t_test(v, mu); | |
55 | Real computed_statistic = std::get<0>(temp); | |
56 | Real computed_pvalue = std::get<1>(temp); | |
57 | ||
58 | CHECK_MOLLIFIED_CLOSE(Real(0), computed_statistic, 15*std::numeric_limits<Real>::epsilon()); | |
59 | CHECK_ULP_CLOSE(Real(1), computed_pvalue, 25); | |
60 | } | |
61 | ||
62 | template<typename Z> | |
63 | void test_integer() | |
64 | { | |
65 | // https://www.wolframalpha.com/input/?i=t+test | |
66 | std::pair<double, double> temp = boost::math::statistics::one_sample_t_test(Z(12), Z(5*5), Z(25), Z(10)); | |
67 | double computed_statistic = std::get<0>(temp); | |
68 | double computed_pvalue = std::get<1>(temp); | |
69 | CHECK_MOLLIFIED_CLOSE(2.0, computed_statistic, 10*std::numeric_limits<double>::epsilon()); | |
70 | CHECK_MOLLIFIED_CLOSE(0.02847*2, computed_pvalue, 0.00001); | |
71 | } | |
72 | ||
92f5a8d4 TL |
73 | void test_agreement_with_mathematica() |
74 | { | |
75 | // Reproduce via: | |
76 | //data = RandomReal[NormalDistribution[], 128]; | |
77 | //NumberForm[data, 16] | |
78 | //NumberForm[TTest[data, 0.0, "TestStatistic"], 16] | |
79 | //NumberForm[TTest[data, 0.0, "PValue"], 16] | |
80 | std::vector<double> v{1.270498757865948,-0.7097895555907483,1.151445006538434,0.915648732663531,-0.7480131480881454,-0.6837323220203325, | |
81 | 2.362877076786142,2.438188734959438,0.1644154283470843,-0.980857299461513,-0.1448627006957758,0.04901437671768214, | |
82 | -0.3895499730435337,1.412356512608596,-0.3865249523080916,-0.6159322168089271,-0.1865107372684944,-0.152509328597876, | |
83 | 1.142603106429423,-1.358368106645048,0.2268475747885975,0.4029249376986136,0.1167407378850566,0.05532794835680535, | |
84 | -1.928794899326586,0.6496438708570567,0.269012797381103,-0.908168796067257,-0.6194990582309883,1.606256899489664, | |
85 | -0.903964536847682,-1.375889704354273,0.04906080087803202,0.2039077019578547,-0.4907377045195846,-0.4781929001716083, | |
86 | -0.2289802280011548,-1.339055086640687,-0.3120811524451416,0.06142580393246503,-0.140496390441262,-0.6482824149508374, | |
87 | -0.2944027976542998,1.619416512991051,0.6285648262611375,1.312636016409526,-1.109965359363169,-0.774547681114892, | |
88 | -0.344875897907528,0.816762481553918,0.1500701005574458,0.807790349338737,-0.2052962007348396,1.057657121384678, | |
89 | 0.836142529983228,0.3432803448381389,-0.01268905497569333,-1.144036865790547,-0.4530056923174255,-0.3061160863293071, | |
90 | -0.02963689772198411,-1.33671649419749,-0.06052105439831394,0.973282554859066,-1.643904288065807,-1.0293884110541, | |
91 | -0.5291066659852803,-0.3294227039691209,0.002993387508002654,0.2248580674319177,0.574521694409057,1.041337304293327, | |
92 | 0.4078548122453237,0.1112225876991191,-0.6448072259486091,-0.3051345048257077,0.089593933234481,0.4611768867673915, | |
93 | 0.7644315320471444,-0.341247840010495,0.0326958894744302,-0.05121900335567795,-0.06019531049352196,1.71234441194424, | |
94 | -0.04175157932686885,0.769694813995503,-1.080913235981393,0.5989354496438777,-0.84416230123901,0.03165655009402087, | |
95 | -0.7502374585144876,-2.734748382516766,1.541068679878993,0.1054620771416859,-0.6543692934553028,1.499220114211276, | |
96 | -0.342006571062175,-0.2053132127077213,0.5457125644270833,-0.7956250897267784,0.7320742348115779,0.4674423735122585, | |
97 | -0.3087396963145776,-1.53764162258267,0.2455449906251891,0.3795993803250636,-0.1195480230909131,0.137639511052913, | |
98 | 0.931721348902457,0.06704522870668304,-0.03773030445251862,0.3888322348695948,-0.06366757901233728,0.5563758371320388, | |
99 | -0.7918177216642121,-0.7566297580399533,-0.3740377818446702,-0.6065664299451118,-0.2341124269010213,2.028052675971757, | |
100 | 0.378550889251416,0.816911727914731,1.162652387697876,-0.3853743867873177,1.196620648443396,0.01265660717000745, | |
101 | 1.816698960862263,-0.972941421015463}; | |
102 | ||
103 | ||
104 | double expected_statistic = 0.4587075249160456; | |
105 | double expected_pvalue = 0.6472282548266728; | |
106 | ||
1e59de90 TL |
107 | std::pair<double, double> temp = boost::math::statistics::one_sample_t_test(v, 0.0); |
108 | double computed_statistic = std::get<0>(temp); | |
109 | double computed_pvalue = std::get<1>(temp); | |
92f5a8d4 TL |
110 | |
111 | CHECK_ULP_CLOSE(expected_statistic, computed_statistic, 8); | |
112 | CHECK_ULP_CLOSE(expected_pvalue, computed_pvalue, 90); | |
113 | ||
114 | ||
115 | { | |
116 | std::vector<double> v = {0.7304375676969546,3.227250635039257,1.01821954205186}; | |
117 | ||
118 | expected_statistic = 2.103013485037935; | |
119 | expected_pvalue = 0.1701790440880712; | |
120 | ||
1e59de90 TL |
121 | std::pair<double, double> temp = boost::math::statistics::one_sample_t_test(v, 0.0); |
122 | double computed_statistic = std::get<0>(temp); | |
123 | double computed_pvalue = std::get<1>(temp); | |
92f5a8d4 TL |
124 | CHECK_ULP_CLOSE(expected_statistic, computed_statistic, 2); |
125 | CHECK_ULP_CLOSE(expected_pvalue, computed_pvalue, 7); | |
126 | } | |
127 | } | |
128 | ||
1e59de90 TL |
129 | template<typename Real> |
130 | void test_two_sample_t() | |
131 | { | |
132 | std::pair<Real, Real> temp = | |
133 | boost::math::statistics::detail::two_sample_t_test_impl<std::pair<Real, Real>>(Real(10.0), Real(1.0), Real(20), Real(5.0), Real(0.25), Real(20)); | |
134 | Real computed_statistic = std::get<0>(temp); | |
135 | Real computed_pvalue = std::get<1>(temp); | |
136 | CHECK_ULP_CLOSE(Real(20), computed_statistic, 5); | |
137 | CHECK_MOLLIFIED_CLOSE(Real(0), computed_pvalue, 1e-21); | |
138 | ||
139 | std::vector<Real> set_1 {301, 298, 295, 297, 304, 305, 309, 298, 291, 299, 293, 304}; | |
140 | ||
141 | temp = boost::math::statistics::two_sample_t_test(set_1, set_1); | |
142 | Real computed_statistic_2 = std::get<0>(temp); | |
143 | Real computed_pvalue_2 = std::get<1>(temp); | |
144 | CHECK_ULP_CLOSE(Real(0), computed_statistic_2, 5); | |
145 | CHECK_ULP_CLOSE(Real(1), computed_pvalue_2, 5); | |
146 | } | |
147 | ||
148 | template<typename Z> | |
149 | void test_integer_two_sample_t() | |
150 | { | |
151 | std::pair<double, double> temp = | |
152 | boost::math::statistics::detail::two_sample_t_test_impl<std::pair<double, double>>(Z(10), Z(4), Z(20), Z(5), Z(1), Z(20)); | |
153 | double computed_statistic = std::get<0>(temp); | |
154 | CHECK_ULP_CLOSE(10.0, computed_statistic, 5); | |
155 | ||
156 | std::vector<Z> set_1 {301, 298, 295, 297, 304, 305, 309, 298, 291, 299, 293, 304}; | |
157 | ||
158 | temp = boost::math::statistics::two_sample_t_test(set_1, set_1); | |
159 | double computed_statistic_2 = std::get<0>(temp); | |
160 | double computed_pvalue_2 = std::get<1>(temp); | |
161 | CHECK_ULP_CLOSE(0.0, computed_statistic_2, 5); | |
162 | CHECK_ULP_CLOSE(1.0, computed_pvalue_2, 5); | |
163 | } | |
164 | ||
165 | template<typename Real> | |
166 | void test_welch() | |
167 | { | |
168 | using std::sqrt; | |
169 | ||
170 | std::pair<Real, Real> temp = | |
171 | boost::math::statistics::detail::welchs_t_test_impl<std::pair<Real, Real>>(Real(10.0), Real(1.0), Real(20), Real(5.0), Real(0.25), Real(20)); | |
172 | Real computed_statistic = std::get<0>(temp); | |
173 | Real computed_pvalue = std::get<1>(temp); | |
174 | CHECK_ULP_CLOSE(Real(20), computed_statistic, 5); | |
175 | CHECK_MOLLIFIED_CLOSE(Real(0), computed_pvalue, 5e-18); | |
176 | ||
177 | temp = boost::math::statistics::detail::welchs_t_test_impl<std::pair<Real, Real>>(Real(10.0), Real(0.5), Real(20), Real(10.0), Real(0.5), Real(20)); | |
178 | Real computed_statistic_2 = std::get<0>(temp); | |
179 | Real computed_pvalue_2 = std::get<1>(temp); | |
180 | CHECK_ULP_CLOSE(Real(0), computed_statistic_2, 5); | |
181 | CHECK_ULP_CLOSE(Real(1), computed_pvalue_2, 5); | |
182 | } | |
183 | ||
184 | template<typename Z> | |
185 | void test_integer_welch() | |
186 | { | |
187 | std::pair<double, double> temp = | |
188 | boost::math::statistics::detail::welchs_t_test_impl<std::pair<double, double>>(10.0, 4.0, 20.0, 5.0, 1.0, 20.0); | |
189 | double computed_statistic = std::get<0>(temp); | |
190 | CHECK_ULP_CLOSE(10.0, computed_statistic, 5); | |
191 | ||
192 | temp = boost::math::statistics::detail::welchs_t_test_impl<std::pair<double, double>>(10.0, 0.5, 20.0, 10.0, 0.5, 20.0); | |
193 | double computed_statistic_2 = std::get<0>(temp); | |
194 | double computed_pvalue_2 = std::get<1>(temp); | |
195 | CHECK_ULP_CLOSE(0.0, computed_statistic_2, 5); | |
196 | CHECK_ULP_CLOSE(1.0, computed_pvalue_2, 5); | |
197 | } | |
198 | ||
199 | template<typename Real> | |
200 | void test_paired_samples() | |
201 | { | |
202 | std::vector<Real> set_1 {2,4}; | |
203 | std::vector<Real> set_2 {1,2}; | |
204 | ||
205 | std::pair<Real, Real> temp = boost::math::statistics::paired_samples_t_test(set_1, set_2); | |
206 | Real computed_statistic = std::get<0>(temp); | |
207 | CHECK_ULP_CLOSE(Real(3), computed_statistic, 5); | |
208 | } | |
209 | ||
210 | template<typename Z> | |
211 | void test_integer_paired_samples() | |
212 | { | |
213 | std::vector<Z> set_1 {2,4}; | |
214 | std::vector<Z> set_2 {1,2}; | |
215 | ||
216 | std::pair<double, double> temp = boost::math::statistics::paired_samples_t_test(set_1, set_2); | |
217 | double computed_statistic = std::get<0>(temp); | |
218 | CHECK_ULP_CLOSE(3.0, computed_statistic, 5); | |
219 | } | |
92f5a8d4 TL |
220 | |
221 | int main() | |
222 | { | |
223 | test_agreement_with_mathematica(); | |
1e59de90 | 224 | |
92f5a8d4 TL |
225 | test_exact_mean<float>(); |
226 | test_exact_mean<double>(); | |
1e59de90 TL |
227 | |
228 | test_integer<int>(); | |
229 | test_integer<int32_t>(); | |
230 | test_integer<int64_t>(); | |
231 | test_integer<uint32_t>(); | |
232 | ||
233 | test_two_sample_t<float>(); | |
234 | test_two_sample_t<double>(); | |
235 | ||
236 | test_integer_two_sample_t<int>(); | |
237 | test_integer_two_sample_t<int32_t>(); | |
238 | test_integer_two_sample_t<int64_t>(); | |
239 | test_integer_two_sample_t<uint32_t>(); | |
240 | ||
241 | test_welch<float>(); | |
242 | test_welch<double>(); | |
243 | ||
244 | test_integer_welch<int>(); | |
245 | test_integer_welch<int32_t>(); | |
246 | test_integer_welch<int64_t>(); | |
247 | test_integer_welch<uint32_t>(); | |
248 | ||
249 | test_paired_samples<float>(); | |
250 | test_paired_samples<double>(); | |
251 | test_integer_paired_samples<int>(); | |
252 | test_integer_paired_samples<int32_t>(); | |
253 | test_integer_paired_samples<int64_t>(); | |
254 | test_integer_paired_samples<uint32_t>(); | |
255 | ||
256 | #ifndef BOOST_MATH_NO_MP_TESTS | |
257 | using quad = boost::multiprecision::cpp_bin_float_quad; | |
258 | test_multiprecision_exact_mean<quad>(); | |
259 | test_two_sample_t<quad>(); | |
260 | test_welch<quad>(); | |
261 | #endif | |
262 | ||
92f5a8d4 TL |
263 | return boost::math::test::report_errors(); |
264 | } |