test_bernoulli.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // test_bernoulli.cpp
  2. // Copyright John Maddock 2006.
  3. // Copyright Paul A. Bristow 2007, 2012.
  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. // Basic sanity test for Bernoulli Cumulative Distribution Function.
  9. #ifdef _MSC_VER
  10. # pragma warning (disable : 4535) // calling _set_se_translator() requires /EHa.
  11. # pragma warning (disable : 4244) // conversion possible loss of data.
  12. # pragma warning (disable : 4996) // 'putenv': The POSIX name for this item is deprecated.
  13. # pragma warning (disable : 4127) // conditional expression is constant.
  14. #endif
  15. // Default domain error policy is
  16. // #define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error
  17. #include <boost/math/concepts/real_concept.hpp> // for real_concept
  18. using ::boost::math::concepts::real_concept;
  19. #include <boost/math/tools/test.hpp>
  20. #include <boost/math/distributions/bernoulli.hpp> // for bernoulli_distribution
  21. using boost::math::bernoulli_distribution;
  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, BOOST_CHECK_EQUAL...
  25. #include <iostream>
  26. using std::cout;
  27. using std::endl;
  28. using std::fixed;
  29. using std::right;
  30. using std::left;
  31. using std::showpoint;
  32. using std::showpos;
  33. using std::setw;
  34. using std::setprecision;
  35. #include <limits>
  36. using std::numeric_limits;
  37. template <class RealType> // Any floating-point type RealType.
  38. void test_spots(RealType)
  39. { // Parameter only provides the type, float, double... value ignored.
  40. // Basic sanity checks, test data may be to double precision only
  41. // so set tolerance to 100 eps expressed as a fraction,
  42. // or 100 eps of type double expressed as a fraction,
  43. // whichever is the larger.
  44. RealType tolerance = (std::max)
  45. (boost::math::tools::epsilon<RealType>(),
  46. static_cast<RealType>(std::numeric_limits<double>::epsilon()));
  47. tolerance *= 100;
  48. cout << "Tolerance for type " << typeid(RealType).name() << " is "
  49. << setprecision(3) << tolerance << " (or " << tolerance * 100 << "%)." << endl;
  50. // Sources of spot test values - calculator,
  51. // or Steve Moshier's command interpreter V1.3 100 decimal digit calculator,
  52. // Wolfram function evaluator.
  53. using boost::math::bernoulli_distribution; // of type RealType.
  54. using ::boost::math::cdf;
  55. using ::boost::math::pdf;
  56. BOOST_CHECK_EQUAL(bernoulli_distribution<RealType>(static_cast<RealType>(0.5)).success_fraction(), static_cast<RealType>(0.5));
  57. BOOST_CHECK_EQUAL(bernoulli_distribution<RealType>(static_cast<RealType>(0.1L)).success_fraction(), static_cast<RealType>(0.1L));
  58. BOOST_CHECK_EQUAL(bernoulli_distribution<RealType>(static_cast<RealType>(0.9L)).success_fraction(), static_cast<RealType>(0.9L));
  59. BOOST_MATH_CHECK_THROW( // Constructor success_fraction outside 0 to 1.
  60. bernoulli_distribution<RealType>(static_cast<RealType>(2)), std::domain_error);
  61. BOOST_MATH_CHECK_THROW(
  62. bernoulli_distribution<RealType>(static_cast<RealType>(-2)), std::domain_error);
  63. BOOST_MATH_CHECK_THROW(
  64. pdf( // pdf k neither 0 nor 1.
  65. bernoulli_distribution<RealType>(static_cast<RealType>(0.25L)), static_cast<RealType>(-1)), std::domain_error);
  66. BOOST_MATH_CHECK_THROW(
  67. pdf( // pdf k neither 0 nor 1.
  68. bernoulli_distribution<RealType>(static_cast<RealType>(0.25L)), static_cast<RealType>(2)), std::domain_error);
  69. BOOST_CHECK_EQUAL(
  70. pdf( // OK k (or n)
  71. bernoulli_distribution<RealType>(static_cast<RealType>(0.5L)), static_cast<RealType>(0)),
  72. static_cast<RealType>(0.5)); // Expect 1 - p.
  73. BOOST_CHECK_CLOSE_FRACTION(
  74. pdf( // OK k (or n)
  75. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)), static_cast<RealType>(0)),
  76. static_cast<RealType>(0.4L), tolerance); // Expect 1 - p.
  77. BOOST_CHECK_CLOSE_FRACTION(
  78. pdf( // OK k (or n)
  79. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)), static_cast<RealType>(0)),
  80. static_cast<RealType>(0.4L), tolerance); // Expect 1- p.
  81. BOOST_CHECK_CLOSE_FRACTION(
  82. pdf( // OK k (or n)
  83. bernoulli_distribution<RealType>(static_cast<RealType>(0.4L)), static_cast<RealType>(0)),
  84. static_cast<RealType>(0.6L), tolerance); // Expect 1- p.
  85. BOOST_CHECK_EQUAL(
  86. mean(bernoulli_distribution<RealType>(static_cast<RealType>(0.5L))), static_cast<RealType>(0.5L));
  87. BOOST_CHECK_EQUAL(
  88. mean(bernoulli_distribution<RealType>(static_cast<RealType>(0.1L))),
  89. static_cast<RealType>(0.1L));
  90. BOOST_CHECK_CLOSE_FRACTION(
  91. variance(bernoulli_distribution<RealType>(static_cast<RealType>(0.1L))),
  92. static_cast<RealType>(0.09L),
  93. tolerance);
  94. BOOST_CHECK_CLOSE_FRACTION(
  95. skewness(bernoulli_distribution<RealType>(static_cast<RealType>(0.1L))),
  96. static_cast<RealType>(2.666666666666666666666666666666666666666666L),
  97. tolerance);
  98. BOOST_CHECK_CLOSE_FRACTION(
  99. kurtosis(bernoulli_distribution<RealType>(static_cast<RealType>(0.1L))),
  100. static_cast<RealType>(8.11111111111111111111111111111111111111111111L),
  101. tolerance);
  102. BOOST_CHECK_CLOSE_FRACTION(
  103. kurtosis_excess(bernoulli_distribution<RealType>(static_cast<RealType>(0.1L))),
  104. static_cast<RealType>(5.11111111111111111111111111111111111111111111L),
  105. tolerance);
  106. BOOST_MATH_CHECK_THROW(
  107. quantile(
  108. bernoulli_distribution<RealType>(static_cast<RealType>(2)), // prob >1
  109. static_cast<RealType>(0)), std::domain_error
  110. );
  111. BOOST_MATH_CHECK_THROW(
  112. quantile(
  113. bernoulli_distribution<RealType>(static_cast<RealType>(-1)), // prob < 0
  114. static_cast<RealType>(0)), std::domain_error
  115. );
  116. BOOST_MATH_CHECK_THROW(
  117. quantile(
  118. bernoulli_distribution<RealType>(static_cast<RealType>(0.5L)), // k >1
  119. static_cast<RealType>(-1)), std::domain_error
  120. );
  121. BOOST_MATH_CHECK_THROW(
  122. quantile(
  123. bernoulli_distribution<RealType>(static_cast<RealType>(0.5L)), // k < 0
  124. static_cast<RealType>(2)), std::domain_error
  125. );
  126. BOOST_CHECK_CLOSE_FRACTION(
  127. cdf(
  128. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  129. static_cast<RealType>(0)),
  130. static_cast<RealType>(0.4L), // 1 - p
  131. tolerance
  132. );
  133. BOOST_CHECK_CLOSE_FRACTION(
  134. cdf(
  135. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  136. static_cast<RealType>(1)),
  137. static_cast<RealType>(1), // p
  138. tolerance
  139. );
  140. BOOST_CHECK_CLOSE_FRACTION(
  141. cdf(complement(
  142. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  143. static_cast<RealType>(1))),
  144. static_cast<RealType>(0),
  145. tolerance
  146. );
  147. BOOST_CHECK_CLOSE_FRACTION(
  148. cdf(complement(
  149. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  150. static_cast<RealType>(0))),
  151. static_cast<RealType>(0.6L),
  152. tolerance
  153. );
  154. BOOST_CHECK_EQUAL(
  155. quantile(
  156. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  157. static_cast<RealType>(0.1L)), // < p
  158. static_cast<RealType>(0)
  159. );
  160. BOOST_CHECK_EQUAL(
  161. quantile(
  162. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  163. static_cast<RealType>(0.9L)), // > p
  164. static_cast<RealType>(1)
  165. );
  166. BOOST_CHECK_EQUAL(
  167. quantile(complement(
  168. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  169. static_cast<RealType>(0.1L))), // < p
  170. static_cast<RealType>(1)
  171. );
  172. BOOST_CHECK_EQUAL(
  173. quantile(complement(
  174. bernoulli_distribution<RealType>(static_cast<RealType>(0.6L)),
  175. static_cast<RealType>(0.9L))), // > p
  176. static_cast<RealType>(0)
  177. );
  178. // Checks for 'bad' parameters.
  179. // Construction.
  180. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType>(-1), std::domain_error); // p outside 0 to 1.
  181. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType>(+2), std::domain_error); // p outside 0 to 1.
  182. // Parameters.
  183. bernoulli_distribution<RealType> dist(RealType(1));
  184. BOOST_MATH_CHECK_THROW(pdf(dist, -1), std::domain_error);
  185. BOOST_MATH_CHECK_THROW(cdf(dist, -1), std::domain_error);
  186. BOOST_MATH_CHECK_THROW(cdf(complement(dist, -1)), std::domain_error);
  187. BOOST_MATH_CHECK_THROW(quantile(dist, 2), std::domain_error);
  188. BOOST_MATH_CHECK_THROW(quantile(complement(dist, -1)), std::domain_error);
  189. BOOST_MATH_CHECK_THROW(quantile(dist, -1), std::domain_error);
  190. BOOST_MATH_CHECK_THROW(quantile(complement(dist, -1)), std::domain_error);
  191. // No longer allow any parameter to be NaN or inf, so all these tests should throw.
  192. if (std::numeric_limits<RealType>::has_quiet_NaN)
  193. {
  194. // Attempt to construct from non-finite should throw.
  195. RealType nan = std::numeric_limits<RealType>::quiet_NaN();
  196. #ifndef BOOST_NO_EXCEPTIONS
  197. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType> b(nan), std::domain_error);
  198. #else
  199. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType>(nan), std::domain_error);
  200. #endif
  201. // Non-finite parameters should throw.
  202. bernoulli_distribution<RealType> b(RealType(1));
  203. BOOST_MATH_CHECK_THROW(pdf(b, +nan), std::domain_error); // x = NaN
  204. BOOST_MATH_CHECK_THROW(cdf(b, +nan), std::domain_error); // x = NaN
  205. BOOST_MATH_CHECK_THROW(cdf(complement(b, +nan)), std::domain_error); // x = + nan
  206. BOOST_MATH_CHECK_THROW(quantile(b, +nan), std::domain_error); // p = + nan
  207. BOOST_MATH_CHECK_THROW(quantile(complement(b, +nan)), std::domain_error); // p = + nan
  208. } // has_quiet_NaN
  209. if (std::numeric_limits<RealType>::has_infinity)
  210. {
  211. RealType inf = std::numeric_limits<RealType>::infinity();
  212. #ifndef BOOST_NO_EXCEPTIONS
  213. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType> w(inf), std::domain_error);
  214. #else
  215. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType>(inf), std::domain_error);
  216. #endif
  217. bernoulli_distribution<RealType> w(RealType(1));
  218. #ifndef BOOST_NO_EXCEPTIONS
  219. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType> w(inf), std::domain_error);
  220. #else
  221. BOOST_MATH_CHECK_THROW(bernoulli_distribution<RealType>(inf), std::domain_error);
  222. #endif
  223. BOOST_MATH_CHECK_THROW(pdf(w, +inf), std::domain_error); // x = inf
  224. BOOST_MATH_CHECK_THROW(cdf(w, +inf), std::domain_error); // x = inf
  225. BOOST_MATH_CHECK_THROW(cdf(complement(w, +inf)), std::domain_error); // x = + inf
  226. BOOST_MATH_CHECK_THROW(quantile(w, +inf), std::domain_error); // p = + inf
  227. BOOST_MATH_CHECK_THROW(quantile(complement(w, +inf)), std::domain_error); // p = + inf
  228. } // has_infinity
  229. } // template <class RealType>void test_spots(RealType)
  230. BOOST_AUTO_TEST_CASE( test_main )
  231. {
  232. BOOST_MATH_CONTROL_FP;
  233. // Check that can generate bernoulli distribution using both convenience methods:
  234. bernoulli_distribution<double> bn1(0.5); // Using default RealType double.
  235. boost::math::bernoulli bn2(0.5); // Using typedef.
  236. BOOST_CHECK_EQUAL(bn1.success_fraction(), 0.5);
  237. BOOST_CHECK_EQUAL(bn2.success_fraction(), 0.5);
  238. BOOST_CHECK_EQUAL(kurtosis(bn2) -3, kurtosis_excess(bn2));
  239. BOOST_CHECK_EQUAL(kurtosis_excess(bn2), -2);
  240. //using namespace boost::math; or
  241. using boost::math::bernoulli;
  242. double tol5eps = std::numeric_limits<double>::epsilon() * 5; // 5 eps as a fraction.
  243. // Default bernoulli is type double, so these test values should also be type double.
  244. BOOST_CHECK_CLOSE_FRACTION(kurtosis_excess(bernoulli(0.1)), 5.11111111111111111111111111111111111111111111111111, tol5eps);
  245. BOOST_CHECK_CLOSE_FRACTION(kurtosis_excess(bernoulli(0.9)), 5.11111111111111111111111111111111111111111111111111, tol5eps);
  246. BOOST_CHECK_CLOSE_FRACTION(kurtosis(bernoulli(0.6)), 1./0.4 + 1./0.6 -3., tol5eps);
  247. BOOST_CHECK_EQUAL(kurtosis(bernoulli(0)), +std::numeric_limits<double>::infinity());
  248. BOOST_CHECK_EQUAL(kurtosis(bernoulli(1)), +std::numeric_limits<double>::infinity());
  249. //
  250. // Basic sanity-check spot values.
  251. // (Parameter value, arbitrarily zero, only communicates the floating point type).
  252. test_spots(0.0F); // Test float.
  253. test_spots(0.0); // Test double.
  254. test_spots(0.0L); // Test long double.
  255. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
  256. test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
  257. #endif
  258. } // BOOST_AUTO_TEST_CASE( test_main )
  259. /*
  260. Output is:
  261. Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_bernouilli.exe"
  262. Running 1 test case...
  263. Tolerance for type float is 1.19e-005 (or 0.00119%).
  264. Tolerance for type double is 2.22e-014 (or 2.22e-012%).
  265. Tolerance for type long double is 2.22e-014 (or 2.22e-012%).
  266. Tolerance for type class boost::math::concepts::real_concept is 2.22e-014 (or 2.22e-012%).
  267. *** No errors detected
  268. */