📄 test_beta_dist.cpp
字号:
// test_beta_dist.cpp// Copyright John Maddock 2006.// Copyright Paul A. Bristow 2007.// Use, modification and distribution are subject to the// Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)// Basic sanity tests for the beta Distribution.// http://members.aol.com/iandjmsmith/BETAEX.HTM beta distribution calculator// Appreas to be a 64-bit calculator showing 17 decimal digit (last is noisy).// Similar to mathCAD?// http://www.nuhertz.com/statmat/distributions.html#Beta// Pretty graphs and explanations for most distributions.// http://functions.wolfram.com/webMathematica/FunctionEvaluation.jsp// provided 40 decimal digits accuracy incomplete beta aka beta regularized == cdf// http://www.ausvet.com.au/pprev/content.php?page=PPscript// mode 0.75 5/95% 0.9 alpha 7.39 beta 3.13// http://www.epi.ucdavis.edu/diagnostictests/betabuster.html// Beta Buster also calculates alpha and beta from mode & percentile estimates.// This is NOT (yet) implemented.#ifdef _MSC_VER# pragma warning(disable: 4127) // conditional expression is constant.#endif#include <boost/math/concepts/real_concept.hpp> // for real_conceptusing ::boost::math::concepts::real_concept;#include <boost/math/distributions/beta.hpp> // for beta_distributionusing boost::math::beta_distribution;using boost::math::beta;#include <boost/test/included/test_exec_monitor.hpp> // for test_main#include <boost/test/floating_point_comparison.hpp> // for BOOST_CHECK_CLOSE_FRACTION#include <iostream>using std::cout;using std::endl;#include <limits>using std::numeric_limits;template <class RealType>void test_spot( RealType a, // alpha a RealType b, // beta b RealType x, // Probability RealType P, // CDF of beta(a, b) RealType Q, // Complement of CDF RealType tol) // Test tolerance.{ boost::math::beta_distribution<RealType> abeta(a, b); BOOST_CHECK_CLOSE_FRACTION(cdf(abeta, x), P, tol); if((P < 0.99) && (Q < 0.99)) { // 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(abeta, x)), Q, tol); if(x != 0) { BOOST_CHECK_CLOSE_FRACTION( quantile(abeta, P), x, tol); } else { // Just check quantile is very small: if((std::numeric_limits<RealType>::max_exponent <= std::numeric_limits<double>::max_exponent) && (boost::is_floating_point<RealType>::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(abeta, P) < boost::math::tools::epsilon<RealType>() * 10); } } // if k if(x != 0) { BOOST_CHECK_CLOSE_FRACTION(quantile(complement(abeta, Q)), x, tol); } else { // Just check quantile is very small: if((std::numeric_limits<RealType>::max_exponent <= std::numeric_limits<double>::max_exponent) && (boost::is_floating_point<RealType>::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(abeta, Q)) < boost::math::tools::epsilon<RealType>() * 10); } } // if x // Estimate alpha & beta from mean and variance: BOOST_CHECK_CLOSE_FRACTION( beta_distribution<RealType>::find_alpha(mean(abeta), variance(abeta)), abeta.alpha(), tol); BOOST_CHECK_CLOSE_FRACTION( beta_distribution<RealType>::find_beta(mean(abeta), variance(abeta)), abeta.beta(), tol); // Estimate sample alpha and beta from others: BOOST_CHECK_CLOSE_FRACTION( beta_distribution<RealType>::find_alpha(abeta.beta(), x, P), abeta.alpha(), tol); BOOST_CHECK_CLOSE_FRACTION( beta_distribution<RealType>::find_beta(abeta.alpha(), x, P), abeta.beta(), tol); } // if((P < 0.99) && (Q < 0.99) } // template <class RealType> void test_spottemplate <class RealType> // Any floating-point type RealType.void test_spots(RealType){ // Basic sanity checks with 'known good' values. // MathCAD test data is to double precision only, // so set tolerance to 100 eps expressed as a fraction, or // 100 eps of type double expressed as a fraction, // whichever is the larger. RealType tolerance = (std::max) (boost::math::tools::epsilon<RealType>(), static_cast<RealType>(std::numeric_limits<double>::epsilon())); // 0 if real_concept. cout << "Boost::math::tools::epsilon = " << boost::math::tools::epsilon<RealType>() <<endl; cout << "std::numeric_limits::epsilon = " << std::numeric_limits<RealType>::epsilon() <<endl; cout << "epsilon = " << tolerance; tolerance *= 1000; // Note: NO * 100 because is fraction, NOT %. cout << ", Tolerance = " << tolerance * 100 << "%." << endl; // RealType teneps = boost::math::tools::epsilon<RealType>() * 10; // Sources of spot test values: // MathCAD defines dbeta(x, s1, s2) pdf, s1 == alpha, s2 = beta, x = x in Wolfram // pbeta(x, s1, s2) cdf and qbeta(x, s1, s2) inverse of cdf // returns pr(X ,= x) when random variable X // has the beta distribution with parameters s1)alpha) and s2(beta). // s1 > 0 and s2 >0 and 0 < x < 1 (but allows x == 0! and x == 1!) // dbeta(0,1,1) = 0 // dbeta(0.5,1,1) = 1 using boost::math::beta_distribution; using ::boost::math::cdf; using ::boost::math::pdf; // Tests that should throw: BOOST_CHECK_THROW(mode(beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1))), std::domain_error); // mode is undefined, and throws domain_error! // BOOST_CHECK_THROW(median(beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1))), std::domain_error); // median is undefined, and throws domain_error! // But now median IS provided via derived accessor as quantile(half). BOOST_CHECK_THROW( // For various bad arguments. pdf( beta_distribution<RealType>(static_cast<RealType>(-1), static_cast<RealType>(1)), // bad alpha < 0. static_cast<RealType>(1)), std::domain_error); BOOST_CHECK_THROW( pdf( beta_distribution<RealType>(static_cast<RealType>(0), static_cast<RealType>(1)), // bad alpha == 0. static_cast<RealType>(1)), std::domain_error); BOOST_CHECK_THROW( pdf( beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(0)), // bad beta == 0. static_cast<RealType>(1)), std::domain_error); BOOST_CHECK_THROW( pdf( beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(-1)), // bad beta < 0. static_cast<RealType>(1)), std::domain_error); BOOST_CHECK_THROW( pdf( beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), // bad x < 0. static_cast<RealType>(-1)), std::domain_error); BOOST_CHECK_THROW( pdf( beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), // bad x > 1. static_cast<RealType>(999)), std::domain_error); // Some exact pdf values. BOOST_CHECK_EQUAL( // a = b = 1 is uniform distribution. pdf(beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), static_cast<RealType>(1)), // x static_cast<RealType>(1)); BOOST_CHECK_EQUAL( pdf(beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), static_cast<RealType>(0)), // x static_cast<RealType>(1)); BOOST_CHECK_CLOSE_FRACTION( pdf(beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), static_cast<RealType>(0.5)), // x static_cast<RealType>(1), tolerance); BOOST_CHECK_EQUAL( beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)).alpha(), static_cast<RealType>(1) ); // BOOST_CHECK_EQUAL( mean(beta_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1))), static_cast<RealType>(0.5) ); // Exact one half. BOOST_CHECK_CLOSE_FRACTION( pdf(beta_distribution<RealType>(static_cast<RealType>(2), static_cast<RealType>(2)), static_cast<RealType>(0.5)), // x static_cast<RealType>(1.5), // Exactly 3/2 tolerance); BOOST_CHECK_CLOSE_FRACTION( pdf(beta_distribution<RealType>(static_cast<RealType>(2), static_cast<RealType>(2)), static_cast<RealType>(0.5)), // x static_cast<RealType>(1.5), // Exactly 3/2 tolerance); // CDF BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(2), static_cast<RealType>(2)), static_cast<RealType>(0.1)), // x static_cast<RealType>(0.02800000000000000000000000000000000000000L), // Seems exact. // http://functions.wolfram.com/webMathematica/FunctionEvaluation.jsp?name=BetaRegularized&ptype=0&z=0.1&a=2&b=2&digits=40 tolerance); BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(2), static_cast<RealType>(2)), static_cast<RealType>(0.0001)), // x static_cast<RealType>(2.999800000000000000000000000000000000000e-8L), // http://members.aol.com/iandjmsmith/BETAEX.HTM 2.9998000000004 // http://functions.wolfram.com/webMathematica/FunctionEvaluation.jsp?name=BetaRegularized&ptype=0&z=0.0001&a=2&b=2&digits=40 tolerance); BOOST_CHECK_CLOSE_FRACTION( pdf(beta_distribution<RealType>(static_cast<RealType>(2), static_cast<RealType>(2)), static_cast<RealType>(0.0001)), // x static_cast<RealType>(0.0005999400000000004L), // http://members.aol.com/iandjmsmith/BETAEX.HTM // Slightly higher tolerance for real concept: (std::numeric_limits<RealType>::is_specialized ? 1 : 10) * tolerance); BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(2), static_cast<RealType>(2)), static_cast<RealType>(0.9999)), // x static_cast<RealType>(0.999999970002L), // http://members.aol.com/iandjmsmith/BETAEX.HTM // Wolfram 0.9999999700020000000000000000000000000000 tolerance); BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(0.5), static_cast<RealType>(2)), static_cast<RealType>(0.9)), // x static_cast<RealType>(0.9961174629530394895796514664963063381217L), // Wolfram tolerance); BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(0.5), static_cast<RealType>(0.5)), static_cast<RealType>(0.1)), // x static_cast<RealType>(0.2048327646991334516491978475505189480977L), // Wolfram tolerance); BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(0.5), static_cast<RealType>(0.5)), static_cast<RealType>(0.9)), // x static_cast<RealType>(0.7951672353008665483508021524494810519023L), // Wolfram tolerance); BOOST_CHECK_CLOSE_FRACTION( quantile(beta_distribution<RealType>(static_cast<RealType>(0.5), static_cast<RealType>(0.5)), static_cast<RealType>(0.7951672353008665483508021524494810519023L)), // x static_cast<RealType>(0.9), // Wolfram tolerance); BOOST_CHECK_CLOSE_FRACTION( cdf(beta_distribution<RealType>(static_cast<RealType>(0.5), static_cast<RealType>(0.5)), static_cast<RealType>(0.6)), // x static_cast<RealType>(0.5640942168489749316118742861695149357858L), // Wolfram tolerance);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -