test_students_t.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. // Copyright Paul A. Bristow 2006, 2017.
  2. // Copyright John Maddock 2006.
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt
  6. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. // test_students_t.cpp
  8. // http://en.wikipedia.org/wiki/Student%27s_t_distribution
  9. // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3664.htm
  10. // Basic sanity test for Student's t probability (quantile) (0. < p < 1).
  11. // and Student's t probability Quantile (0. < p < 1).
  12. #ifdef _MSC_VER
  13. # pragma warning (disable :4127) // conditional expression is constant.
  14. #endif
  15. #define BOOST_TEST_MAIN
  16. #include <boost/test/unit_test.hpp> // Boost.Test
  17. #include <boost/test/tools/floating_point_comparison.hpp>
  18. #include <boost/math/concepts/real_concept.hpp> // for real_concept
  19. #include <boost/math/tools/test.hpp> // for real_concept
  20. #include "test_out_of_range.hpp"
  21. #include <boost/math/distributions/students_t.hpp>
  22. using boost::math::students_t_distribution;
  23. #include <iostream>
  24. using std::cout;
  25. using std::endl;
  26. using std::setprecision;
  27. #include <limits>
  28. using std::numeric_limits;
  29. template <class RealType>
  30. RealType naive_pdf(RealType v, RealType t)
  31. {
  32. // Calculate the pdf of the students t in a deliberately
  33. // naive way, using equation (5) from
  34. // http://mathworld.wolfram.com/Studentst-Distribution.html
  35. // This is equivalent to, but a different method
  36. // to the one in the actual implementation, so can be used as
  37. // a very basic sanity check. However some published values
  38. // would be nice....
  39. using namespace std; // for ADL
  40. using boost::math::beta;
  41. //return pow(v / (v + t*t), (1+v) / 2) / (sqrt(v) * beta(v/2, RealType(0.5f)));
  42. RealType result = boost::math::tgamma_ratio((v+1)/2, v/2);
  43. result /= sqrt(v * boost::math::constants::pi<RealType>());
  44. result /= pow(1 + t*t/v, (v+1)/2);
  45. return result;
  46. }
  47. template <class RealType>
  48. void test_spots(RealType)
  49. {
  50. // Basic sanity checks
  51. RealType tolerance = static_cast<RealType>(1e-4); // 1e-6 (as %)
  52. // Some tests only pass at 1e-5 because probability value is less accurate,
  53. // a digit in 6th decimal place, although calculated using
  54. // a t-distribution generator (claimed 6 decimal digits) at
  55. // http://faculty.vassar.edu/lowry/VassarStats.html
  56. // http://faculty.vassar.edu/lowry/tsamp.html
  57. // df = 5, +/-t = 2.0, 1-tailed = 0.050970, 2-tailed = 0.101939
  58. cout << "Tolerance for type " << typeid(RealType).name() << " is " << tolerance << " %" << endl;
  59. // http://en.wikipedia.org/wiki/Student%27s_t_distribution#Table_of_selected_values
  60. // Using tabulated value of t = 3.182 for 0.975, 3 df, one-sided.
  61. // http://www.mth.kcl.ac.uk/~shaww/web_page/papers/Tdistribution06.pdf refers to:
  62. // A lookup table of quantiles of the RealType distribution
  63. // for 1 to 25 in steps of 0.1 is provided in CSV form at:
  64. // www.mth.kcl.ac.uk/~shaww/web_page/papers/Tsupp/tquantiles.csv
  65. // gives accurate t of -3.1824463052837 and 3 degrees of freedom.
  66. // Values below are from this source, saved as tquantiles.xls.
  67. // DF are across the columns, probabilities down the rows
  68. // and the t- values (quantiles) are shown.
  69. // These values are probably accurate to nearly 64-bit double
  70. // (perhaps 14 decimal digits).
  71. BOOST_CHECK_CLOSE(
  72. ::boost::math::cdf(
  73. students_t_distribution<RealType>(2), // degrees_of_freedom
  74. static_cast<RealType>(-6.96455673428326)), // t
  75. static_cast<RealType>(0.01), // probability.
  76. tolerance); // %
  77. BOOST_CHECK_CLOSE(
  78. ::boost::math::cdf(
  79. students_t_distribution<RealType>(5), // degrees_of_freedom
  80. static_cast<RealType>(-3.36492999890721)), // t
  81. static_cast<RealType>(0.01), // probability.
  82. tolerance);
  83. BOOST_CHECK_CLOSE(
  84. ::boost::math::cdf(
  85. students_t_distribution<RealType>(1), // degrees_of_freedom
  86. static_cast<RealType>(-31830.988607907)), // t
  87. static_cast<RealType>(0.00001), // probability.
  88. tolerance);
  89. BOOST_CHECK_CLOSE(
  90. ::boost::math::cdf(
  91. students_t_distribution<RealType>(25.), // degrees_of_freedom
  92. static_cast<RealType>(-5.2410429995425)), // t
  93. static_cast<RealType>(0.00001), // probability.
  94. tolerance);
  95. BOOST_CHECK_CLOSE(
  96. ::boost::math::cdf(
  97. students_t_distribution<RealType>(1), // degrees_of_freedom
  98. static_cast<RealType>(-63661.97723)), // t
  99. static_cast<RealType>(0.000005), // probability.
  100. tolerance);
  101. BOOST_CHECK_CLOSE(
  102. ::boost::math::cdf(
  103. students_t_distribution<RealType>(5.), // degrees_of_freedom
  104. static_cast<RealType>(-17.89686614)), // t
  105. static_cast<RealType>(0.000005), // probability.
  106. tolerance);
  107. BOOST_CHECK_CLOSE(
  108. ::boost::math::cdf(
  109. students_t_distribution<RealType>(25.), // degrees_of_freedom
  110. static_cast<RealType>(-5.510848412)), // t
  111. static_cast<RealType>(0.000005), // probability.
  112. tolerance);
  113. BOOST_CHECK_CLOSE(
  114. ::boost::math::cdf(
  115. students_t_distribution<RealType>(10.), // degrees_of_freedom
  116. static_cast<RealType>(-1.812461123)), // t
  117. static_cast<RealType>(0.05), // probability.
  118. tolerance);
  119. BOOST_CHECK_CLOSE(
  120. ::boost::math::cdf(
  121. students_t_distribution<RealType>(10), // degrees_of_freedom
  122. static_cast<RealType>(1.812461123)), // t
  123. static_cast<RealType>(0.95), // probability.
  124. tolerance);
  125. BOOST_CHECK_CLOSE(
  126. ::boost::math::cdf(
  127. complement(
  128. students_t_distribution<RealType>(10), // degrees_of_freedom
  129. static_cast<RealType>(1.812461123))), // t
  130. static_cast<RealType>(0.05), // probability.
  131. tolerance);
  132. BOOST_CHECK_CLOSE(
  133. ::boost::math::cdf(
  134. students_t_distribution<RealType>(10), // degrees_of_freedom
  135. static_cast<RealType>(9.751995491)), // t
  136. static_cast<RealType>(0.999999), // probability.
  137. tolerance);
  138. BOOST_CHECK_CLOSE(
  139. ::boost::math::cdf(
  140. students_t_distribution<RealType>(10.), // degrees_of_freedom - for ALL degrees_of_freedom!
  141. static_cast<RealType>(0.)), // t
  142. static_cast<RealType>(0.5), // probability.
  143. tolerance);
  144. // Student's t Inverse function tests.
  145. // Special cases
  146. BOOST_MATH_CHECK_THROW(boost::math::quantile(
  147. students_t_distribution<RealType>(1.), // degrees_of_freedom (ignored).
  148. static_cast<RealType>(0)), std::overflow_error); // t == -infinity.
  149. BOOST_MATH_CHECK_THROW(boost::math::quantile(
  150. students_t_distribution<RealType>(1.), // degrees_of_freedom (ignored).
  151. static_cast<RealType>(1)), std::overflow_error); // t == +infinity.
  152. BOOST_CHECK_EQUAL(boost::math::quantile(
  153. students_t_distribution<RealType>(1.), // degrees_of_freedom (ignored).
  154. static_cast<RealType>(0.5)), // probability == half - special case.
  155. static_cast<RealType>(0)); // t == zero.
  156. BOOST_CHECK_EQUAL(boost::math::quantile(
  157. complement(
  158. students_t_distribution<RealType>(1.), // degrees_of_freedom (ignored).
  159. static_cast<RealType>(0.5))), // probability == half - special case.
  160. static_cast<RealType>(0)); // t == zero.
  161. BOOST_CHECK_CLOSE(boost::math::quantile(
  162. students_t_distribution<RealType>(1.), // degrees_of_freedom (ignored).
  163. static_cast<RealType>(0.5)), // probability == half - special case.
  164. static_cast<RealType>(0), // t == zero.
  165. tolerance);
  166. BOOST_CHECK_CLOSE( // Tests of p middling.
  167. ::boost::math::cdf(
  168. students_t_distribution<RealType>(5.), // degrees_of_freedom
  169. static_cast<RealType>(-0.559429644)), // t
  170. static_cast<RealType>(0.3), // probability.
  171. tolerance);
  172. BOOST_CHECK_CLOSE(
  173. ::boost::math::quantile(
  174. students_t_distribution<RealType>(5.), // degrees_of_freedom
  175. static_cast<RealType>(0.3)), // probability.
  176. static_cast<RealType>(-0.559429644), // t
  177. tolerance);
  178. BOOST_CHECK_CLOSE(
  179. ::boost::math::quantile(
  180. complement(
  181. students_t_distribution<RealType>(5.), // degrees_of_freedom
  182. static_cast<RealType>(0.7))), // probability.
  183. static_cast<RealType>(-0.559429644), // t
  184. tolerance);
  185. BOOST_CHECK_CLOSE( // Tests of p high.
  186. ::boost::math::cdf(
  187. students_t_distribution<RealType>(5.), // degrees_of_freedom
  188. static_cast<RealType>(1.475884049)), // t
  189. static_cast<RealType>(0.9), // probability.
  190. tolerance);
  191. BOOST_CHECK_CLOSE(
  192. ::boost::math::quantile(
  193. students_t_distribution<RealType>(5.), // degrees_of_freedom
  194. static_cast<RealType>(0.9)), // probability.
  195. static_cast<RealType>(1.475884049), // t
  196. tolerance);
  197. BOOST_CHECK_CLOSE( // Tests of p low.
  198. ::boost::math::cdf(
  199. students_t_distribution<RealType>(5.), // degrees_of_freedom
  200. static_cast<RealType>(-1.475884049)), // t
  201. static_cast<RealType>(0.1), // probability.
  202. tolerance);
  203. BOOST_CHECK_CLOSE(
  204. ::boost::math::quantile(
  205. students_t_distribution<RealType>(5.), // degrees_of_freedom
  206. static_cast<RealType>(0.1)), // probability.
  207. static_cast<RealType>(-1.475884049), // t
  208. tolerance);
  209. BOOST_CHECK_CLOSE(
  210. ::boost::math::cdf(
  211. students_t_distribution<RealType>(2.), // degrees_of_freedom
  212. static_cast<RealType>(-6.96455673428326)), // t
  213. static_cast<RealType>(0.01), // probability.
  214. tolerance);
  215. BOOST_CHECK_CLOSE(
  216. ::boost::math::quantile(
  217. students_t_distribution<RealType>(2.), // degrees_of_freedom
  218. static_cast<RealType>(0.01)), // probability.
  219. static_cast<RealType>(-6.96455673428326), // t
  220. tolerance);
  221. //
  222. // Some special tests to exercise the double-precision approximations
  223. // to the quantile:
  224. //
  225. // tolerance is 50 eps expressed as a persent:
  226. //
  227. tolerance = boost::math::tools::epsilon<RealType>() * 5000;
  228. BOOST_CHECK_CLOSE(boost::math::quantile(
  229. students_t_distribution<RealType>(2.00390625L), // degrees_of_freedom.
  230. static_cast<RealType>(0.5625L)), // probability.
  231. static_cast<RealType>(0.178133131573788108465134803511798566L), // t.
  232. tolerance);
  233. BOOST_CHECK_CLOSE(boost::math::quantile(
  234. students_t_distribution<RealType>(1L), // degrees_of_freedom.
  235. static_cast<RealType>(0.03125L)), // probability.
  236. static_cast<RealType>(-10.1531703876088604621071476634194722L), // t.
  237. tolerance);
  238. BOOST_CHECK_CLOSE(boost::math::quantile(
  239. students_t_distribution<RealType>(1L), // degrees_of_freedom.
  240. static_cast<RealType>(0.875L)), // probability.
  241. static_cast<RealType>(2.41421356237309504880168872421390942L), // t.
  242. tolerance);
  243. BOOST_CHECK_CLOSE(boost::math::quantile(
  244. students_t_distribution<RealType>(2L), // degrees_of_freedom.
  245. static_cast<RealType>(0.03125L)), // probability.
  246. static_cast<RealType>(-3.81000381000571500952501666878143315L), // t.
  247. tolerance);
  248. BOOST_CHECK_CLOSE(boost::math::quantile(
  249. students_t_distribution<RealType>(2L), // degrees_of_freedom.
  250. static_cast<RealType>(0.875L)), // probability.
  251. static_cast<RealType>(1.60356745147454630810732088527854144L), // t.
  252. tolerance);
  253. BOOST_CHECK_CLOSE(boost::math::quantile(
  254. students_t_distribution<RealType>(4L), // degrees_of_freedom.
  255. static_cast<RealType>(0.03125L)), // probability.
  256. static_cast<RealType>(-2.56208431914409044861223047927635034L), // t.
  257. tolerance);
  258. BOOST_CHECK_CLOSE(boost::math::quantile(
  259. students_t_distribution<RealType>(4L), // degrees_of_freedom.
  260. static_cast<RealType>(0.875L)), // probability.
  261. static_cast<RealType>(1.34439755550909142430681981315923574L), // t.
  262. tolerance);
  263. BOOST_CHECK_CLOSE(boost::math::quantile(
  264. students_t_distribution<RealType>(6L), // degrees_of_freedom.
  265. static_cast<RealType>(0.03125L)), // probability.
  266. static_cast<RealType>(-2.28348667906973065861212495010082952L), // t.
  267. tolerance);
  268. BOOST_CHECK_CLOSE(boost::math::quantile(
  269. students_t_distribution<RealType>(6L), // degrees_of_freedom.
  270. static_cast<RealType>(0.875L)), // probability.
  271. static_cast<RealType>(1.27334930914664286821103236660071906L), // t.
  272. tolerance);
  273. BOOST_CHECK_CLOSE(boost::math::quantile(
  274. students_t_distribution<RealType>(8L), // degrees_of_freedom.
  275. static_cast<RealType>(0.03125L)), // probability.
  276. static_cast<RealType>(-2.16296475406014719458642055768894376L), // t.
  277. tolerance);
  278. BOOST_CHECK_CLOSE(boost::math::quantile(
  279. students_t_distribution<RealType>(8L), // degrees_of_freedom.
  280. static_cast<RealType>(0.875L)), // probability.
  281. static_cast<RealType>(1.24031826078267310637634677726479038L), // t.
  282. tolerance);
  283. BOOST_CHECK_CLOSE(boost::math::quantile(
  284. students_t_distribution<RealType>(10L), // degrees_of_freedom.
  285. static_cast<RealType>(0.03125L)), // probability.
  286. static_cast<RealType>(-2.09596136475109350926340169211429572L), // t.
  287. tolerance);
  288. BOOST_CHECK_CLOSE(boost::math::quantile(
  289. students_t_distribution<RealType>(10L), // degrees_of_freedom.
  290. static_cast<RealType>(0.875L)), // probability.
  291. static_cast<RealType>(1.2212553950039221407185188573696834L), // t.
  292. tolerance);
  293. BOOST_CHECK_CLOSE(boost::math::quantile(
  294. students_t_distribution<RealType>(2.125L), // degrees_of_freedom.
  295. static_cast<RealType>(0.03125L)), // probability.
  296. static_cast<RealType>(-3.62246031671091980110493455859296532L), // t.
  297. tolerance);
  298. BOOST_CHECK_CLOSE(boost::math::quantile(
  299. students_t_distribution<RealType>(2.125L), // degrees_of_freedom.
  300. static_cast<RealType>(0.875L)), // probability.
  301. static_cast<RealType>(1.56905270993307293450392958697861969L), // t.
  302. tolerance);
  303. BOOST_CHECK_CLOSE(boost::math::quantile(
  304. students_t_distribution<RealType>(3L), // degrees_of_freedom.
  305. static_cast<RealType>(0.03125L)), // probability.
  306. static_cast<RealType>(-2.90004411882995814036141778367917946L), // t.
  307. tolerance);
  308. BOOST_CHECK_CLOSE(boost::math::quantile(
  309. students_t_distribution<RealType>(3L), // degrees_of_freedom.
  310. static_cast<RealType>(0.875L)), // probability.
  311. static_cast<RealType>(1.42262528146180931868169289781115099L), // t.
  312. tolerance);
  313. if(boost::is_floating_point<RealType>::value)
  314. {
  315. BOOST_CHECK_CLOSE(boost::math::cdf(
  316. students_t_distribution<RealType>(1e30f),
  317. boost::math::quantile(
  318. students_t_distribution<RealType>(1e30f), static_cast<RealType>(0.25f))),
  319. static_cast<RealType>(0.25f), tolerance);
  320. BOOST_CHECK_CLOSE(boost::math::cdf(
  321. students_t_distribution<RealType>(1e20f),
  322. boost::math::quantile(
  323. students_t_distribution<RealType>(1e20f), static_cast<RealType>(0.25f))),
  324. static_cast<RealType>(0.25f), tolerance);
  325. BOOST_CHECK_CLOSE(boost::math::cdf(
  326. students_t_distribution<RealType>(static_cast<RealType>(0x7FFFFFFF)),
  327. boost::math::quantile(
  328. students_t_distribution<RealType>(static_cast<RealType>(0x7FFFFFFF)), static_cast<RealType>(0.25f))),
  329. static_cast<RealType>(0.25f), tolerance);
  330. BOOST_CHECK_CLOSE(boost::math::cdf(
  331. students_t_distribution<RealType>(static_cast<RealType>(0x10000000)),
  332. boost::math::quantile(
  333. students_t_distribution<RealType>(static_cast<RealType>(0x10000000)), static_cast<RealType>(0.25f))),
  334. static_cast<RealType>(0.25f), tolerance);
  335. BOOST_CHECK_CLOSE(boost::math::cdf(
  336. students_t_distribution<RealType>(static_cast<RealType>(0x0fffffff)),
  337. boost::math::quantile(
  338. students_t_distribution<RealType>(static_cast<RealType>(0x0fffffff)), static_cast<RealType>(0.25f))),
  339. static_cast<RealType>(0.25f), tolerance);
  340. }
  341. // Student's t pdf tests.
  342. // for PDF checks, use 100 eps tolerance expressed as a percent:
  343. tolerance = boost::math::tools::epsilon<RealType>() * 10000;
  344. for(unsigned i = 1; i < 20; i += 3)
  345. {
  346. for(RealType r = -10; r < 10; r += 0.125)
  347. {
  348. //std::cout << "df=" << i << " t=" << r << std::endl;
  349. BOOST_CHECK_CLOSE(
  350. boost::math::pdf(
  351. students_t_distribution<RealType>(static_cast<RealType>(i)),
  352. r),
  353. naive_pdf<RealType>(static_cast<RealType>(i), r),
  354. tolerance);
  355. }
  356. }
  357. RealType tol2 = boost::math::tools::epsilon<RealType>() * 5;
  358. students_t_distribution<RealType> dist(8);
  359. RealType x = static_cast<RealType>(0.125);
  360. using namespace std; // ADL of std names.
  361. // mean:
  362. BOOST_CHECK_CLOSE(
  363. mean(dist)
  364. , static_cast<RealType>(0), tol2);
  365. // variance:
  366. // BOOST_CHECK_CLOSE(
  367. // variance(dist)
  368. // , static_cast<RealType>(13.0L / 6.0L), tol2);
  369. //// was , static_cast<RealType>(8.0L / 6.0L), tol2);
  370. // std deviation:
  371. BOOST_CHECK_CLOSE(
  372. standard_deviation(dist)
  373. , static_cast<RealType>(sqrt(8.0L / 6.0L)), tol2);
  374. // hazard:
  375. BOOST_CHECK_CLOSE(
  376. hazard(dist, x)
  377. , pdf(dist, x) / cdf(complement(dist, x)), tol2);
  378. // cumulative hazard:
  379. BOOST_CHECK_CLOSE(
  380. chf(dist, x)
  381. , -log(cdf(complement(dist, x))), tol2);
  382. // coefficient_of_variation:
  383. BOOST_MATH_CHECK_THROW(
  384. coefficient_of_variation(dist),
  385. std::overflow_error);
  386. // mode:
  387. BOOST_CHECK_CLOSE(
  388. mean(dist)
  389. , static_cast<RealType>(0), tol2);
  390. // median:
  391. BOOST_CHECK_CLOSE(
  392. median(dist)
  393. , static_cast<RealType>(0), tol2);
  394. // skewness:
  395. BOOST_CHECK_CLOSE(
  396. skewness(dist)
  397. , static_cast<RealType>(0), tol2);
  398. // kurtosis:
  399. BOOST_CHECK_CLOSE(
  400. kurtosis(dist)
  401. , static_cast<RealType>(4.5), tol2);
  402. // kurtosis excess:
  403. BOOST_CHECK_CLOSE(
  404. kurtosis_excess(dist)
  405. , static_cast<RealType>(1.5), tol2);
  406. // Parameter estimation. These results are close to but
  407. // not identical to those reported on the NIST website at
  408. // http://www.itl.nist.gov/div898/handbook/prc/section2/prc222.htm
  409. // the NIST results appear to be calculated using a normal
  410. // approximation, which slightly under-estimates the degrees of
  411. // freedom required, particularly when the result is small.
  412. //
  413. BOOST_CHECK_EQUAL(
  414. ceil(students_t_distribution<RealType>::find_degrees_of_freedom(
  415. static_cast<RealType>(0.5),
  416. static_cast<RealType>(0.005),
  417. static_cast<RealType>(0.01),
  418. static_cast<RealType>(1.0))),
  419. 99);
  420. BOOST_CHECK_EQUAL(
  421. ceil(students_t_distribution<RealType>::find_degrees_of_freedom(
  422. static_cast<RealType>(1.5),
  423. static_cast<RealType>(0.005),
  424. static_cast<RealType>(0.01),
  425. static_cast<RealType>(1.0))),
  426. 14);
  427. BOOST_CHECK_EQUAL(
  428. ceil(students_t_distribution<RealType>::find_degrees_of_freedom(
  429. static_cast<RealType>(0.5),
  430. static_cast<RealType>(0.025),
  431. static_cast<RealType>(0.01),
  432. static_cast<RealType>(1.0))),
  433. 76);
  434. BOOST_CHECK_EQUAL(
  435. ceil(students_t_distribution<RealType>::find_degrees_of_freedom(
  436. static_cast<RealType>(1.5),
  437. static_cast<RealType>(0.025),
  438. static_cast<RealType>(0.01),
  439. static_cast<RealType>(1.0))),
  440. 11);
  441. BOOST_CHECK_EQUAL(
  442. ceil(students_t_distribution<RealType>::find_degrees_of_freedom(
  443. static_cast<RealType>(0.5),
  444. static_cast<RealType>(0.05),
  445. static_cast<RealType>(0.01),
  446. static_cast<RealType>(1.0))),
  447. 65);
  448. BOOST_CHECK_EQUAL(
  449. ceil(students_t_distribution<RealType>::find_degrees_of_freedom(
  450. static_cast<RealType>(1.5),
  451. static_cast<RealType>(0.05),
  452. static_cast<RealType>(0.01),
  453. static_cast<RealType>(1.0))),
  454. 9);
  455. // Test for large degrees of freedom when should be same as normal.
  456. RealType inf = std::numeric_limits<RealType>::infinity();
  457. RealType nan = std::numeric_limits<RealType>::quiet_NaN();
  458. std::string type = typeid(RealType).name();
  459. // if (type != "class boost::math::concepts::real_concept") fails for gcc
  460. if (typeid(RealType) != typeid(boost::math::concepts::real_concept))
  461. { // Ordinary floats only.
  462. RealType limit = 1/ boost::math::tools::epsilon<RealType>();
  463. // Default policy to get full accuracy.
  464. // std::cout << "Switch over to normal if df > " << limit << std::endl;
  465. // float Switch over to normal if df > 8.38861e+006
  466. // double Switch over to normal if df > 4.5036e+015
  467. // Can't test real_concept - doesn't converge.
  468. boost::math::normal_distribution<RealType> n(0, 1); //
  469. students_t_distribution<RealType> st(boost::math::tools::max_value<RealType>()); // Well over the switchover point,
  470. // PDF
  471. BOOST_CHECK_EQUAL(pdf(st, 0), pdf(n, 0.)); // Should be exactly equal.
  472. students_t_distribution<RealType> st2(limit /5 ); // Just below the switchover point,
  473. BOOST_CHECK_CLOSE_FRACTION(pdf(st2, 0), pdf(n, 0.), tolerance); // Should be very close to normal.
  474. // CDF
  475. BOOST_CHECK_EQUAL(cdf(st, 0), cdf(n, 0.)); // Should be exactly equal.
  476. BOOST_CHECK_CLOSE_FRACTION(cdf(st2, 0), cdf(n, 0.), tolerance); // Should be very close to normal.
  477. // Tests for df = infinity.
  478. students_t_distribution<RealType> infdf(inf);
  479. BOOST_CHECK_EQUAL(infdf.degrees_of_freedom(), inf);
  480. BOOST_CHECK_EQUAL(mean(infdf), 0); // OK.
  481. #ifndef BOOST_NO_EXCEPTIONS
  482. BOOST_MATH_CHECK_THROW(students_t_distribution<RealType> minfdf(-inf), std::domain_error);
  483. BOOST_MATH_CHECK_THROW(students_t_distribution<RealType> minfdf(nan), std::domain_error);
  484. BOOST_MATH_CHECK_THROW(students_t_distribution<RealType> minfdf(-nan), std::domain_error);
  485. #endif
  486. BOOST_CHECK_EQUAL(pdf(infdf, -inf), 0);
  487. BOOST_CHECK_EQUAL(pdf(infdf, +inf), 0);
  488. BOOST_CHECK_EQUAL(cdf(infdf, -inf), 0);
  489. BOOST_CHECK_EQUAL(cdf(infdf, +inf), 1);
  490. // BOOST_CHECK_CLOSE_FRACTION(pdf(infdf, 0), static_cast<RealType>(0.3989422804014326779399460599343818684759L), tolerance);
  491. BOOST_CHECK_CLOSE_FRACTION(pdf(infdf, 0),boost::math::constants::one_div_root_two_pi<RealType>() , tolerance);
  492. BOOST_CHECK_CLOSE_FRACTION(cdf(infdf, 0),boost::math::constants::half<RealType>() , tolerance);
  493. // Checks added for Trac #7717 report by Thomas Mang.
  494. BOOST_MATH_CHECK_THROW(quantile(dist, -1), std::domain_error);
  495. BOOST_MATH_CHECK_THROW(quantile(dist, 2), std::domain_error);
  496. BOOST_MATH_CHECK_THROW(pdf(students_t_distribution<RealType>(0), 0), std::domain_error);
  497. BOOST_MATH_CHECK_THROW(pdf(students_t_distribution<RealType>(-1), 0), std::domain_error);
  498. // Check on df for mean (moment k = 1)
  499. BOOST_MATH_CHECK_THROW(mean(students_t_distribution<RealType>(nan)), std::domain_error);
  500. // BOOST_MATH_CHECK_THROW(mean(students_t_distribution<RealType>(inf)), std::domain_error); inf is now OK
  501. BOOST_MATH_CHECK_THROW(mean(students_t_distribution<RealType>(-1)), std::domain_error);
  502. BOOST_MATH_CHECK_THROW(mean(students_t_distribution<RealType>(0)), std::domain_error);
  503. BOOST_MATH_CHECK_THROW(mean(students_t_distribution<RealType>(1)), std::domain_error); // df == k
  504. BOOST_CHECK_EQUAL(mean(students_t_distribution<RealType>(2)), 0); // OK.
  505. BOOST_CHECK_EQUAL(mean(students_t_distribution<RealType>(inf)), 0); // OK.
  506. // Check on df for variance (moment 2)
  507. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(nan)), std::domain_error);
  508. // BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(inf)), std::domain_error); // inf is now OK.
  509. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(-1)), std::domain_error);
  510. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(0)), std::domain_error);
  511. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(1)), std::domain_error);
  512. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(static_cast<RealType>(1.99999L))), std::domain_error);
  513. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(static_cast<RealType>(1.99999L))), std::domain_error);
  514. BOOST_MATH_CHECK_THROW(variance(students_t_distribution<RealType>(2)), std::domain_error); // df ==
  515. BOOST_CHECK_EQUAL(variance(students_t_distribution<RealType>(2.5)), 5); // OK.
  516. BOOST_CHECK_EQUAL(variance(students_t_distribution<RealType>(3)), 3); // OK.
  517. BOOST_CHECK_EQUAL(variance(students_t_distribution<RealType>(inf)), 1); // OK.
  518. // Check on df for skewness (moment 3)
  519. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(nan)), std::domain_error);
  520. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(-1)), std::domain_error);
  521. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(0)), std::domain_error);
  522. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(1)), std::domain_error);
  523. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(1.5L)), std::domain_error);
  524. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(2)), std::domain_error);
  525. BOOST_MATH_CHECK_THROW(skewness(students_t_distribution<RealType>(3)), std::domain_error); // df == k
  526. BOOST_CHECK_EQUAL(skewness(students_t_distribution<RealType>(3.5)), 0); // OK.
  527. BOOST_CHECK_EQUAL(skewness(students_t_distribution<RealType>(4)), 0); // OK.
  528. BOOST_CHECK_EQUAL(skewness(students_t_distribution<RealType>(inf)), 0); // OK.
  529. // Check on df for kurtosis_excess (moment 4)
  530. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(nan)), std::domain_error);
  531. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(-1)), std::domain_error);
  532. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(0)), std::domain_error);
  533. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(1)), std::domain_error);
  534. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(1.5L)), std::domain_error);
  535. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(2)), std::domain_error);
  536. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(static_cast<RealType>(2.1))), std::domain_error);
  537. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(3)), std::domain_error);
  538. BOOST_MATH_CHECK_THROW(kurtosis_excess(students_t_distribution<RealType>(4)), std::domain_error); // df == k
  539. BOOST_CHECK_EQUAL(kurtosis_excess(students_t_distribution<RealType>(5)), 6); // OK.
  540. BOOST_CHECK_EQUAL(kurtosis_excess(students_t_distribution<RealType>(inf)), 0); // OK.
  541. // Check on df for kurtosis (moment 4)
  542. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(nan)), std::domain_error);
  543. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(-1)), std::domain_error);
  544. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(0)), std::domain_error);
  545. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(1)), std::domain_error);
  546. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(2)), std::domain_error);
  547. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(static_cast<RealType>(2.0001L))), std::domain_error);
  548. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(3)), std::domain_error);
  549. BOOST_MATH_CHECK_THROW(kurtosis(students_t_distribution<RealType>(4)), std::domain_error); // df == k
  550. BOOST_CHECK_EQUAL(kurtosis(students_t_distribution<RealType>(5)), 9); // OK.
  551. BOOST_CHECK_EQUAL(kurtosis(students_t_distribution<RealType>(inf)), 3); // OK.
  552. }
  553. // Use a new distribution ignore_error_students_t with a custom policy to ignore all errors,
  554. // and check returned values are as expected.
  555. /*
  556. Sandia-darwin-intel-12.0 - math - test_students_t / intel-darwin-12.0
  557. ../libs/math/test/test_students_t.cpp(544): error: "domain_error" has already been declared in the current scope
  558. using boost::math::policies::domain_error;
  559. ../libs/math/test/test_students_t.cpp(552): error: "pole_error" has already been declared in the current scope
  560. using boost::math::policies::pole_error;
  561. Unclear where previous declaration is.
  562. Does not seem to be in student_t.hpp or any included files???
  563. So to avoid this perceived problem by this compiler,
  564. the ignore policy below uses fully specified names.
  565. */
  566. using boost::math::policies::policy;
  567. // Types of error whose action can be altered by policies:.
  568. //using boost::math::policies::evaluation_error;
  569. //using boost::math::policies::domain_error;
  570. //using boost::math::policies::overflow_error;
  571. //using boost::math::policies::underflow_error;
  572. //using boost::math::policies::domain_error;
  573. //using boost::math::policies::pole_error;
  574. //// Actions on error (in enum error_policy_type):
  575. //using boost::math::policies::errno_on_error;
  576. //using boost::math::policies::ignore_error;
  577. //using boost::math::policies::throw_on_error;
  578. //using boost::math::policies::denorm_error;
  579. //using boost::math::policies::pole_error;
  580. //using boost::math::policies::user_error;
  581. typedef policy<
  582. boost::math::policies::domain_error<boost::math::policies::ignore_error>,
  583. boost::math::policies::overflow_error<boost::math::policies::ignore_error>,
  584. boost::math::policies::underflow_error<boost::math::policies::ignore_error>,
  585. boost::math::policies::denorm_error<boost::math::policies::ignore_error>,
  586. boost::math::policies::pole_error<boost::math::policies::ignore_error>,
  587. boost::math::policies::evaluation_error<boost::math::policies::ignore_error>
  588. > my_ignore_policy;
  589. typedef students_t_distribution<RealType, my_ignore_policy> ignore_error_students_t;
  590. // Only test NaN and infinity if type has these features (realconcept returns zero).
  591. // Integers are always converted to RealType,
  592. // others requires static cast to RealType from long double.
  593. if(std::numeric_limits<RealType>::has_quiet_NaN)
  594. {
  595. // Mean
  596. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_students_t(-1))));
  597. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_students_t(0))));
  598. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_students_t(1))));
  599. // Variance
  600. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_students_t(std::numeric_limits<RealType>::quiet_NaN()))));
  601. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_students_t(-1))));
  602. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_students_t(0))));
  603. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_students_t(1))));
  604. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_students_t(static_cast<RealType>(1.7L)))));
  605. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_students_t(2))));
  606. // Skewness
  607. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_students_t(std::numeric_limits<RealType>::quiet_NaN()))));
  608. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_students_t(-1))));
  609. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_students_t(0))));
  610. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_students_t(1))));
  611. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_students_t(2))));
  612. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_students_t(3))));
  613. // Kurtosis
  614. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(std::numeric_limits<RealType>::quiet_NaN()))));
  615. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(-1))));
  616. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(0))));
  617. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(1))));
  618. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(2))));
  619. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(static_cast<RealType>(2.0001L)))));
  620. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(3))));
  621. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_students_t(4))));
  622. // Kurtosis excess
  623. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(std::numeric_limits<RealType>::quiet_NaN()))));
  624. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(-1))));
  625. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(0))));
  626. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(1))));
  627. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(2))));
  628. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(static_cast<RealType>(2.0001L)))));
  629. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(3))));
  630. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_students_t(4))));
  631. } // has_quiet_NaN
  632. BOOST_CHECK(boost::math::isfinite(mean(ignore_error_students_t(1 + std::numeric_limits<RealType>::epsilon()))));
  633. BOOST_CHECK(boost::math::isfinite(variance(ignore_error_students_t(2 + 2 * std::numeric_limits<RealType>::epsilon()))));
  634. BOOST_CHECK(boost::math::isfinite(variance(ignore_error_students_t(static_cast<RealType>(2.0001L)))));
  635. BOOST_CHECK(boost::math::isfinite(variance(ignore_error_students_t(2 + 2 * std::numeric_limits<RealType>::epsilon()))));
  636. BOOST_CHECK(boost::math::isfinite(skewness(ignore_error_students_t(3 + 3 * std::numeric_limits<RealType>::epsilon()))));
  637. BOOST_CHECK(boost::math::isfinite(kurtosis(ignore_error_students_t(4 + 4 * std::numeric_limits<RealType>::epsilon()))));
  638. BOOST_CHECK(boost::math::isfinite(kurtosis(ignore_error_students_t(static_cast<RealType>(4.0001L)))));
  639. // check_out_of_range<students_t_distribution<RealType> >(1);
  640. // Cannot be used because fails "exception std::domain_error is expected but not raised"
  641. // if df = +infinity is allowed, must use new version that allows skipping infinity tests.
  642. // Infinite == true
  643. check_support<students_t_distribution<RealType> >(students_t_distribution<RealType>(1), true);
  644. } // template <class RealType>void test_spots(RealType)
  645. BOOST_AUTO_TEST_CASE( test_main )
  646. {
  647. // Check that can construct students_t distribution using the two convenience methods:
  648. using namespace boost::math;
  649. students_t myst1(2); // Using typedef
  650. students_t_distribution<> myst2(2); // Using default RealType double.
  651. //students_t_distribution<double> myst3(2); // Using explicit RealType double.
  652. // Basic sanity-check spot values.
  653. // (Parameter value, arbitrarily zero, only communicates the floating point type).
  654. test_spots(0.0F); // Test float. OK at decdigits = 0 tolerance = 0.0001 %
  655. test_spots(0.0); // Test double. OK at decdigits 7, tolerance = 1e07 %
  656. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  657. test_spots(0.0L); // Test long double.
  658. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
  659. test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
  660. #endif
  661. #else
  662. std::cout << "<note>The long double tests have been disabled on this platform "
  663. "either because the long double overloads of the usual math functions are "
  664. "not available at all, or because they are too inaccurate for these tests "
  665. "to pass.</note>" << std::endl;
  666. #endif
  667. } // BOOST_AUTO_TEST_CASE( test_main )
  668. /*
  669. Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\test_students_t.exe"
  670. Running 1 test case...
  671. Tolerance for type float is 0.0001 %
  672. Tolerance for type double is 0.0001 %
  673. Tolerance for type long double is 0.0001 %
  674. Tolerance for type class boost::math::concepts::real_concept is 0.0001 %
  675. *** No errors detected
  676. */