mirror of
https://github.com/boostorg/math.git
synced 2026-01-28 07:22:12 +00:00
418 lines
13 KiB
C++
418 lines
13 KiB
C++
// Copyright Thijs van den Berg 2007.
|
|
/*
|
|
|
|
This module tests the Laplace distribution.
|
|
|
|
Test 1: test_pdf_cdf_ocatave()
|
|
Compare pdf, cdf agains results obtained from GNU Octave.
|
|
|
|
Test 2: test_cdf_quantile_symmetry()
|
|
Checks if quantile is the inverse of cdf by testing
|
|
quantile(cdf(x)) == x
|
|
|
|
Test 3: test_hazard_pdf_cdf_symmetry()
|
|
Checks the relation between hazard, pdf and cdf.
|
|
hazard = pdf/(1-cdf)
|
|
|
|
|
|
Test 4: test_location_scale_symmetry()
|
|
Checks the pdf, cdf invariant for translation and scaling invariant
|
|
cdf(x,location,scale) = cdf( (x-location)/scale, 0, 1)
|
|
scale * pdf(x,location,scale) = pdf( (x-location)/scale, 0, 1)
|
|
|
|
Test 5: test_mmm_moments()
|
|
Tests...
|
|
mean == location
|
|
mode == location
|
|
median == location
|
|
|
|
standard_deviation = sqrt(2)*scale
|
|
skewness == 0
|
|
kurtoris == 6
|
|
excess kurtoris == 3
|
|
|
|
Test 6: test_complemented()
|
|
Test the cdf an quantile complemented function
|
|
cdf(L,x) == cdf(complement(l,-x))
|
|
quantile(L,p) == quantile(complement(l,1-p))
|
|
|
|
Test 7: test_bad_dist_parameters()
|
|
Test invalid dustribution construction.
|
|
|
|
Test 8: test_extreme_function_arguments()
|
|
Test x = +/- inf. for cdf(), pdf()
|
|
Test p ={0,1} for quantile()
|
|
*/
|
|
|
|
|
|
#define BOOST_TEST_MAIN
|
|
#include <boost/test/unit_test.hpp>
|
|
#include <boost/math/constants/constants.hpp>
|
|
#include <boost/math/distributions/laplace.hpp>
|
|
using boost::math::laplace_distribution;
|
|
|
|
|
|
/*
|
|
#include <iostream>
|
|
using std::cout;
|
|
using std::endl;
|
|
using std::setprecision;
|
|
|
|
#include <limits>
|
|
using std::numeric_limits;
|
|
*/
|
|
|
|
/*
|
|
This function test various values of the standard Laplace distribution pdf,cdf
|
|
against values generated by GNU Octave
|
|
The test code is generated woth the following Octave script:
|
|
|
|
f = fopen('octave_boost_laplace.cpp', 'w');
|
|
|
|
for x = [real(-2.0), real(-1.0), real(-0.5), real(0.0), real(0.5), real(1.0), real(2.0)]
|
|
|
|
# pdf tests
|
|
# -----------------------
|
|
fdisp(f, " BOOST_CHECK_CLOSE(" ),;
|
|
fdisp(f, (sprintf (" pdf(laplace_distribution<RealType>(), static_cast<RealType>(%16.14fL)),", x)));
|
|
fdisp(f, (sprintf (" static_cast<RealType>(%16.14fL),", laplace_pdf(x) )) );
|
|
fdisp(f, " tolerance);" );
|
|
fdisp(f, "" );
|
|
|
|
# cdf tests
|
|
# -----------------------
|
|
fdisp(f, " BOOST_CHECK_CLOSE(" );
|
|
fdisp(f, (sprintf (" cdf(laplace_distribution<RealType>(), static_cast<RealType>(%16.14fL)),", x)));
|
|
fdisp(f, (sprintf (" static_cast<RealType>(%16.14fL),", laplace_cdf(x) )) );
|
|
fdisp(f, " tolerance);" );
|
|
fdisp(f, "" );
|
|
|
|
endfor
|
|
|
|
fclose(f);
|
|
*/
|
|
template <class RealType>
|
|
void test_pdf_cdf_ocatave()
|
|
{
|
|
RealType tolerance(1e-10f);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(-2.00000000000000L)),
|
|
static_cast<RealType>(0.06766764161831L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(-2.00000000000000L)),
|
|
static_cast<RealType>(0.06766764161831L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(-1.00000000000000L)),
|
|
static_cast<RealType>(0.18393972058572L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(-1.00000000000000L)),
|
|
static_cast<RealType>(0.18393972058572L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(-0.50000000000000L)),
|
|
static_cast<RealType>(0.30326532985632L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(-0.50000000000000L)),
|
|
static_cast<RealType>(0.30326532985632L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(0.00000000000000L)),
|
|
static_cast<RealType>(0.50000000000000L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(0.00000000000000L)),
|
|
static_cast<RealType>(0.50000000000000L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(0.50000000000000L)),
|
|
static_cast<RealType>(0.30326532985632L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(0.50000000000000L)),
|
|
static_cast<RealType>(0.69673467014368L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(1.00000000000000L)),
|
|
static_cast<RealType>(0.18393972058572L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(1.00000000000000L)),
|
|
static_cast<RealType>(0.81606027941428L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(), static_cast<RealType>(2.00000000000000L)),
|
|
static_cast<RealType>(0.06766764161831L),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(), static_cast<RealType>(2.00000000000000L)),
|
|
static_cast<RealType>(0.93233235838169L),
|
|
tolerance);
|
|
}
|
|
|
|
template <class RealType>
|
|
void test_cdf_quantile_symmetry()
|
|
{
|
|
RealType tolerance(boost::math::tools::epsilon<RealType>() * 500); // 5 eps as a percentage
|
|
|
|
const float xtest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
|
|
for (int i=0; i<7; ++i)
|
|
{
|
|
RealType x( static_cast<RealType>(xtest[i]) );
|
|
RealType x2( quantile(laplace_distribution<RealType>(), cdf(laplace_distribution<RealType>(), x)) );
|
|
BOOST_CHECK_CLOSE( x, x2, tolerance);
|
|
}
|
|
}
|
|
|
|
|
|
template <class RealType>
|
|
void test_hazard_pdf_cdf_symmetry()
|
|
{
|
|
RealType tolerance(boost::math::tools::epsilon<RealType>() * 500); // 5 eps as a percentage
|
|
|
|
const float xtest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
|
|
for (int xi=0; xi<7; ++xi)
|
|
{
|
|
RealType x( static_cast<RealType>(xtest[xi]) );
|
|
RealType p( pdf(laplace_distribution<RealType>(), x) );
|
|
RealType c( cdf(laplace_distribution<RealType>(), x) );
|
|
RealType h1( p/(static_cast<RealType>(1.0) - c) );
|
|
RealType h2( hazard(laplace_distribution<RealType>(), x) );
|
|
BOOST_CHECK_CLOSE( h1, h2, tolerance);
|
|
}
|
|
}
|
|
|
|
template <class RealType>
|
|
void test_location_scale_symmetry()
|
|
{
|
|
RealType tolerance(boost::math::tools::epsilon<RealType>() * 500); // 5 eps as a percentage
|
|
|
|
const float xtest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
const float ltest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
const float stest[3] = { 0.5, 1.0, 2.0 };
|
|
|
|
for (int xi=0; xi<7; ++xi)
|
|
for (int li=0; li<7; ++li)
|
|
for (int si=0; si<3; ++si)
|
|
{
|
|
RealType x( static_cast<RealType>(xtest[xi]) );
|
|
RealType l( static_cast<RealType>(ltest[li]) );
|
|
RealType s( static_cast<RealType>(stest[si]) );
|
|
RealType x0( (x-l)/s );
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
pdf(laplace_distribution<RealType>(l,s), x) * s,
|
|
pdf(laplace_distribution<RealType>(), x0),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(laplace_distribution<RealType>(l,s), x),
|
|
cdf(laplace_distribution<RealType>(), x0),
|
|
tolerance);
|
|
|
|
}
|
|
}
|
|
|
|
template <class RealType>
|
|
void test_mmm_moments()
|
|
{
|
|
RealType tolerance(boost::math::tools::epsilon<RealType>() * 500); // 5 eps as a percentage
|
|
|
|
const float xtest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
const float ltest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
const float stest[3] = { 0.5, 1.0, 2.0 };
|
|
|
|
for (int xi=0; xi<7; ++xi)
|
|
for (int li=0; li<7; ++li)
|
|
for (int si=0; si<3; ++si)
|
|
{
|
|
RealType x( static_cast<RealType>(xtest[xi]) );
|
|
RealType l( static_cast<RealType>(ltest[li]) );
|
|
RealType s( static_cast<RealType>(stest[si]) );
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
mean( laplace_distribution<RealType>(l,s) ),
|
|
l,
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
median( laplace_distribution<RealType>(l,s) ),
|
|
l,
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
mode( laplace_distribution<RealType>(l,s) ),
|
|
l,
|
|
tolerance);
|
|
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
standard_deviation( laplace_distribution<RealType>(l,s) ),
|
|
static_cast<RealType>( s * boost::math::constants::root_two<RealType>() ),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
skewness( laplace_distribution<RealType>(l,s) ),
|
|
static_cast<RealType>(0),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
kurtosis( laplace_distribution<RealType>(l,s) ),
|
|
static_cast<RealType>(6),
|
|
tolerance);
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
kurtosis_excess( laplace_distribution<RealType>(l,s) ),
|
|
static_cast<RealType>(3),
|
|
tolerance);
|
|
}
|
|
}
|
|
|
|
|
|
template <class RealType>
|
|
void test_complemented()
|
|
{
|
|
RealType tolerance(boost::math::tools::epsilon<RealType>() * 500); // 5 eps as a percentage
|
|
|
|
const float xtest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
const float ptest[7] = { 0.125, 0.25, 0.5, 0.75, 0.875 };
|
|
const float ltest[7] = { -2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0 };
|
|
const float stest[3] = { 0.5, 1.0, 2.0 };
|
|
|
|
for (int li=0; li<7; ++li)
|
|
for (int si=0; si<3; ++si)
|
|
{
|
|
RealType l( static_cast<RealType>(ltest[li]) );
|
|
RealType s( static_cast<RealType>(stest[si]) );
|
|
|
|
for (int xi=0; xi<7; ++xi)
|
|
{
|
|
RealType x( static_cast<RealType>(xtest[xi]) );
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
cdf(complement(laplace_distribution<RealType>(l,s), -x)),
|
|
cdf(laplace_distribution<RealType>(l,s), x),
|
|
tolerance);
|
|
}
|
|
|
|
for (int pi=0; pi<5; ++pi)
|
|
{
|
|
RealType p( static_cast<RealType>(ptest[pi]) );
|
|
|
|
BOOST_CHECK_CLOSE(
|
|
quantile(complement(laplace_distribution<RealType>(l,s), 1-p )),
|
|
quantile(laplace_distribution<RealType>(l,s), p),
|
|
tolerance);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template <class RealType>
|
|
void test_bad_dist_parameters()
|
|
{
|
|
BOOST_CHECK_THROW(boost::math::laplace_distribution<RealType> lbad1(0, 0), std::domain_error);
|
|
BOOST_CHECK_THROW(boost::math::laplace_distribution<RealType> lbad2(0, -1), std::domain_error);
|
|
}
|
|
|
|
|
|
|
|
template <class RealType>
|
|
void test_extreme_function_arguments()
|
|
{
|
|
boost::math::laplace_distribution<RealType> L1(0, 1);
|
|
boost::math::laplace_distribution<RealType> L2(1, 2);
|
|
|
|
// check pdf at x = +/- infinity
|
|
BOOST_CHECK_THROW(pdf(L1, +std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
BOOST_CHECK_THROW(pdf(L1, -std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
BOOST_CHECK_THROW(pdf(L2, +std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
BOOST_CHECK_THROW(pdf(L2, -std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
|
|
// check cdf at x = +/- infinity
|
|
BOOST_CHECK_THROW(cdf(L1, +std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
BOOST_CHECK_THROW(cdf(L1, -std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
BOOST_CHECK_THROW(cdf(L2, +std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
BOOST_CHECK_THROW(cdf(L2, -std::numeric_limits<RealType>::infinity()), std::domain_error);
|
|
|
|
// check quantile at p = 0,1
|
|
BOOST_CHECK_EQUAL( quantile(L1, 0), -std::numeric_limits<RealType>::infinity() );
|
|
BOOST_CHECK_EQUAL( quantile(L1, 1), +std::numeric_limits<RealType>::infinity() );
|
|
BOOST_CHECK_EQUAL( quantile(L2, 0), -std::numeric_limits<RealType>::infinity() );
|
|
BOOST_CHECK_EQUAL( quantile(L2, 1), +std::numeric_limits<RealType>::infinity() );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE( vs_GNU_Octave )
|
|
{
|
|
test_pdf_cdf_ocatave<float>();
|
|
test_pdf_cdf_ocatave<double>();
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE( cdf_quantile_symmetry )
|
|
{
|
|
test_cdf_quantile_symmetry<float>();
|
|
test_cdf_quantile_symmetry<double>();
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE( hazard_pdf_cdf_symmetry )
|
|
{
|
|
test_hazard_pdf_cdf_symmetry<float>();
|
|
test_hazard_pdf_cdf_symmetry<double>();
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE( location_scale_symmetry )
|
|
{
|
|
test_location_scale_symmetry<float>();
|
|
test_location_scale_symmetry<double>();
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE( mmm_moments )
|
|
{
|
|
test_mmm_moments<float>();
|
|
test_mmm_moments<double>();
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( t_complemented )
|
|
{
|
|
test_complemented<float>();
|
|
test_complemented<double>();
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( bad_dist_parameters )
|
|
{
|
|
test_bad_dist_parameters<float>();
|
|
test_bad_dist_parameters<double>();
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( extreme_function_arguments )
|
|
{
|
|
test_extreme_function_arguments<float>();
|
|
test_extreme_function_arguments<double>();
|
|
} |