diff --git a/doc/distributions/arcsine.qbk b/doc/distributions/arcsine.qbk index 664a810e4..248832b8f 100644 --- a/doc/distributions/arcsine.qbk +++ b/doc/distributions/arcsine.qbk @@ -19,6 +19,7 @@ public: typedef RealType value_type; typedef Policy policy_type; + // Constructor from two range parameters, x_min and x_max: arcsine_distribution(RealType x_min, RealType x_max); @@ -51,13 +52,11 @@ The [@http://en.wikipedia.org/wiki/Probability_density_function probability dens for the [@http://en.wikipedia.org/wiki/arcsine_distribution arcsine distribution] defined on the interval \[0,1\] is given by: -[sixemspace] f(x; x_min, x_max) = 1 / [pi] [sqrt]((x - x_min) (x_max - x)) - -[figspace] f(x; x_min, x_max) = 1 / [pi] [sqrt]((x - x_min) (x_max - x)) +[figspace] [figspace] f(x; x_min, x_max) = 1 /([pi][sdot][sqrt]((x - x_min)[sdot](x_max - x)) For example, __WolframAlpha arcsine distribution, from input of - N[pDF[arcsinedistribution[0, 1], 0.5], 50] + N[PDF[arcsinedistribution[0, 1], 0.5], 50] computes the PDF value @@ -78,7 +77,7 @@ and some generalized examples with other ['x] ranges. The Cumulative Distribution Function CDF is defined as -[sixemspace] F(x) = 2 / [pi] arcsin (sqrt((x-x_min)(x_max - x))) +[figspace] [figspace] F(x) = 2[sdot]arcsin([sqrt]((x-x_min)/(x_max - x))) / [pi] [graph arcsine_cdf] @@ -121,7 +120,7 @@ that are generic to all distributions are supported: __usual_accessors. The formulae for calculating these are shown in the table below, and at [@http://mathworld.wolfram.com/arcsineDistribution.html Wolfram Mathworld]. -[note There are always [*two] values for the mode, at ['x_min] and at ['x_max], default 0 and 1, +[note There are always [*two] values for the [*mode], at ['x_min] and at ['x_max], default 0 and 1, so instead we raise the exception __domain_error. At these extrema, the PDFs are infinite, and the CDFs zero or unity.] @@ -151,14 +150,14 @@ and the PDF can be calculated thus: [arcsine_snip_2] -From the plot of PDF, it is clear that ['x] = 1/2 is the [*minimum] of the curve, +From the plot of PDF, it is clear that ['x] = [frac12] is the [*minimum] of the curve, so this is the [*least likely] scenario. (This is highly counter-intuitive, considering that fair tosses must [*eventually] become equal. -It turns out that ['eventually] is not just very long, but infinite). +It turns out that ['eventually] is not just very long, but [*infinite]!). The [*most likely] scenarios are towards the extrema where ['x] = 0 or ['x] = 1. -If fraction of time is on the left is a 1/4, +If fraction of time on the left is a [frac14], it is only slightly more likely because the curve is quite flat bottomed. [arcsine_snip_3] @@ -173,7 +172,7 @@ We can easily compute this setting ['x] = 5./100 = 0.05 Similarly, we can compute from a fraction of 0.05 /2 = 0.025 (halved because we are considering both winners and losers) -corresponding to 1 - 0.025 or 97.5% of the gamblers, (walkers, particles) on the [*same side] of the origin +corresponding to 1 - 0.025 or 97.5% of the gamblers, (walkers, particles...) on the [*same side] of the origin [arcsine_snip_5] @@ -197,7 +196,7 @@ and gamblers continue to provide proof. [*Moral]: if you in a losing patch, leave the game. (Because the odds to recover to a good patch are poor). -[*Corollary]: Quit while you are ahead! +[*Corollary]: Quit while you are ahead? A working example is at [@../../example/arcsine_example.cpp arcsine_example.cpp] including sample output . @@ -217,7 +216,7 @@ For example, for a standard [0, 1] arcsine distribution ['as], the pdf is symmet so that one would expect `pdf(as, 0.01) == pdf(as, 0.99)`. But as ['x] nears unity, there is increasing [@http://en.wikipedia.org/wiki/Loss_of_significance loss of significance]. To counteract this, the complement versions of CDF and quantile -are implemented with alternative expressions using ['cos[super -1]] instead of ['asin[super -1]]. +are implemented with alternative expressions using ['cos[super -1]] instead of ['sin[super -1]]. Users should see __why_complements for guidance on when to avoid loss of accuracy by using complements. [h4 Testing] @@ -233,7 +232,7 @@ In the following table ['a] and ['b] are the parameters ['x_min][space] and ['x_ [table [[Function][Implementation Notes]] -[[support] [x [isin] \[x_min, x_max\], default x [isin] \[0, 1\] ]] +[[support] [x [isin] \[a, b\], default x [isin] \[0, 1\] ]] [[pdf] [f(x; a, b) = 1/([pi][sdot][sqrt](x - a)[sdot](b - x))]] [[cdf] [F(x) = 2/[pi][sdot]sin[super-1]([sqrt](x - a) / (b - a) ) ]] [[cdf of complement] [2/([pi][sdot]cos[super-1]([sqrt](x - a) / (b - a)))]] diff --git a/doc/graphs/arcsine01_cdf.png b/doc/graphs/arcsine01_cdf.png index a7db2a4e4..051612350 100644 Binary files a/doc/graphs/arcsine01_cdf.png and b/doc/graphs/arcsine01_cdf.png differ diff --git a/doc/graphs/arcsine01_cdf.svg b/doc/graphs/arcsine01_cdf.svg index 85323c97e..eac488308 100644 --- a/doc/graphs/arcsine01_cdf.svg +++ b/doc/graphs/arcsine01_cdf.svg @@ -55,7 +55,7 @@ xmlns ="http://www.w3.org/2000/svg" Probability Random Variable x - + diff --git a/doc/graphs/arcsine01_pdf.png b/doc/graphs/arcsine01_pdf.png index ff1c8ba1c..816009599 100644 Binary files a/doc/graphs/arcsine01_pdf.png and b/doc/graphs/arcsine01_pdf.png differ diff --git a/doc/graphs/arcsine_cdf.png b/doc/graphs/arcsine_cdf.png index 7289605cf..7827570cb 100644 Binary files a/doc/graphs/arcsine_cdf.png and b/doc/graphs/arcsine_cdf.png differ diff --git a/doc/graphs/arcsine_cdf.svg b/doc/graphs/arcsine_cdf.svg index 3b327c954..681d25240 100644 --- a/doc/graphs/arcsine_cdf.svg +++ b/doc/graphs/arcsine_cdf.svg @@ -50,11 +50,11 @@ xmlns ="http://www.w3.org/2000/svg" Probability Random Variable x - - - - - + + + + + diff --git a/doc/graphs/arcsine_pdf.png b/doc/graphs/arcsine_pdf.png index 9cab8523f..16ae38eef 100644 Binary files a/doc/graphs/arcsine_pdf.png and b/doc/graphs/arcsine_pdf.png differ diff --git a/doc/graphs/arcsine_pdf.svg b/doc/graphs/arcsine_pdf.svg index 2919dda34..b917b0214 100644 --- a/doc/graphs/arcsine_pdf.svg +++ b/doc/graphs/arcsine_pdf.svg @@ -52,7 +52,7 @@ xmlns ="http://www.w3.org/2000/svg" - + diff --git a/doc/graphs/dist_graphs.cpp b/doc/graphs/dist_graphs.cpp index 4da079cce..515d392ef 100644 --- a/doc/graphs/dist_graphs.cpp +++ b/doc/graphs/dist_graphs.cpp @@ -101,7 +101,7 @@ public: double margin = 1e-2; // Margin of 1% (say) to get lowest off the 'end stop'. if((a != 0) && (fabs(a) > margin)) { - mod = a * (1 + (a > 0) ? margin : -margin)); + mod = a * (1 + ((a > 0) ? margin : -margin)); } else { // Case of mod near zero? diff --git a/doc/html/index.html b/doc/html/index.html index ad7447a4a..e82a6a6e4 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -111,7 +111,7 @@ This manual is also available in -

Last revised: October 20, 2014 at 13:16:35 GMT

+

Last revised: November 27, 2014 at 14:58:32 GMT


diff --git a/doc/html/indexes/s01.html b/doc/html/indexes/s01.html index f1e1b4852..4f780a0ea 100644 --- a/doc/html/indexes/s01.html +++ b/doc/html/indexes/s01.html @@ -24,7 +24,7 @@

-Function Index

+Function Index

A B C D E F G H I J K L M N O P Q R S T U V Z

diff --git a/doc/html/indexes/s02.html b/doc/html/indexes/s02.html index b7f04e7ec..f4352f2d6 100644 --- a/doc/html/indexes/s02.html +++ b/doc/html/indexes/s02.html @@ -24,7 +24,7 @@

-Class Index

+Class Index

A B C D E F G H I L M N O P Q R S T U W

diff --git a/doc/html/indexes/s03.html b/doc/html/indexes/s03.html index 29aa2637a..a18b0e2a6 100644 --- a/doc/html/indexes/s03.html +++ b/doc/html/indexes/s03.html @@ -24,7 +24,7 @@

-Typedef Index

+Typedef Index

A B C D E F G H I L N O P R S T U V W

diff --git a/doc/html/indexes/s04.html b/doc/html/indexes/s04.html index 223ea1eb5..e1cb4c248 100644 --- a/doc/html/indexes/s04.html +++ b/doc/html/indexes/s04.html @@ -24,7 +24,7 @@

-Macro Index

+Macro Index

B F

diff --git a/doc/html/indexes/s05.html b/doc/html/indexes/s05.html index 7938566f7..b92df739b 100644 --- a/doc/html/indexes/s05.html +++ b/doc/html/indexes/s05.html @@ -23,7 +23,7 @@

-Index

+Index

A B C D E F G H I J K L M N O P Q R S T U V W Z

diff --git a/doc/html/math_toolkit/conventions.html b/doc/html/math_toolkit/conventions.html index 6242d20ce..8526f6034 100644 --- a/doc/html/math_toolkit/conventions.html +++ b/doc/html/math_toolkit/conventions.html @@ -27,7 +27,7 @@ Document Conventions

- +

This documentation aims to use of the following naming and formatting conventions. diff --git a/doc/html/math_toolkit/navigation.html b/doc/html/math_toolkit/navigation.html index 4af2d23d5..42ff1381f 100644 --- a/doc/html/math_toolkit/navigation.html +++ b/doc/html/math_toolkit/navigation.html @@ -27,7 +27,7 @@ Navigation

- +

Boost.Math documentation is provided in both HTML and PDF formats. diff --git a/doc/html/math_toolkit/sf_implementation.html b/doc/html/math_toolkit/sf_implementation.html index 67451da6d..2ed1a3bb9 100644 --- a/doc/html/math_toolkit/sf_implementation.html +++ b/doc/html/math_toolkit/sf_implementation.html @@ -710,7 +710,20 @@ /cygdrive/c/progra~1/Inkscape/inkscape -d 120 -e $(cygpath -a -w $(basename $file .svg).png) $(cygpath -a -w $file); done

- Currently Inkscape seems to generate the better looking png's. + Using BASH +

+
# Convert single SVG to PNG file.
+# /c/progra~1/Inkscape/inkscape -d 120 -e a.png a.svg
+
+

+ or to convert All files in folder SVG to PNG. +

+
for file in *.svg; do
+/c/progra~1/Inkscape/inkscape -d 120 -e $(basename $file .svg).png $file
+done
+
+

+ Currently Inkscape seems to generate the better looking PNGs.

The PDF is generated into \pdf\math.pdf using a command from a shell or command diff --git a/include/boost/math/distributions/arcsine.hpp b/include/boost/math/distributions/arcsine.hpp index cfab487d6..8aad5b2d0 100644 --- a/include/boost/math/distributions/arcsine.hpp +++ b/include/boost/math/distributions/arcsine.hpp @@ -90,11 +90,10 @@ namespace boost function, msg.c_str(), x_max, pol); // "x_max argument is %1%, but must be > x_min !", x_max, pol); - // "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better. TODO? + // "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better. // But would require replication of all helpers functions in /policies/error_handling.hpp for two values, // as well as two value versions of raise_error, raise_domain_error and do_format ... - - + // so use slightly hacky lexical_cast to string instead. return false; } return true; @@ -208,22 +207,44 @@ namespace boost inline const std::pair support(const arcsine_distribution& dist) { // Range of supported values for random variable x. // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. - return std::pair(static_cast(dist.x_min()), static_cast(dist.x_max())); } template inline RealType mean(const arcsine_distribution& dist) { // Mean of arcsine distribution . - return (dist.x_min() + dist.x_max()) / 2; + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::mean(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_min + x_max) / 2; } // mean template inline RealType variance(const arcsine_distribution& dist) { // Variance of standard arcsine distribution = (1-0)/8 = 0.125. - RealType a = dist.x_min(); - RealType b = dist.x_max(); - return (b - a) * (b - a) / 8; + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist( + "boost::math::variance(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_max - x_min) * (x_max - x_min) / 8; } // variance template @@ -240,25 +261,77 @@ namespace boost template inline RealType median(const arcsine_distribution& dist) { // Median of arcsine distribution (a + b) / 2 == mean. - return (dist.x_min() + dist.x_max()) / 2; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + RealType result; + if (false == arcsine_detail::check_dist( + "boost::math::median(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_min + x_max) / 2; } template - inline RealType skewness(const arcsine_distribution& /* dist */) + inline RealType skewness(const arcsine_distribution& dist) { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::skewness(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } return 0; } // skewness template - inline RealType kurtosis_excess(const arcsine_distribution& /* dist */) + inline RealType kurtosis_excess(const arcsine_distribution& dist) { - RealType result = -3; + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::kurtosis_excess(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + result = -3; return result / 2; } // kurtosis_excess template inline RealType kurtosis(const arcsine_distribution& dist) { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::kurtosis(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return 3 + kurtosis_excess(dist); } // kurtosis @@ -275,7 +348,7 @@ namespace boost RealType x = xx; // Argument checks: - RealType result = 0; + RealType result = 0; if (false == arcsine_detail::check_dist_and_x( function, lo, hi, x, diff --git a/test/test_arcsine.cpp b/test/test_arcsine.cpp index 68fc779c4..a2f5ef956 100644 --- a/test/test_arcsine.cpp +++ b/test/test_arcsine.cpp @@ -41,35 +41,183 @@ using std::endl; #include using std::numeric_limits; + +template +void test_ignore_policy(RealType) +{ + // Check on returns when errors are ignored. + if ((typeid(RealType) != typeid(boost::math::concepts::real_concept)) + && std::numeric_limits::has_infinity + && std::numeric_limits::has_quiet_NaN + ) + { // Ordinary floats only. + + using namespace boost::math; + // RealType inf = std::numeric_limits::infinity(); + RealType nan = std::numeric_limits::quiet_NaN(); + + using boost::math::policies::policy; + // Types of error whose action can be altered by policies:. + //using boost::math::policies::evaluation_error; + //using boost::math::policies::domain_error; + //using boost::math::policies::overflow_error; + //using boost::math::policies::underflow_error; + //using boost::math::policies::domain_error; + //using boost::math::policies::pole_error; + + //// Actions on error (in enum error_policy_type): + //using boost::math::policies::errno_on_error; + //using boost::math::policies::ignore_error; + //using boost::math::policies::throw_on_error; + //using boost::math::policies::denorm_error; + //using boost::math::policies::pole_error; + //using boost::math::policies::user_error; + + typedef policy< + boost::math::policies::domain_error, + boost::math::policies::overflow_error, + boost::math::policies::underflow_error, + boost::math::policies::denorm_error, + boost::math::policies::pole_error, + boost::math::policies::evaluation_error + > ignore_all_policy; + + typedef arcsine_distribution ignore_error_arcsine; + + // Only test NaN and infinity if type has these features (realconcept returns zero). + // Integers are always converted to RealType, + // others requires static cast to RealType from long double. + + if (std::numeric_limits::has_quiet_NaN) + { + // PDF + if (std::numeric_limits::has_infinity) + { + // pdf(ignore_error_arcsine(0, 1), std::numeric_limits::infinity()); + // std::cout << "arcsine(-1,+1) ignore error pdf (infinity) " << pdf(ignore_error_arcsine(-1, +1), std::numeric_limits::infinity()) << std::endl; + // arcsine(-1,+1) ignore error pdf (infinity) 1.#QNAN + } + BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), std::numeric_limits::infinity()))); // x == infinity + BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), std::numeric_limits::infinity()))); // x == infinity + BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), static_cast (-2)))); // x < xmin + BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), static_cast (-2)))); // x < xmin + BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), static_cast (+2)))); // x > x_max + BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), static_cast (+2)))); // x > x_max + + // Mean + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(-nan, 0)))); + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(+nan, 0)))); + + if (std::numeric_limits::has_infinity) + { + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(-std::numeric_limits::infinity(), 0)))); + // std::cout << "arcsine(-inf,+1) mean " << mean(ignore_error_arcsine(-std::numeric_limits::infinity())) << std::endl; + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(std::numeric_limits::infinity(), 0)))); + } + // Check error message is correct. + try + { + typedef arcsine_distribution signal_error_arcsine; + //std::cout << mean(signal_error_arcsine(-std::numeric_limits::infinity())) << std::endl; + // Error in function boost::math::arcsine_distribution::arcsine_distribution: x_min argument is -1.#INF, but must be finite ! + } + catch (std::exception ex) + { + std::cout << ex.what() << std::endl; + } + + // NaN constructors. + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(2, nan)))); + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(nan, nan)))); + BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(nan, 2)))); + + // Variance + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(nan, 0)))); + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(1, nan)))); + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(2, nan)))); + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(0, 0)))); + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(1, 0)))); + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(static_cast(1.7L), 0)))); + BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(2, 0)))); + + // Skewness + BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(nan, 0)))); + BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(-1, nan)))); + BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(0, 0)))); + BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(1, 0)))); + BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(2, 0)))); + BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(3, 0)))); + + // Kurtosis + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(nan, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(-1, nan)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(0, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(1, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(2, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(static_cast(2.0001L), 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(3, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(4, 0)))); + + // Kurtosis excess + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(nan, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(-1, nan)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(0, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(1, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(2, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(static_cast(2.0001L), 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(3, 0)))); + BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(4, 0)))); + } // has_quiet_NaN + + // + BOOST_CHECK(boost::math::isfinite(mean(ignore_error_arcsine(0, std::numeric_limits::epsilon())))); + + // Checks on error messages. + try + { + typedef arcsine_distribution signal_error_arcsine; + // std::cout << "mean(ignore_error_arcsine(0, std::numeric_limits::epsilon())) == " << std::endl; + // std::cout << mean(ignore_error_arcsine(0, std::numeric_limits::epsilon())) << std::endl; // 5.96046e-008 + //std::cout << "mean(ignore_error_arcsine(0, 0)) == " << std::endl; + //std::cout << mean(ignore_error_arcsine(0, 0)) << std::endl; // 1.#QNAN + } + catch (std::exception ex) + { + std::cout << ex.what() << std::endl; + } + + check_support >(arcsine_distribution(0, 1)); + } // ordinary floats. +} // template void test_ignore_policy(RealType) + + template RealType informax() -{ +{ //! \return Infinity else max_value. return ((std::numeric_limits::has_infinity) ? std::numeric_limits::infinity() : boost::math::tools::max_value()); } -/* template void test_spot( - RealType a, // alpha a - RealType b, // arcsine b + RealType a, // alpha a or lo or x_min + RealType b, // arcsine b or hi or x_maz RealType x, // Probability RealType P, // CDF of arcsine(a, b) - RealType Q, // Complement of CDF + RealType Q, // Complement of CDF of arcsine (a, b) RealType tol) // Test tolerance. { - boost::math::arcsine_distribution arcsine(a, b); - BOOST_CHECK_CLOSE_FRACTION(cdf(aarcsine, x), P, tol); + boost::math::arcsine_distribution anarcsine(a, b); + BOOST_CHECK_CLOSE_FRACTION(cdf(anarcsine, x), P, tol); if ((P < 0.99) && (Q < 0.99)) - { // We can only check this if P is not too close to 1, + { // We can only check this if P is not too close to 1, // so that we can guarantee that Q is free of error, - // (and similarly for Q) - BOOST_CHECK_CLOSE_FRACTION( - cdf(complement(aarcsine, x)), Q, tol); + // (and similarly for Q). + BOOST_CHECK_CLOSE_FRACTION(cdf(complement(anarcsine, x)), Q, tol); if (x != 0) { BOOST_CHECK_CLOSE_FRACTION( - quantile(aarcsine, P), x, tol); + quantile(anarcsine, P), x, tol); } else { @@ -79,24 +227,23 @@ void test_spot( { // Limit where this is checked: if exponent range is very large we may // run out of iterations in our root finding algorithm. - BOOST_CHECK(quantile(aarcsine, P) < boost::math::tools::epsilon() * 10); + BOOST_CHECK(quantile(anarcsine, P) < boost::math::tools::epsilon() * 10); } } // if k if (x != 0) { - BOOST_CHECK_CLOSE_FRACTION(quantile(complement(aarcsine, Q)), x, tol); + BOOST_CHECK_CLOSE_FRACTION(quantile(complement(anarcsine, Q)), x, tol); } else { // Just check quantile is very small: if ((std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) && (boost::is_floating_point::value)) { // Limit where this is checked: if exponent range is very large we may // run out of iterations in our root finding algorithm. - BOOST_CHECK(quantile(complement(aarcsine, Q)) < boost::math::tools::epsilon() * 10); + BOOST_CHECK(quantile(complement(anarcsine, Q)) < boost::math::tools::epsilon() * 10); } } // if x } } // template void test_spot -*/ template // Any floating-point type RealType. void test_spots(RealType) @@ -133,8 +280,25 @@ void test_spots(RealType) // 0.63661977236758134307553505349005744813783858296183 arcsine_distribution arcsine_01; // (Our) Standard arcsine. + // Member functions. + BOOST_CHECK_EQUAL(arcsine_01.x_min(), 0); + BOOST_CHECK_EQUAL(arcsine_01.x_max(), 1); + + // Derived functions. + BOOST_CHECK_EQUAL(mean(arcsine_01), 0.5); // 1 / (1 + 1) = 1/2 exactly. + BOOST_CHECK_EQUAL(median(arcsine_01), 0.5); // 1 / (1 + 1) = 1/2 exactly. + BOOST_CHECK_EQUAL(variance(arcsine_01), 0.125); // 1/8 = 0.125 + BOOST_CHECK_CLOSE_FRACTION(standard_deviation(arcsine_01), one_div_root_two() / 2, tolerance); // 1/ sqrt(s) = 0.35355339059327379 + BOOST_CHECK_EQUAL(skewness(arcsine_01), 0); // + BOOST_CHECK_EQUAL(kurtosis_excess(arcsine_01), -1.5); // 3/2 + BOOST_CHECK_EQUAL(support(arcsine_01).first, 0); // + BOOST_CHECK_EQUAL(range(arcsine_01).first, 0); // + BOOST_CHECK_THROW(mode(arcsine_01), std::domain_error); // Two modes at x_min and x_max, so throw instead. // PDF + // N[PDF[arcsinedistribution[0, 1], 0.25], 50] + // N[PDF[arcsinedistribution[0, 1], 0.75], 50] + // 0.73510519389572273268176866441729258852984864048885 BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.000001), static_cast(318.31004533885312973989414360099118178698415543136L), tolerance); BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.000005), static_cast(142.35286456604168061345817902422241622116338936911L), tolerance); @@ -179,14 +343,12 @@ void test_spots(RealType) // Quantile. // Check 1st, 2nd and 3rd quartiles. - - // N[PDF[arcsinedistribution[0, 1], 0.25], 50] - // 0.73510519389572273268176866441729258852984864048885 - BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast(0.25L)), static_cast(0.14644660940672624L), tolerance); BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast(0.5L)), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5 BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast(0.75L)), static_cast(0.85355339059327373L), tolerance); + + // N[CDF[arcsinedistribution[0, 1], 0.05], 50] == 0.14356629312870627075094188477505571882161519989741 BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast(0.14356629312870627075094188477505571882161519989741L)), 0.05, tolerance); @@ -232,6 +394,30 @@ void test_spots(RealType) BOOST_CHECK_SMALL(quantile(as_m11, static_cast(0.5L)), 2 * tolerance); // p = 0.5, x = 0 BOOST_CHECK_CLOSE_FRACTION(quantile(as_m11, static_cast(2) / 3), +static_cast(0.5L), 4 * tolerance); // p = 2/3, x = +0.5 + // Loop back tests. + test_spot( + static_cast(0), // lo or a + static_cast(1), // hi or b + static_cast(0.05), // Random variate x + static_cast(0.14356629312870627075094188477505571882161519989741L), // Probability of result (CDF of arcsine), P + static_cast(0.85643370687129372924905811522494428117838480010259L), // Complement of CDF Q = 1 - P + tolerance); // Test tolerance. + + test_spot( + static_cast(0), // lo or a + static_cast(1), // hi or b + static_cast(0.95), // Random variate x + static_cast(0.85643370687129372924905811522494428117838480010259L), // Probability of result (CDF of arcsine), P + static_cast(0.14356629312870627075094188477505571882161519989741L), // Complement of CDF Q = 1 - P + tolerance * 4); // Test tolerance (slightly inceased compared to x < 0.5 above). + + test_spot( + static_cast(0), // lo or a + static_cast(1), // hi or b + static_cast(static_cast(0.5L)), // Random variate x + static_cast(static_cast(0.5L)), // Probability of result (CDF of arcsine), P + static_cast(static_cast(0.5L)), // Complement of CDF Q = 1 - P + tolerance * 4); // Test tolerance. // Arcsine(-2, -1) xmin = -2, x_max = -1 - Asymmetric both negative. arcsine_distribution as_m2m1(-2, -1); @@ -265,6 +451,7 @@ void test_spots(RealType) BOOST_CHECK_THROW(mode(arcsine_distribution(static_cast(0), static_cast(1))), std::domain_error); // mode is undefined, and must throw domain_error! + BOOST_CHECK_THROW( // For various bad arguments. pdf( arcsine_distribution(static_cast(+1), static_cast(-1)), // min_x > max_x @@ -293,8 +480,8 @@ void test_spots(RealType) // Checks on things that are errors. // Construction with 'bad' parameters. - BOOST_CHECK_THROW(arcsine_distribution(+1, -1), std::domain_error); - BOOST_CHECK_THROW(arcsine_distribution(+1, 0), std::domain_error); + BOOST_CHECK_THROW(arcsine_distribution(+1, -1), std::domain_error); // max < min. + BOOST_CHECK_THROW(arcsine_distribution(+1, 0), std::domain_error); // max < min. arcsine_distribution<> dist; BOOST_CHECK_THROW(pdf(dist, -1), std::domain_error); @@ -351,13 +538,16 @@ void test_spots(RealType) // Error handling checks: check_out_of_range >(-1, +1); // (All) valid constructor parameter values. // and range and non-finite. + + test_ignore_policy(static_cast(0)); + } // template void test_spots(RealType) BOOST_AUTO_TEST_CASE(test_main) { BOOST_MATH_CONTROL_FP; - // Check that can generate arcsine distribution using one convenience methods: + // Check that can generate arcsine distribution using convenience method: using boost::math::arcsine; arcsine_distribution<> arcsine_01; // Using default RealType double. @@ -365,6 +555,7 @@ void test_spots(RealType) arcsine as; // Using typedef for default standard arcsine. + // BOOST_CHECK_EQUAL(as.x_min(), 0); // BOOST_CHECK_EQUAL(as.x_max(), 1); BOOST_CHECK_EQUAL(mean(as), 0.5); // 1 / (1 + 1) = 1/2 exactly. @@ -376,9 +567,8 @@ void test_spots(RealType) BOOST_CHECK_EQUAL(support(as).first, 0); // BOOST_CHECK_EQUAL(range(as).first, 0); // BOOST_CHECK_THROW(mode(as), std::domain_error); // Two modes at x_min and x_max, so throw instead. - // BOOST_CHECK_THROW(arcsine_distribution(+1, -1), std::domain_error); // min > max - // (Parameter value, arbitrarily zero, only communicates the floating point type). + // (Parameter value, arbitrarily zero, only communicates the floating point type). test_spots(0.0F); // Test float. test_spots(0.0); // Test double. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS @@ -392,8 +582,20 @@ void test_spots(RealType) /* + +Microsoft Visual Studio Professional 2013 +Version 12.0.30110.00 Update 1 + + 1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_arcsine.exe" + 1> Running 1 test case... + 1> Platform: Win32 + 1> Compiler: Microsoft Visual C++ version 12.0 ???? MSVC says 2013 + 1> STL : Dinkumware standard library version 610 + 1> Boost : 1.56.0 + Sample Output is: + 1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_arcsine.exe" 1> Running 1 test case... 1> Platform: Win32 1> Compiler: Microsoft Visual C++ version 12.0 @@ -406,7 +608,17 @@ void test_spots(RealType) 1> 1> *** No errors detected + GCC 4.9.1 + Running 1 test case... + tolerance = 2.38419e-007 + tolerance = 4.44089e-016 + tolerance = 4.44089e-016 + tolerance = 4.44089e-016 + + *** No errors detected + + RUN SUCCESSFUL (total time: 141ms) */