mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Add SYCL testing of normal dist Add CUDA testing of normal dist Add NVRTC testing of normal dist NVRTC fixes Move headers for NVRTC support Add GPU support to inverse gaussian dist Add NVRTC testing of inverse Gaussian dist Add CUDA testing of inverse gaussian dist Add SYCL testing of inverse gaussian dist Add GPU support to lognormal dist Add SYCL testing of lognormal dist Add CUDA testing of lognormal dist Add nvrtc testing of lognormal dist Add GPU support to negative binomial dist Avoid float_prior on GPU platform Add NVRTC testing of negative binomial dist Fix ambiguous use of nextafter Add CUDA testing of negative binomial dist Fix float_prior workaround Add SYCL testing of negative binomial dist Add GPU support to non_central_beta dist Add SYCL testing of nc beta dist Add CUDA testing of nc beta dist Enable generic dist handling on GPU Add GPU support to brent_find_minima Add NVRTC testing of nc beta dist Add utility header Replace non-functional macro with new function Add GPU support to non central chi squared dist Add SYCL testing of non central chi squared dist Add missing macro definition Markup generic quantile finder Add CUDA testing of non central chi squared dist Add NVRTC testing of non central chi squared dist Add GPU support to the non-central f dist Add SYCL testing of ncf Add CUDA testing of ncf dist Add NVRTC testing of ncf dist Add GPU support to students_t dist Add SYCL testing of students_t dist Add CUDA testing of students_t Add NVRTC testing of students_t dist Workaround for header cycle Add GPU support to pareto dist Add SYCL testing of pareto dist Add CUDA testing of pareto dist Add NVRTC testing of pareto dist Add missing header Add GPU support to poisson dist Add SYCL testing of poisson dist Add CUDA testing of poisson dist Add NVRTC testing of poisson dist Add forward decl for NVRTC platform Add GPU support to rayleigh dist Add CUDA testing of rayleigh dist Add SYCL testing of rayleigh dist Add NVRTC testing of rayleigh dist Add GPU support to triangular dist Add SYCL testing of triangular dist Add NVRTC testing of triangular dist Add CUDA testing of triangular dist Add GPU support to the uniform dist Add CUDA testing of uniform dist Add SYCL testing of uniform dist Add NVRTC testing of uniform dist Fix missing header Add markers to docs
684 lines
27 KiB
C++
684 lines
27 KiB
C++
// test_poisson.cpp
|
|
|
|
// Copyright Paul A. Bristow 2007.
|
|
// Copyright John Maddock 2006.
|
|
|
|
// 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 test for Poisson Cumulative Distribution Function.
|
|
|
|
#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
|
|
|
|
#if !defined(TEST_FLOAT) && !defined(TEST_DOUBLE) && !defined(TEST_LDOUBLE) && !defined(TEST_REAL_CONCEPT)
|
|
# define TEST_FLOAT
|
|
# define TEST_DOUBLE
|
|
# define TEST_LDOUBLE
|
|
# define TEST_REAL_CONCEPT
|
|
#endif
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning(disable: 4127) // conditional expression is constant.
|
|
#endif
|
|
|
|
#include <boost/math/tools/config.hpp>
|
|
|
|
#define BOOST_TEST_MAIN
|
|
#include <boost/test/unit_test.hpp> // Boost.Test
|
|
#include <boost/test/tools/floating_point_comparison.hpp>
|
|
|
|
#ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
|
|
#include <boost/math/concepts/real_concept.hpp> // for real_concept
|
|
#endif
|
|
|
|
#include <boost/math/distributions/poisson.hpp>
|
|
using boost::math::poisson_distribution;
|
|
|
|
#include <boost/math/special_functions/gamma.hpp> // for (incomplete) gamma.
|
|
// using boost::math::qamma_Q;
|
|
#include "table_type.hpp"
|
|
#include "test_out_of_range.hpp"
|
|
#include "../include_private/boost/math/tools/test.hpp"
|
|
|
|
#include <iostream>
|
|
using std::cout;
|
|
using std::endl;
|
|
using std::setprecision;
|
|
using std::showpoint;
|
|
using std::ios;
|
|
#include <limits>
|
|
using std::numeric_limits;
|
|
|
|
template <class RealType> // Any floating-point type RealType.
|
|
void test_spots(RealType)
|
|
{
|
|
// Basic sanity checks, tolerance is about numeric_limits<RealType>::digits10 decimal places,
|
|
// guaranteed for type RealType, eg 6 for float, 15 for double,
|
|
// expressed as a percentage (so -2) for BOOST_CHECK_CLOSE,
|
|
|
|
int decdigits = std::numeric_limits<RealType>::digits10;
|
|
// May eb >15 for 80 and 128-bit FP types.
|
|
if (decdigits <= 0)
|
|
{ // decdigits is not defined, for example real concept,
|
|
// so assume precision of most test data is double (for example, MathCAD).
|
|
decdigits = std::numeric_limits<double>::digits10; // == 15 for 64-bit
|
|
}
|
|
if (decdigits > 15 ) // numeric_limits<double>::digits10)
|
|
{ // 15 is the accuracy of the MathCAD test data.
|
|
decdigits = 15; // numeric_limits<double>::digits10;
|
|
}
|
|
|
|
decdigits -= 1; // Perhaps allow some decimal digit(s) margin of numerical error.
|
|
RealType tolerance = static_cast<RealType>(std::pow(10., static_cast<double>(2-decdigits))); // 1e-6 (-2 so as %)
|
|
tolerance *= 2; // Allow some bit(s) small margin (2 means + or - 1 bit) of numerical error.
|
|
// Typically 2e-13% = 2e-15 as fraction for double.
|
|
|
|
// Sources of spot test values:
|
|
|
|
// Many be some combinations for which the result is 'exact',
|
|
// or at least is good to 40 decimal digits.
|
|
// 40 decimal digits includes 128-bit significand User Defined Floating-Point types,
|
|
|
|
// Best source of accurate values is:
|
|
// Mathworld online calculator (40 decimal digits precision, suitable for up to 128-bit significands)
|
|
// http://functions.wolfram.com/webMathematica/FunctionEvaluation.jsp?name=GammaRegularized
|
|
// GammaRegularized is same as gamma incomplete, gamma or gamma_q(a, x) or Q(a, z).
|
|
|
|
// http://documents.wolfram.com/calculationcenter/v2/Functions/ListsMatrices/Statistics/PoissonDistribution.html
|
|
|
|
// MathCAD defines ppois(k, lambda== mean) as k integer, k >=0.
|
|
// ppois(0, 5) = 6.73794699908547e-3
|
|
// ppois(1, 5) = 0.040427681994513;
|
|
// ppois(10, 10) = 5.830397501929850E-001
|
|
// ppois(10, 1) = 9.999999899522340E-001
|
|
// ppois(5,5) = 0.615960654833065
|
|
|
|
// qpois returns inverse Poisson distribution, that is the smallest (floor) k so that ppois(k, lambda) >= p
|
|
// p is real number, real mean lambda > 0
|
|
// k is approximately the integer for which probability(X <= k) = p
|
|
// when random variable X has the Poisson distribution with parameters lambda.
|
|
// Uses discrete bisection.
|
|
// qpois(6.73794699908547e-3, 5) = 1
|
|
// qpois(0.040427681994513, 5) =
|
|
|
|
// Test Poisson with spot values from MathCAD 'known good'.
|
|
|
|
using boost::math::poisson_distribution;
|
|
using ::boost::math::poisson;
|
|
using ::boost::math::cdf;
|
|
using ::boost::math::pdf;
|
|
|
|
// Check that bad arguments throw.
|
|
#ifndef BOOST_MATH_NO_EXCEPTIONS
|
|
BOOST_MATH_CHECK_THROW(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(0)), // mean zero is bad.
|
|
static_cast<RealType>(0)), // even for a good k.
|
|
std::domain_error); // Expected error to be thrown.
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(-1)), // mean negative is bad.
|
|
static_cast<RealType>(0)),
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unit OK,
|
|
static_cast<RealType>(-1)), // but negative events is bad.
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(0)), // mean zero is bad.
|
|
static_cast<RealType>(99999)), // for any k events.
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(0)), // mean zero is bad.
|
|
static_cast<RealType>(99999)), // for any k events.
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
quantile(poisson_distribution<RealType>(static_cast<RealType>(0)), // mean zero.
|
|
static_cast<RealType>(0.5)), // probability OK.
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
quantile(poisson_distribution<RealType>(static_cast<RealType>(-1)),
|
|
static_cast<RealType>(-1)), // bad probability.
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
quantile(poisson_distribution<RealType>(static_cast<RealType>(1)),
|
|
static_cast<RealType>(-1)), // bad probability.
|
|
std::domain_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
quantile(poisson_distribution<RealType>(static_cast<RealType>(1)),
|
|
static_cast<RealType>(1)), // bad probability.
|
|
std::overflow_error);
|
|
|
|
BOOST_MATH_CHECK_THROW(
|
|
quantile(complement(poisson_distribution<RealType>(static_cast<RealType>(1)),
|
|
static_cast<RealType>(0))), // bad probability.
|
|
std::overflow_error);
|
|
#endif
|
|
|
|
BOOST_CHECK_EQUAL(
|
|
quantile(poisson_distribution<RealType>(static_cast<RealType>(1)),
|
|
static_cast<RealType>(0)), // bad probability.
|
|
0);
|
|
|
|
BOOST_CHECK_EQUAL(
|
|
quantile(complement(poisson_distribution<RealType>(static_cast<RealType>(1)),
|
|
static_cast<RealType>(1))), // bad probability.
|
|
0);
|
|
|
|
// Check some test values.
|
|
|
|
BOOST_CHECK_CLOSE( // mode
|
|
mode(poisson_distribution<RealType>(static_cast<RealType>(4))), // mode = mean = 4.
|
|
static_cast<RealType>(4), // mode.
|
|
tolerance);
|
|
|
|
//BOOST_CHECK_CLOSE( // mode
|
|
// median(poisson_distribution<RealType>(static_cast<RealType>(4))), // mode = mean = 4.
|
|
// static_cast<RealType>(4), // mode.
|
|
// tolerance);
|
|
poisson_distribution<RealType> dist4(static_cast<RealType>(40));
|
|
|
|
BOOST_CHECK_CLOSE( // median
|
|
median(dist4), // mode = mean = 4. median = 40.328333333333333
|
|
quantile(dist4, static_cast<RealType>(0.5)), // 39.332839138842637
|
|
tolerance);
|
|
|
|
// PDF
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(poisson_distribution<RealType>(static_cast<RealType>(4)), // mean 4.
|
|
static_cast<RealType>(0)),
|
|
static_cast<RealType>(1.831563888873410E-002), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(poisson_distribution<RealType>(static_cast<RealType>(4)), // mean 4.
|
|
static_cast<RealType>(2)),
|
|
static_cast<RealType>(1.465251111098740E-001), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(poisson_distribution<RealType>(static_cast<RealType>(20)), // mean big.
|
|
static_cast<RealType>(1)), // k small
|
|
static_cast<RealType>(4.122307244877130E-008), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(poisson_distribution<RealType>(static_cast<RealType>(4)), // mean 4.
|
|
static_cast<RealType>(20)), // K>> mean
|
|
static_cast<RealType>(8.277463646553730E-009), // probability.
|
|
tolerance);
|
|
|
|
// LOGPDF
|
|
BOOST_CHECK_CLOSE(
|
|
logpdf(poisson_distribution<RealType>(static_cast<RealType>(4)), // mean 4.
|
|
static_cast<RealType>(0)),
|
|
log(static_cast<RealType>(1.831563888873410E-002)), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
logpdf(poisson_distribution<RealType>(static_cast<RealType>(4)), // mean 4.
|
|
static_cast<RealType>(2)),
|
|
log(static_cast<RealType>(1.465251111098740E-001)), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
logpdf(poisson_distribution<RealType>(static_cast<RealType>(20)), // mean big.
|
|
static_cast<RealType>(1)), // k small
|
|
log(static_cast<RealType>(4.122307244877130E-008)), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
logpdf(poisson_distribution<RealType>(static_cast<RealType>(4)), // mean 4.
|
|
static_cast<RealType>(20)), // K>> mean
|
|
log(static_cast<RealType>(8.277463646553730E-009)), // probability.
|
|
tolerance);
|
|
|
|
// CDF
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(0)), // zero k events.
|
|
static_cast<RealType>(3.678794411714420E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(1)), // one k event.
|
|
static_cast<RealType>(7.357588823428830E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(2)), // two k events.
|
|
static_cast<RealType>(9.196986029286060E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(10)), // two k events.
|
|
static_cast<RealType>(9.999999899522340E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(15)), // two k events.
|
|
static_cast<RealType>(9.999999999999810E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(16)), // two k events.
|
|
static_cast<RealType>(9.999999999999990E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(17)), // two k events.
|
|
static_cast<RealType>(1.), // probability unity for double.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(33)), // k events at limit for float unchecked_factorial table.
|
|
static_cast<RealType>(1.), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(100)), // mean 100.
|
|
static_cast<RealType>(33)), // k events at limit for float unchecked_factorial table.
|
|
static_cast<RealType>(6.328271240363390E-15), // probability is tiny.
|
|
tolerance * static_cast<RealType>(2e11)); // 6.3495253382825722e-015 MathCAD
|
|
// Note that there two tiny probability are much more different.
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(100)), // mean 100.
|
|
static_cast<RealType>(34)), // k events at limit for float unchecked_factorial table.
|
|
static_cast<RealType>(1.898481372109020E-14), // probability is tiny.
|
|
tolerance*static_cast<RealType>(2e11)); // 1.8984813721090199e-014 MathCAD
|
|
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(33)), // mean = k
|
|
static_cast<RealType>(33)), // k events above limit for float unchecked_factorial table.
|
|
static_cast<RealType>(5.461191812386560E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(33)), // mean = k-1
|
|
static_cast<RealType>(34)), // k events above limit for float unchecked_factorial table.
|
|
static_cast<RealType>(6.133535681502950E-1), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1)), // mean unity.
|
|
static_cast<RealType>(34)), // k events above limit for float unchecked_factorial table.
|
|
static_cast<RealType>(1.), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(5.)), // mean
|
|
static_cast<RealType>(5)), // k events.
|
|
static_cast<RealType>(0.615960654833065), // probability.
|
|
tolerance);
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(5.)), // mean
|
|
static_cast<RealType>(1)), // k events.
|
|
static_cast<RealType>(0.040427681994512805), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(5.)), // mean
|
|
static_cast<RealType>(0)), // k events (uses special case formula, not gamma).
|
|
static_cast<RealType>(0.006737946999085467), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(1.)), // mean
|
|
static_cast<RealType>(0)), // k events (uses special case formula, not gamma).
|
|
static_cast<RealType>(0.36787944117144233), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(10.)), // mean
|
|
static_cast<RealType>(10)), // k events.
|
|
static_cast<RealType>(0.5830397501929856), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(4.)), // mean
|
|
static_cast<RealType>(5)), // k events.
|
|
static_cast<RealType>(0.785130387030406), // probability.
|
|
tolerance);
|
|
|
|
// complement CDF
|
|
BOOST_CHECK_CLOSE( // Complement CDF
|
|
cdf(complement(poisson_distribution<RealType>(static_cast<RealType>(4.)), // mean
|
|
static_cast<RealType>(5))), // k events.
|
|
static_cast<RealType>(1 - 0.785130387030406), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE( // Complement CDF
|
|
cdf(complement(poisson_distribution<RealType>(static_cast<RealType>(4.)), // mean
|
|
static_cast<RealType>(0))), // Zero k events (uses special case formula, not gamma).
|
|
static_cast<RealType>(0.98168436111126578), // probability.
|
|
tolerance);
|
|
BOOST_CHECK_CLOSE( // Complement CDF
|
|
cdf(complement(poisson_distribution<RealType>(static_cast<RealType>(1.)), // mean
|
|
static_cast<RealType>(0))), // Zero k events (uses special case formula, not gamma).
|
|
static_cast<RealType>(0.63212055882855767), // probability.
|
|
tolerance);
|
|
|
|
// Example where k is bigger than max_factorial (>34 for float)
|
|
// (therefore using log gamma so perhaps less accurate).
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(40.)), // mean
|
|
static_cast<RealType>(40)), // k events.
|
|
static_cast<RealType>(0.5419181783625430), // probability.
|
|
tolerance);
|
|
|
|
// Quantile & complement.
|
|
BOOST_CHECK_CLOSE(
|
|
boost::math::quantile(
|
|
poisson_distribution<RealType>(5), // mean.
|
|
static_cast<RealType>(0.615960654833065)), // probability.
|
|
static_cast<RealType>(5.), // Expect k = 5
|
|
tolerance/5); //
|
|
|
|
// EQUAL is too optimistic - fails [5.0000000000000124 != 5]
|
|
// BOOST_CHECK_EQUAL(boost::math::quantile( //
|
|
// poisson_distribution<RealType>(5.), // mean.
|
|
// static_cast<RealType>(0.615960654833065)), // probability.
|
|
// static_cast<RealType>(5.)); // Expect k = 5 events.
|
|
|
|
BOOST_CHECK_CLOSE(boost::math::quantile(
|
|
poisson_distribution<RealType>(4), // mean.
|
|
static_cast<RealType>(0.785130387030406)), // probability.
|
|
static_cast<RealType>(5.), // Expect k = 5 events.
|
|
tolerance/5);
|
|
|
|
// Check on quantile of other examples of inverse of cdf.
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(10.)), // mean
|
|
static_cast<RealType>(10)), // k events.
|
|
static_cast<RealType>(0.5830397501929856), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(boost::math::quantile( // inverse of cdf above.
|
|
poisson_distribution<RealType>(10.), // mean.
|
|
static_cast<RealType>(0.5830397501929856)), // probability.
|
|
static_cast<RealType>(10.), // Expect k = 10 events.
|
|
tolerance/5);
|
|
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(poisson_distribution<RealType>(static_cast<RealType>(4.)), // mean
|
|
static_cast<RealType>(5)), // k events.
|
|
static_cast<RealType>(0.785130387030406), // probability.
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(boost::math::quantile( // inverse of cdf above.
|
|
poisson_distribution<RealType>(4.), // mean.
|
|
static_cast<RealType>(0.785130387030406)), // probability.
|
|
static_cast<RealType>(5.), // Expect k = 10 events.
|
|
tolerance/5);
|
|
|
|
|
|
|
|
//BOOST_CHECK_CLOSE(boost::math::quantile(
|
|
// poisson_distribution<RealType>(5), // mean.
|
|
// static_cast<RealType>(0.785130387030406)), // probability.
|
|
// // 6.1882832344329559 result but MathCAD givest smallest integer ppois(k, mean) >= prob
|
|
// static_cast<RealType>(6.), // Expect k = 6 events.
|
|
// tolerance/5);
|
|
|
|
//BOOST_CHECK_CLOSE(boost::math::quantile(
|
|
// poisson_distribution<RealType>(5), // mean.
|
|
// static_cast<RealType>(0.77)), // probability.
|
|
// // 6.1882832344329559 result but MathCAD givest smallest integer ppois(k, mean) >= prob
|
|
// static_cast<RealType>(7.), // Expect k = 6 events.
|
|
// tolerance/5);
|
|
|
|
//BOOST_CHECK_CLOSE(boost::math::quantile(
|
|
// poisson_distribution<RealType>(5), // mean.
|
|
// static_cast<RealType>(0.75)), // probability.
|
|
// // 6.1882832344329559 result but MathCAD givest smallest integer ppois(k, mean) >= prob
|
|
// static_cast<RealType>(6.), // Expect k = 6 events.
|
|
// tolerance/5);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
boost::math::quantile(
|
|
complement(
|
|
poisson_distribution<RealType>(4),
|
|
static_cast<RealType>(1 - 0.785130387030406))), // complement.
|
|
static_cast<RealType>(5), // Expect k = 5 events.
|
|
tolerance/5);
|
|
|
|
BOOST_CHECK_EQUAL(boost::math::quantile( // Check case when probability < cdf(0) (== pdf(0))
|
|
poisson_distribution<RealType>(1), // mean is small, so cdf and pdf(0) are about 0.35.
|
|
static_cast<RealType>(0.0001)), // probability < cdf(0).
|
|
static_cast<RealType>(0)); // Expect k = 0 events exactly.
|
|
|
|
BOOST_CHECK_EQUAL(
|
|
boost::math::quantile(
|
|
complement(
|
|
poisson_distribution<RealType>(1),
|
|
static_cast<RealType>(0.9999))), // complement, so 1-probability < cdf(0)
|
|
static_cast<RealType>(0)); // Expect k = 0 events exactly.
|
|
|
|
//
|
|
// Test quantile policies against test data:
|
|
//
|
|
#define T RealType
|
|
#include "poisson_quantile.ipp"
|
|
|
|
for(unsigned i = 0; i < poisson_quantile_data.size(); ++i)
|
|
{
|
|
using namespace boost::math::policies;
|
|
typedef policy<discrete_quantile<boost::math::policies::real> > P1;
|
|
typedef policy<discrete_quantile<integer_round_down> > P2;
|
|
typedef policy<discrete_quantile<integer_round_up> > P3;
|
|
typedef policy<discrete_quantile<integer_round_outwards> > P4;
|
|
typedef policy<discrete_quantile<integer_round_inwards> > P5;
|
|
typedef policy<discrete_quantile<integer_round_nearest> > P6;
|
|
RealType tol = boost::math::tools::epsilon<RealType>() * 20;
|
|
if(!boost::is_floating_point<RealType>::value)
|
|
tol *= 7;
|
|
//
|
|
// Check full real value first:
|
|
//
|
|
poisson_distribution<RealType, P1> p1(poisson_quantile_data[i][0]);
|
|
RealType x = quantile(p1, poisson_quantile_data[i][1]);
|
|
BOOST_CHECK_CLOSE_FRACTION(x, poisson_quantile_data[i][2], tol);
|
|
x = quantile(complement(p1, poisson_quantile_data[i][1]));
|
|
BOOST_CHECK_CLOSE_FRACTION(x, poisson_quantile_data[i][3], tol * 3);
|
|
//
|
|
// Now with round down to integer:
|
|
//
|
|
poisson_distribution<RealType, P2> p2(poisson_quantile_data[i][0]);
|
|
x = quantile(p2, poisson_quantile_data[i][1]);
|
|
BOOST_CHECK_EQUAL(x, floor(poisson_quantile_data[i][2]));
|
|
x = quantile(complement(p2, poisson_quantile_data[i][1]));
|
|
BOOST_CHECK_EQUAL(x, floor(poisson_quantile_data[i][3]));
|
|
//
|
|
// Now with round up to integer:
|
|
//
|
|
poisson_distribution<RealType, P3> p3(poisson_quantile_data[i][0]);
|
|
x = quantile(p3, poisson_quantile_data[i][1]);
|
|
BOOST_CHECK_EQUAL(x, ceil(poisson_quantile_data[i][2]));
|
|
x = quantile(complement(p3, poisson_quantile_data[i][1]));
|
|
BOOST_CHECK_EQUAL(x, ceil(poisson_quantile_data[i][3]));
|
|
//
|
|
// Now with round to integer "outside":
|
|
//
|
|
poisson_distribution<RealType, P4> p4(poisson_quantile_data[i][0]);
|
|
x = quantile(p4, poisson_quantile_data[i][1]);
|
|
BOOST_CHECK_EQUAL(x, poisson_quantile_data[i][1] < 0.5f ? floor(poisson_quantile_data[i][2]) : ceil(poisson_quantile_data[i][2]));
|
|
x = quantile(complement(p4, poisson_quantile_data[i][1]));
|
|
BOOST_CHECK_EQUAL(x, poisson_quantile_data[i][1] < 0.5f ? ceil(poisson_quantile_data[i][3]) : floor(poisson_quantile_data[i][3]));
|
|
//
|
|
// Now with round to integer "inside":
|
|
//
|
|
poisson_distribution<RealType, P5> p5(poisson_quantile_data[i][0]);
|
|
x = quantile(p5, poisson_quantile_data[i][1]);
|
|
BOOST_CHECK_EQUAL(x, poisson_quantile_data[i][1] < 0.5f ? ceil(poisson_quantile_data[i][2]) : floor(poisson_quantile_data[i][2]));
|
|
x = quantile(complement(p5, poisson_quantile_data[i][1]));
|
|
BOOST_CHECK_EQUAL(x, poisson_quantile_data[i][1] < 0.5f ? floor(poisson_quantile_data[i][3]) : ceil(poisson_quantile_data[i][3]));
|
|
//
|
|
// Now with round to nearest integer:
|
|
//
|
|
poisson_distribution<RealType, P6> p6(poisson_quantile_data[i][0]);
|
|
x = quantile(p6, poisson_quantile_data[i][1]);
|
|
BOOST_CHECK_EQUAL(x, floor(poisson_quantile_data[i][2] + 0.5f));
|
|
x = quantile(complement(p6, poisson_quantile_data[i][1]));
|
|
BOOST_CHECK_EQUAL(x, floor(poisson_quantile_data[i][3] + 0.5f));
|
|
}
|
|
check_out_of_range<poisson_distribution<RealType> >(1);
|
|
} // template <class RealType>void test_spots(RealType)
|
|
|
|
//
|
|
|
|
BOOST_AUTO_TEST_CASE( test_main )
|
|
{
|
|
// Check that can construct normal distribution using the two convenience methods:
|
|
using namespace boost::math;
|
|
poisson myp1(2); // Using typedef
|
|
poisson_distribution<> myp2(2); // Using default RealType double.
|
|
|
|
// Basic sanity-check spot values.
|
|
|
|
// Some plain double examples & tests:
|
|
cout.precision(17); // double max_digits10
|
|
cout.setf(ios::showpoint);
|
|
|
|
poisson mypoisson(4.); // // mean = 4, default FP type is double.
|
|
cout << "mean(mypoisson, 4.) == " << mean(mypoisson) << endl;
|
|
cout << "mean(mypoisson, 0.) == " << mean(mypoisson) << endl;
|
|
cout << "cdf(mypoisson, 2.) == " << cdf(mypoisson, 2.) << endl;
|
|
cout << "pdf(mypoisson, 2.) == " << pdf(mypoisson, 2.) << endl;
|
|
|
|
// poisson mydudpoisson(0.);
|
|
// throws (if BOOST_MATH_DOMAIN_ERROR_POLICY == throw_on_error).
|
|
|
|
#ifndef BOOST_MATH_NO_EXCEPTIONS
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_MATH_CHECK_THROW(poisson mydudpoisson(-1), std::domain_error);// Mean must be > 0.
|
|
BOOST_MATH_CHECK_THROW(poisson mydudpoisson(-1), std::logic_error);// Mean must be > 0.
|
|
#else
|
|
BOOST_MATH_CHECK_THROW(poisson(-1), std::domain_error);// Mean must be > 0.
|
|
BOOST_MATH_CHECK_THROW(poisson(-1), std::logic_error);// Mean must be > 0.
|
|
#endif
|
|
// Passes the check because logic_error is a parent????
|
|
// BOOST_MATH_CHECK_THROW(poisson mydudpoisson(-1), std::overflow_error); // fails the check
|
|
// because overflow_error is unrelated - except from std::exception
|
|
BOOST_MATH_CHECK_THROW(cdf(mypoisson, -1), std::domain_error); // k must be >= 0
|
|
#endif
|
|
BOOST_CHECK_EQUAL(mean(mypoisson), 4.);
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(mypoisson, 2.), // k events = 2.
|
|
1.465251111098740E-001, // probability.
|
|
5e-13);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(mypoisson, 2.), // k events = 2.
|
|
0.238103305553545, // probability.
|
|
5e-13);
|
|
|
|
|
|
#if 0
|
|
// Compare cdf from finite sum of pdf and gamma_q.
|
|
using boost::math::cdf;
|
|
using boost::math::pdf;
|
|
|
|
double mean = 4.;
|
|
cout.precision(17); // double max_digits10
|
|
cout.setf(ios::showpoint);
|
|
cout << showpoint << endl; // Ensure trailing zeros are shown.
|
|
// This also helps show the expected precision max_digits10
|
|
//cout.unsetf(ios::showpoint); // No trailing zeros are shown.
|
|
|
|
cout << "k pdf sum cdf diff" << endl;
|
|
double sum = 0.;
|
|
for (int i = 0; i <= 50; i++)
|
|
{
|
|
cout << i << ' ' ;
|
|
double p = pdf(poisson_distribution<double>(mean), static_cast<double>(i));
|
|
sum += p;
|
|
|
|
cout << p << ' ' << sum << ' '
|
|
<< cdf(poisson_distribution<double>(mean), static_cast<double>(i)) << ' ';
|
|
{
|
|
cout << boost::math::gamma_q<double>(i+1, mean); // cdf
|
|
double diff = boost::math::gamma_q<double>(i+1, mean) - sum; // cdf -sum
|
|
cout << setprecision (2) << ' ' << diff; // 0 0 to 4, 1 eps 5 to 9, 10 to 20 2 eps, 21 upwards 3 eps
|
|
|
|
}
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(mypoisson, static_cast<double>(i)),
|
|
sum, // of pdfs.
|
|
4e-14); // Fails at 2e-14
|
|
// This call puts the precision etc back to default 6 !!!
|
|
cout << setprecision(17) << showpoint;
|
|
|
|
|
|
cout << endl;
|
|
}
|
|
|
|
cout << cdf(poisson_distribution<double>(5), static_cast<double>(0)) << ' ' << endl; // 0.006737946999085467
|
|
cout << cdf(poisson_distribution<double>(5), static_cast<double>(1)) << ' ' << endl; // 0.040427681994512805
|
|
cout << cdf(poisson_distribution<double>(2), static_cast<double>(3)) << ' ' << endl; // 0.85712346049854715
|
|
|
|
{ // Compare approximate formula in Wikipedia with quantile(half)
|
|
for (int i = 1; i < 100; i++)
|
|
{
|
|
poisson_distribution<double> distn(static_cast<double>(i));
|
|
cout << i << ' ' << median(distn) << ' ' << quantile(distn, 0.5) << ' '
|
|
<< median(distn) - quantile(distn, 0.5) << endl; // formula appears to be out-by-one??
|
|
} // so quantile(half) used via derived accressors.
|
|
}
|
|
#endif
|
|
|
|
// (Parameter value, arbitrarily zero, only communicates the floating-point type).
|
|
#ifdef TEST_POISSON
|
|
test_spots(0.0F); // Test float.
|
|
#endif
|
|
#ifdef TEST_DOUBLE
|
|
test_spots(0.0); // Test double.
|
|
#endif
|
|
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
|
if (std::numeric_limits<long double>::digits10 > std::numeric_limits<double>::digits10)
|
|
{ // long double is better than double (so not MSVC where they are same).
|
|
#ifdef TEST_LDOUBLE
|
|
test_spots(0.0L); // Test long double.
|
|
#endif
|
|
}
|
|
|
|
#ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
|
|
#ifdef TEST_REAL_CONCEPT
|
|
test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
} // BOOST_AUTO_TEST_CASE( test_main )
|
|
|
|
/*
|
|
|
|
Output:
|
|
|
|
Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\test_poisson.exe"
|
|
Running 1 test case...
|
|
mean(mypoisson, 4.) == 4.0000000000000000
|
|
mean(mypoisson, 0.) == 4.0000000000000000
|
|
cdf(mypoisson, 2.) == 0.23810330555354431
|
|
pdf(mypoisson, 2.) == 0.14652511110987343
|
|
*** No errors detected
|
|
|
|
*/
|