test_arcsine.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. // test_arcsine_dist.cpp
  2. // Copyright John Maddock 2014.
  3. // Copyright Paul A. Bristow 2014.
  4. // Use, modification and distribution are subject to the
  5. // Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt
  7. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. // Tests for the arcsine Distribution.
  9. #include <pch.hpp> // Must be 1st include, and include_directory /libs/math/src/tr1/ is needed.
  10. #ifdef _MSC_VER
  11. # pragma warning(disable: 4127) // Conditional expression is constant.
  12. # pragma warning (disable : 4996) // POSIX name for this item is deprecated.
  13. # pragma warning (disable : 4224) // Nonstandard extension used : formal parameter 'arg' was previously defined as a type.
  14. #endif
  15. #include <boost/math/concepts/real_concept.hpp> // for real_concept.
  16. using ::boost::math::concepts::real_concept;
  17. #include <boost/math/tools/test.hpp> // for real_concept.
  18. #include <boost/math/distributions/arcsine.hpp> // for arcsine_distribution.
  19. using boost::math::arcsine_distribution;
  20. #include <boost/math/constants/constants.hpp>
  21. using boost::math::constants::one_div_root_two;
  22. #define BOOST_TEST_MAIN
  23. #include <boost/test/unit_test.hpp> // for test_main
  24. #include <boost/test/tools/floating_point_comparison.hpp> // for BOOST_CHECK_CLOSE_FRACTION
  25. #include <cmath>
  26. #include "test_out_of_range.hpp"
  27. #include <iostream>
  28. using std::cout;
  29. using std::endl;
  30. #include <limits>
  31. using std::numeric_limits;
  32. template <class RealType>
  33. void test_ignore_policy(RealType)
  34. {
  35. // Check on returns when errors are ignored.
  36. if ((typeid(RealType) != typeid(boost::math::concepts::real_concept))
  37. && std::numeric_limits<RealType>::has_infinity
  38. && std::numeric_limits<RealType>::has_quiet_NaN
  39. )
  40. { // Ordinary floats only.
  41. using namespace boost::math;
  42. // RealType inf = std::numeric_limits<RealType>::infinity();
  43. RealType nan = std::numeric_limits<RealType>::quiet_NaN();
  44. using boost::math::policies::policy;
  45. // Types of error whose action can be altered by policies:.
  46. //using boost::math::policies::evaluation_error;
  47. //using boost::math::policies::domain_error;
  48. //using boost::math::policies::overflow_error;
  49. //using boost::math::policies::underflow_error;
  50. //using boost::math::policies::domain_error;
  51. //using boost::math::policies::pole_error;
  52. //// Actions on error (in enum error_policy_type):
  53. //using boost::math::policies::errno_on_error;
  54. //using boost::math::policies::ignore_error;
  55. //using boost::math::policies::throw_on_error;
  56. //using boost::math::policies::denorm_error;
  57. //using boost::math::policies::pole_error;
  58. //using boost::math::policies::user_error;
  59. typedef policy<
  60. boost::math::policies::domain_error<boost::math::policies::ignore_error>,
  61. boost::math::policies::overflow_error<boost::math::policies::ignore_error>,
  62. boost::math::policies::underflow_error<boost::math::policies::ignore_error>,
  63. boost::math::policies::denorm_error<boost::math::policies::ignore_error>,
  64. boost::math::policies::pole_error<boost::math::policies::ignore_error>,
  65. boost::math::policies::evaluation_error<boost::math::policies::ignore_error>
  66. > ignore_all_policy;
  67. typedef arcsine_distribution<RealType, ignore_all_policy> ignore_error_arcsine;
  68. // Only test NaN and infinity if type has these features (realconcept returns zero).
  69. // Integers are always converted to RealType,
  70. // others requires static cast to RealType from long double.
  71. if (std::numeric_limits<RealType>::has_quiet_NaN)
  72. {
  73. // Demonstrate output of PDF with infinity,
  74. // but strin goutput from NaN is platform dependent, so can't use BOOST_CHECK.
  75. if (std::numeric_limits<RealType>::has_infinity)
  76. {
  77. //std::cout << "pdf(ignore_error_arcsine(-1, +1), std::numeric_limits<RealType>::infinity()) = " << pdf(ignore_error_arcsine(-1, +1), std::numeric_limits<RealType>::infinity()) << std::endl;
  78. // Outputs: pdf(ignore_error_arcsine(-1, +1), std::numeric_limits<RealType>::infinity()) = 1.#QNAN
  79. }
  80. BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), std::numeric_limits<RealType>::infinity()))); // x == infinity
  81. BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), std::numeric_limits<RealType>::infinity()))); // x == infinity
  82. BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), static_cast <RealType>(-2)))); // x < xmin
  83. BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), static_cast <RealType>(-2)))); // x < xmin
  84. BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), static_cast <RealType>(+2)))); // x > x_max
  85. BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), static_cast <RealType>(+2)))); // x > x_max
  86. // Mean
  87. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(-nan, 0))));
  88. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(+nan, 0))));
  89. if (std::numeric_limits<RealType>::has_infinity)
  90. {
  91. //BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(-std::numeric_limits<RealType>::infinity(), 0))));
  92. // std::cout << "arcsine(-inf,+1) mean " << mean(ignore_error_arcsine(-std::numeric_limits<RealType>::infinity())) << std::endl;
  93. //BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(std::numeric_limits<RealType>::infinity(), 0))));
  94. }
  95. // NaN constructors.
  96. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(2, nan))));
  97. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(nan, nan))));
  98. BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(nan, 2))));
  99. // Variance
  100. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(nan, 0))));
  101. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(1, nan))));
  102. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(2, nan))));
  103. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(0, 0))));
  104. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(1, 0))));
  105. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(static_cast<RealType>(1.7L), 0))));
  106. BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(2, 0))));
  107. // Skewness
  108. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(nan, 0))));
  109. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(-1, nan))));
  110. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(0, 0))));
  111. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(1, 0))));
  112. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(2, 0))));
  113. BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(3, 0))));
  114. // Kurtosis
  115. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(nan, 0))));
  116. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(-1, nan))));
  117. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(0, 0))));
  118. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(1, 0))));
  119. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(2, 0))));
  120. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(static_cast<RealType>(2.0001L), 0))));
  121. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(3, 0))));
  122. BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(4, 0))));
  123. // Kurtosis excess
  124. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(nan, 0))));
  125. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(-1, nan))));
  126. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(0, 0))));
  127. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(1, 0))));
  128. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(2, 0))));
  129. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(static_cast<RealType>(2.0001L), 0))));
  130. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(3, 0))));
  131. BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(4, 0))));
  132. } // has_quiet_NaN
  133. //
  134. BOOST_CHECK(boost::math::isfinite(mean(ignore_error_arcsine(0, std::numeric_limits<RealType>::epsilon()))));
  135. check_support<arcsine_distribution<RealType> >(arcsine_distribution<RealType>(0, 1));
  136. } // ordinary floats.
  137. } // template <class RealType> void test_ignore_policy(RealType)
  138. template <class RealType>
  139. RealType informax()
  140. { //! \return Infinity else max_value.
  141. return ((std::numeric_limits<RealType>::has_infinity) ?
  142. std::numeric_limits<RealType>::infinity() : boost::math::tools::max_value<RealType>());
  143. }
  144. template <class RealType>
  145. void test_spot(
  146. RealType a, // alpha a or lo or x_min
  147. RealType b, // arcsine b or hi or x_maz
  148. RealType x, // Probability
  149. RealType P, // CDF of arcsine(a, b)
  150. RealType Q, // Complement of CDF of arcsine (a, b)
  151. RealType tol) // Test tolerance.
  152. {
  153. boost::math::arcsine_distribution<RealType> anarcsine(a, b);
  154. BOOST_CHECK_CLOSE_FRACTION(cdf(anarcsine, x), P, tol);
  155. if ((P < 0.99) && (Q < 0.99))
  156. { // We can only check this if P is not too close to 1,
  157. // so that we can guarantee that Q is free of error,
  158. // (and similarly for Q).
  159. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(anarcsine, x)), Q, tol);
  160. if (x != 0)
  161. {
  162. BOOST_CHECK_CLOSE_FRACTION(
  163. quantile(anarcsine, P), x, tol);
  164. }
  165. else
  166. {
  167. // Just check quantile is very small:
  168. if ((std::numeric_limits<RealType>::max_exponent <= std::numeric_limits<double>::max_exponent)
  169. && (boost::is_floating_point<RealType>::value))
  170. {
  171. // Limit where this is checked: if exponent range is very large we may
  172. // run out of iterations in our root finding algorithm.
  173. BOOST_CHECK(quantile(anarcsine, P) < boost::math::tools::epsilon<RealType>() * 10);
  174. }
  175. } // if k
  176. if (x != 0)
  177. {
  178. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(anarcsine, Q)), x, tol * 10);
  179. }
  180. else
  181. { // Just check quantile is very small:
  182. if ((std::numeric_limits<RealType>::max_exponent <= std::numeric_limits<double>::max_exponent) && (boost::is_floating_point<RealType>::value))
  183. { // Limit where this is checked: if exponent range is very large we may
  184. // run out of iterations in our root finding algorithm.
  185. BOOST_CHECK(quantile(complement(anarcsine, Q)) < boost::math::tools::epsilon<RealType>() * 10);
  186. }
  187. } // if x
  188. }
  189. } // template <class RealType> void test_spot
  190. template <class RealType> // Any floating-point type RealType.
  191. void test_spots(RealType)
  192. {
  193. // Basic sanity checks with 'known good' values.
  194. // so set tolerance to a few eps expressed as a fraction, or
  195. // few eps of type double expressed as a fraction,
  196. // whichever is the larger.
  197. RealType tolerance = (std::max)
  198. (boost::math::tools::epsilon<RealType>(),
  199. static_cast<RealType>(std::numeric_limits<double>::epsilon())); // 0 if real_concept.
  200. tolerance *= 2; // Note: NO * 100 because tolerance is a fraction, NOT %.
  201. cout << "tolerance = " << tolerance << endl;
  202. using boost::math::arcsine_distribution;
  203. using ::boost::math::cdf;
  204. using ::boost::math::pdf;
  205. using ::boost::math::complement;
  206. using ::boost::math::quantile;
  207. // Basic sanity-check spot values.
  208. // Test values from Wolfram alpha, for example:
  209. // http://www.wolframalpha.com/input/?i=+N%5BPDF%5Barcsinedistribution%5B0%2C+1%5D%2C+0.5%5D%2C+50%5D
  210. // N[PDF[arcsinedistribution[0, 1], 0.5], 50]
  211. // 0.63661977236758134307553505349005744813783858296183
  212. arcsine_distribution<RealType> arcsine_01; // (Our) Standard arcsine.
  213. // Member functions.
  214. BOOST_CHECK_EQUAL(arcsine_01.x_min(), 0);
  215. BOOST_CHECK_EQUAL(arcsine_01.x_max(), 1);
  216. // Derived functions.
  217. BOOST_CHECK_EQUAL(mean(arcsine_01), 0.5); // 1 / (1 + 1) = 1/2 exactly.
  218. BOOST_CHECK_EQUAL(median(arcsine_01), 0.5); // 1 / (1 + 1) = 1/2 exactly.
  219. BOOST_CHECK_EQUAL(variance(arcsine_01), 0.125); // 1/8 = 0.125
  220. BOOST_CHECK_CLOSE_FRACTION(standard_deviation(arcsine_01), one_div_root_two<double>() / 2, tolerance); // 1/ sqrt(s) = 0.35355339059327379
  221. BOOST_CHECK_EQUAL(skewness(arcsine_01), 0); //
  222. BOOST_CHECK_EQUAL(kurtosis_excess(arcsine_01), -1.5); // 3/2
  223. BOOST_CHECK_EQUAL(support(arcsine_01).first, 0); //
  224. BOOST_CHECK_EQUAL(range(arcsine_01).first, 0); //
  225. BOOST_MATH_CHECK_THROW(mode(arcsine_01), std::domain_error); // Two modes at x_min and x_max, so throw instead.
  226. // PDF
  227. // pdf of x = 1/4 is same as reflected value at x = 3/4.
  228. // N[PDF[arcsinedistribution[0, 1], 0.25], 50]
  229. // N[PDF[arcsinedistribution[0, 1], 0.75], 50]
  230. // 0.73510519389572273268176866441729258852984864048885
  231. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.000001), static_cast<RealType>(318.31004533885312973989414360099118178698415543136L), tolerance);
  232. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.000005), static_cast<RealType>(142.35286456604168061345817902422241622116338936911L), tolerance);
  233. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.05), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), tolerance);
  234. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.5), static_cast<RealType>(0.63661977236758134307553505349005744813783858296183L), tolerance);
  235. // Note loss of significance when x is near x_max.
  236. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.95), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), 8 * tolerance); // Less accurate.
  237. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.999995), static_cast<RealType>(142.35286456604168061345817902422241622116338936911L), 50000 * tolerance); // Much less accurate.
  238. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.999999), static_cast<RealType>(318.31004533885312973989414360099118178698415543136L), 100000 * tolerance);// Even less accurate.
  239. // Extreme x.
  240. if (std::numeric_limits<RealType>::has_infinity)
  241. { //
  242. BOOST_CHECK_EQUAL(pdf(arcsine_01, 0), informax<RealType>()); //
  243. BOOST_CHECK_EQUAL(pdf(arcsine_01, 1), informax<RealType>()); //
  244. }
  245. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, tolerance),
  246. 1 /(sqrt(tolerance) * boost::math::constants::pi<RealType>()), 2 * tolerance); //
  247. BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, static_cast<RealType>(1) - tolerance),
  248. 1 /(sqrt(tolerance) * boost::math::constants::pi<RealType>()), 2 * tolerance); //
  249. // CDF
  250. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.000001), static_cast<RealType>(0.00063661987847092448418377367957384866092127786060574L), tolerance);
  251. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.000005), static_cast<RealType>(0.0014235262731079289297302426454125318201831474507326L), tolerance);
  252. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.05), static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), tolerance);
  253. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.5), static_cast<RealType>(0.5L), tolerance); // Exact.
  254. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.95), static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), 2 * tolerance);
  255. // Values near unity should use the cdf complemented for better accuracy,
  256. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.999995), static_cast<RealType>(0.99857647372689207107026975735458746817981685254927L), 100 * tolerance); // Less accurate.
  257. BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.999999), static_cast<RealType>(0.99936338012152907551581622632042615133907872213939L), 1000 * tolerance); // Less accurate.
  258. // Complement CDF
  259. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.000001)), static_cast<RealType>(1 - 0.00063661987847092448418377367957384866092127786060574L), 2 * tolerance);
  260. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.000001)), static_cast<RealType>(0.99936338012152907551581622632043L), 2 * tolerance); //
  261. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.05)), static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), tolerance);
  262. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.5)), static_cast<RealType>(0.5L), tolerance); // Exact.
  263. // Some values near unity when complement is expected to be less accurate.
  264. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.95)), static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), 8 * tolerance); // 2 for asin
  265. BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.999999)), static_cast<RealType>(1 - 0.99936338012152907551581622632042615133907872213939L), 1000000 * tolerance); // 10000 for asin, 1000000 for acos.
  266. // Quantile.
  267. // Check 1st, 2nd and 3rd quartiles.
  268. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.25L)), static_cast<RealType>(0.14644660940672624L), tolerance);
  269. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.5L)), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5
  270. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.75L)), static_cast<RealType>(0.85355339059327373L), tolerance);
  271. // N[CDF[arcsinedistribution[0, 1], 0.05], 50] == 0.14356629312870627075094188477505571882161519989741
  272. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L)), 0.05, tolerance);
  273. // Quantile of complement.
  274. // N[1-CDF[arcsinedistribution[0, 1], 0.05], 50] == 0.85643370687129372924905811522494428117838480010259
  275. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L))), 0.05, tolerance * 2);
  276. // N[sin^2[0.75 * pi/2],50] == 0.85355339059327376220042218105242451964241796884424
  277. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.25L))), static_cast<RealType>(0.85355339059327376220042218105242451964241796884424L), tolerance);
  278. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.5L))), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5
  279. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.75L))), static_cast<RealType>(0.14644660940672623779957781894757548035758203115576L), 2 * tolerance); // Less accurate.
  280. // N[CDF[arcsinedistribution[0, 1], 0.25], 5
  281. // 0.33333333333333333333333333333333333333333333333333
  282. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(1) / 3), static_cast<RealType>(0.25L), 2 * tolerance);
  283. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.5L)), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5
  284. BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(2) / 3), static_cast<RealType>(0.75L), tolerance);
  285. // Arcsine(-1, +1) xmin = -1, x_max = +1 symmetric about zero.
  286. arcsine_distribution<RealType> as_m11(-1, +1);
  287. BOOST_CHECK_EQUAL(as_m11.x_min(), -1); //
  288. BOOST_CHECK_EQUAL(as_m11.x_max(), +1);
  289. BOOST_CHECK_EQUAL(mean(as_m11), 0); //
  290. BOOST_CHECK_EQUAL(median(as_m11), 0); //
  291. BOOST_CHECK_CLOSE_FRACTION(standard_deviation(as_m11), one_div_root_two<RealType>(), tolerance * 2); //
  292. BOOST_CHECK_EQUAL(variance(as_m11), 0.5); // 1 - (-1) = 2 ^ 2 = 4 /8 = 0.5
  293. BOOST_CHECK_EQUAL(skewness(as_m11), 0); //
  294. BOOST_CHECK_EQUAL(kurtosis_excess(as_m11), -1.5); // 3/2
  295. BOOST_CHECK_CLOSE_FRACTION(pdf(as_m11, 0.05), static_cast<RealType>(0.31870852113797122803869876869296281629727218095644L), tolerance);
  296. BOOST_CHECK_CLOSE_FRACTION(pdf(as_m11, 0.5), static_cast<RealType>(0.36755259694786136634088433220864629426492432024443L), tolerance);
  297. BOOST_CHECK_CLOSE_FRACTION(pdf(as_m11, 0.95), static_cast<RealType>(1.0194074882503562519812229448639426942621591013381L), 2 * tolerance); // Less accurate.
  298. BOOST_CHECK_CLOSE_FRACTION(cdf(as_m11, 0.05), static_cast<RealType>(0.51592213323666034437274347433261364289389772737836L), tolerance);
  299. BOOST_CHECK_CLOSE_FRACTION(cdf(as_m11, 0.5), static_cast<RealType>(0.66666666666666666666666666666666666666666666666667L), 2 * tolerance);
  300. BOOST_CHECK_CLOSE_FRACTION(cdf(as_m11, 0.95), static_cast<RealType>(0.89891737589574013042121018491729701360300248368629L), tolerance); // Not less accurate.
  301. // Quantile
  302. BOOST_CHECK_CLOSE_FRACTION(quantile(as_m11, static_cast<RealType>(1) / 3), -static_cast<RealType>(0.5L), 2 * tolerance); // p = 1/3 x = -0.5
  303. BOOST_CHECK_SMALL(quantile(as_m11, static_cast<RealType>(0.5L)), 2 * tolerance); // p = 0.5, x = 0
  304. BOOST_CHECK_CLOSE_FRACTION(quantile(as_m11, static_cast<RealType>(2) / 3), +static_cast<RealType>(0.5L), 4 * tolerance); // p = 2/3, x = +0.5
  305. // Loop back tests.
  306. test_spot(
  307. static_cast<RealType>(0), // lo or a
  308. static_cast<RealType>(1), // hi or b
  309. static_cast<RealType>(0.05), // Random variate x
  310. static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), // Probability of result (CDF of arcsine), P
  311. static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), // Complement of CDF Q = 1 - P
  312. tolerance); // Test tolerance.
  313. test_spot(
  314. static_cast<RealType>(0), // lo or a
  315. static_cast<RealType>(1), // hi or b
  316. static_cast<RealType>(0.95), // Random variate x
  317. static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), // Probability of result (CDF of arcsine), P
  318. static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), // Complement of CDF Q = 1 - P
  319. tolerance * 4); // Test tolerance (slightly inceased compared to x < 0.5 above).
  320. test_spot(
  321. static_cast<RealType>(0), // lo or a
  322. static_cast<RealType>(1), // hi or b
  323. static_cast<RealType>(static_cast<RealType>(0.5L)), // Random variate x
  324. static_cast<RealType>(static_cast<RealType>(0.5L)), // Probability of result (CDF of arcsine), P
  325. static_cast<RealType>(static_cast<RealType>(0.5L)), // Complement of CDF Q = 1 - P
  326. tolerance * 4); // Test tolerance.
  327. // Arcsine(-2, -1) xmin = -2, x_max = -1 - Asymmetric both negative.
  328. arcsine_distribution<RealType> as_m2m1(-2, -1);
  329. BOOST_CHECK_EQUAL(as_m2m1.x_min(), -2); //
  330. BOOST_CHECK_EQUAL(as_m2m1.x_max(), -1);
  331. BOOST_CHECK_EQUAL(mean(as_m2m1), -1.5); // 1 / (1 + 1) = 1/2 exactly.
  332. BOOST_CHECK_EQUAL(median(as_m2m1), -1.5); // 1 / (1 + 1) = 1/2 exactly.
  333. BOOST_CHECK_EQUAL(variance(as_m2m1), 0.125);
  334. BOOST_CHECK_EQUAL(skewness(as_m2m1), 0); //
  335. BOOST_CHECK_EQUAL(kurtosis_excess(as_m2m1), -1.5); // 3/2
  336. BOOST_CHECK_CLOSE_FRACTION(pdf(as_m2m1, -1.95), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), 4 * tolerance);
  337. BOOST_CHECK_CLOSE_FRACTION(pdf(as_m2m1, -1.5), static_cast<RealType>(0.63661977236758134307553505349005744813783858296183L), tolerance);
  338. BOOST_CHECK_CLOSE_FRACTION(pdf(as_m2m1, -1.05), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), 4 * tolerance); // Less accurate.
  339. BOOST_CHECK_CLOSE_FRACTION(cdf(as_m2m1, -1.05), static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), tolerance);
  340. BOOST_CHECK_CLOSE_FRACTION(cdf(as_m2m1, -1.5), static_cast<RealType>(0.5L), tolerance);
  341. BOOST_CHECK_CLOSE_FRACTION(cdf(as_m2m1, -1.95), static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), 8 * tolerance); // Not much less accurate.
  342. // Quantile
  343. BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L)), -static_cast<RealType>(1.05L), 2 * tolerance); //
  344. BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.5L)), -static_cast<RealType>(1.5L), 2 * tolerance); //
  345. BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L)), -static_cast<RealType>(1.95L), 4 * tolerance); //
  346. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(as_m2m1, static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L))), -static_cast<RealType>(1.05L), 2 * tolerance); //
  347. BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.5L)), -static_cast<RealType>(1.5L), 2 * tolerance); //
  348. BOOST_CHECK_CLOSE_FRACTION(quantile(complement(as_m2m1, static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L))), -static_cast<RealType>(1.95L), 4 * tolerance);
  349. // Tests that should throw:
  350. BOOST_MATH_CHECK_THROW(mode(arcsine_distribution<RealType>(static_cast<RealType>(0), static_cast<RealType>(1))), std::domain_error);
  351. // mode is undefined, and must throw domain_error!
  352. BOOST_MATH_CHECK_THROW( // For various bad arguments.
  353. pdf(
  354. arcsine_distribution<RealType>(static_cast<RealType>(+1), static_cast<RealType>(-1)), // min_x > max_x
  355. static_cast<RealType>(1)), std::domain_error);
  356. BOOST_MATH_CHECK_THROW(
  357. pdf(
  358. arcsine_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(0)), // bad constructor parameters.
  359. static_cast<RealType>(1)), std::domain_error);
  360. BOOST_MATH_CHECK_THROW(
  361. pdf(
  362. arcsine_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(-1)), // bad constructor parameters.
  363. static_cast<RealType>(1)), std::domain_error);
  364. BOOST_MATH_CHECK_THROW(
  365. pdf(
  366. arcsine_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), // equal constructor parameters.
  367. static_cast<RealType>(-1)), std::domain_error);
  368. BOOST_MATH_CHECK_THROW(
  369. pdf(
  370. arcsine_distribution<RealType>(static_cast<RealType>(0), static_cast<RealType>(1)), // bad x > 1.
  371. static_cast<RealType>(999)), std::domain_error);
  372. // Checks on things that are errors.
  373. // Construction with 'bad' parameters.
  374. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(+1, -1), std::domain_error); // max < min.
  375. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(+1, 0), std::domain_error); // max < min.
  376. arcsine_distribution<> dist;
  377. BOOST_MATH_CHECK_THROW(pdf(dist, -1), std::domain_error);
  378. BOOST_MATH_CHECK_THROW(cdf(dist, -1), std::domain_error);
  379. BOOST_MATH_CHECK_THROW(cdf(complement(dist, -1)), std::domain_error);
  380. BOOST_MATH_CHECK_THROW(quantile(dist, -1), std::domain_error);
  381. BOOST_MATH_CHECK_THROW(quantile(complement(dist, -1)), std::domain_error);
  382. BOOST_MATH_CHECK_THROW(quantile(dist, -1), std::domain_error);
  383. BOOST_MATH_CHECK_THROW(quantile(complement(dist, -1)), std::domain_error);
  384. // Various combinations of bad contructor and member function parameters.
  385. BOOST_MATH_CHECK_THROW(pdf(boost::math::arcsine_distribution<RealType>(0, 1), -1), std::domain_error);
  386. BOOST_MATH_CHECK_THROW(pdf(boost::math::arcsine_distribution<RealType>(-1, 1), +2), std::domain_error);
  387. BOOST_MATH_CHECK_THROW(quantile(boost::math::arcsine_distribution<RealType>(1, 1), -1), std::domain_error);
  388. BOOST_MATH_CHECK_THROW(quantile(boost::math::arcsine_distribution<RealType>(1, 1), 2), std::domain_error);
  389. // No longer allow any parameter to be NaN or inf, so all these tests should throw.
  390. if (std::numeric_limits<RealType>::has_quiet_NaN)
  391. {
  392. // Attempt to construct from non-finite parameters should throw.
  393. RealType nan = std::numeric_limits<RealType>::quiet_NaN();
  394. #ifndef BOOST_NO_EXCEPTIONS
  395. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(nan), std::domain_error);
  396. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(1, nan), std::domain_error);
  397. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(nan, 1), std::domain_error);
  398. #else
  399. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(nan), std::domain_error);
  400. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(1, nan), std::domain_error);
  401. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(nan, 1), std::domain_error);
  402. #endif
  403. arcsine_distribution<RealType> w(RealType(-1), RealType(+1));
  404. // NaN parameters to member functions should throw.
  405. BOOST_MATH_CHECK_THROW(pdf(w, +nan), std::domain_error); // x = NaN
  406. BOOST_MATH_CHECK_THROW(cdf(w, +nan), std::domain_error); // x = NaN
  407. BOOST_MATH_CHECK_THROW(cdf(complement(w, +nan)), std::domain_error); // x = + nan
  408. BOOST_MATH_CHECK_THROW(quantile(w, +nan), std::domain_error); // p = + nan
  409. BOOST_MATH_CHECK_THROW(quantile(complement(w, +nan)), std::domain_error); // p = + nan
  410. } // has_quiet_NaN
  411. if (std::numeric_limits<RealType>::has_infinity)
  412. {
  413. // Attempt to construct from non-finite should throw.
  414. RealType inf = std::numeric_limits<RealType>::infinity();
  415. #ifndef BOOST_NO_EXCEPTIONS
  416. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(inf), std::domain_error);
  417. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(1, inf), std::domain_error);
  418. #else
  419. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(inf), std::domain_error);
  420. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(1, inf), std::domain_error);
  421. #endif
  422. // Infinite parameters to member functions should throw.
  423. arcsine_distribution<RealType> w(RealType(0), RealType(1));
  424. #ifndef BOOST_NO_EXCEPTIONS
  425. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(inf), std::domain_error);
  426. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(1, inf), std::domain_error);
  427. #else
  428. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(inf), std::domain_error);
  429. BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(1, inf), std::domain_error);
  430. #endif
  431. BOOST_MATH_CHECK_THROW(pdf(w, +inf), std::domain_error); // x = inf
  432. BOOST_MATH_CHECK_THROW(cdf(w, +inf), std::domain_error); // x = inf
  433. BOOST_MATH_CHECK_THROW(cdf(complement(w, +inf)), std::domain_error); // x = + inf
  434. BOOST_MATH_CHECK_THROW(quantile(w, +inf), std::domain_error); // p = + inf
  435. BOOST_MATH_CHECK_THROW(quantile(complement(w, +inf)), std::domain_error); // p = + inf
  436. } // has_infinity
  437. // Error handling checks:
  438. check_out_of_range<boost::math::arcsine_distribution<RealType> >(-1, +1); // (All) valid constructor parameter values.
  439. // and range and non-finite.
  440. test_ignore_policy(static_cast<RealType>(0));
  441. } // template <class RealType>void test_spots(RealType)
  442. BOOST_AUTO_TEST_CASE(test_main)
  443. {
  444. BOOST_MATH_CONTROL_FP;
  445. // Check that can generate arcsine distribution using convenience method:
  446. using boost::math::arcsine;
  447. arcsine_distribution<> arcsine_01; // Using default RealType double.
  448. // Note: NOT arcsine01() - or compiler will assume a function.
  449. arcsine as; // Using typedef for default standard arcsine.
  450. //
  451. BOOST_CHECK_EQUAL(as.x_min(), 0); //
  452. BOOST_CHECK_EQUAL(as.x_max(), 1);
  453. BOOST_CHECK_EQUAL(mean(as), 0.5); // 1 / (1 + 1) = 1/2 exactly.
  454. BOOST_CHECK_EQUAL(median(as), 0.5); // 1 / (1 + 1) = 1/2 exactly.
  455. BOOST_CHECK_EQUAL(variance(as), 0.125); //0.125
  456. BOOST_CHECK_CLOSE_FRACTION(standard_deviation(as), one_div_root_two<double>() / 2, std::numeric_limits<double>::epsilon()); // 0.353553
  457. BOOST_CHECK_EQUAL(skewness(as), 0); //
  458. BOOST_CHECK_EQUAL(kurtosis_excess(as), -1.5); // 3/2
  459. BOOST_CHECK_EQUAL(support(as).first, 0); //
  460. BOOST_CHECK_EQUAL(range(as).first, 0); //
  461. BOOST_MATH_CHECK_THROW(mode(as), std::domain_error); // Two modes at x_min and x_max, so throw instead.
  462. // (Parameter value, arbitrarily zero, only communicates the floating point type).
  463. test_spots(0.0F); // Test float.
  464. test_spots(0.0); // Test double.
  465. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  466. test_spots(0.0L); // Test long double.
  467. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
  468. test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
  469. #endif
  470. #endif
  471. /* */
  472. } // BOOST_AUTO_TEST_CASE( test_main )
  473. /*
  474. Microsoft Visual Studio Professional 2013
  475. Version 12.0.30110.00 Update 1
  476. 1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_arcsine.exe"
  477. 1> Running 1 test case...
  478. 1> Platform: Win32
  479. 1> Compiler: Microsoft Visual C++ version 12.0 ???? MSVC says 2013
  480. 1> STL : Dinkumware standard library version 610
  481. 1> Boost : 1.56.0
  482. Sample Output is:
  483. 1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_arcsine.exe"
  484. 1> Running 1 test case...
  485. 1> Platform: Win32
  486. 1> Compiler: Microsoft Visual C++ version 12.0
  487. 1> STL : Dinkumware standard library version 610
  488. 1> Boost : 1.56.0
  489. 1> tolerance = 2.38419e-007
  490. 1> tolerance = 4.44089e-016
  491. 1> tolerance = 4.44089e-016
  492. 1> tolerance = 4.44089e-016
  493. 1>
  494. 1> *** No errors detected
  495. GCC 4.9.1
  496. Running 1 test case...
  497. tolerance = 2.38419e-007
  498. tolerance = 4.44089e-016
  499. tolerance = 4.44089e-016
  500. tolerance = 4.44089e-016
  501. *** No errors detected
  502. RUN SUCCESSFUL (total time: 141ms)
  503. */