2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-19 04:22:09 +00:00

1F1: Exclude values very close to 1 from logarithmic testing for now.

Add tests for log and regularized cases.
Log cases still have many failures and are not yet tested.
This commit is contained in:
jzmaddock
2019-05-13 18:07:47 +01:00
parent d81eb7ea31
commit dc7ecc0581
6 changed files with 5851 additions and 2 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

197
test/test_1F1_log.cpp Normal file
View File

@@ -0,0 +1,197 @@
// (C) 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)
#include "test_1F1_log.hpp"
#include <boost/multiprecision/cpp_bin_float.hpp>
void expected_results()
{
//
// Define the max and mean errors expected for
// various compilers and platforms.
//
const char* largest_type;
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
if(boost::math::policies::digits<double, boost::math::policies::policy<> >() == boost::math::policies::digits<long double, boost::math::policies::policy<> >())
{
largest_type = "(long\\s+)?double|real_concept|cpp_bin_float_quad|dec_40|cpp_bin_float_double_extended";
}
else
{
largest_type = "long double|real_concept|cpp_bin_float_quad|dec_40|cpp_bin_float_double_extended";
}
#else
largest_type = "(long\\s+)?double";
#endif
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"cpp_bin_float_quad|cpp_bin_float_double_extended", // test type(s)
"Integer a values", // test data group
".*", 25000, 800); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"cpp_bin_float_quad|cpp_bin_float_double_extended", // test type(s)
"Large.*", // test data group
".*", 500000, 20000); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"cpp_bin_float_quad|cpp_bin_float_double_extended", // test type(s)
"Small.*", // test data group
".*", 2000, 200); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Integer a values", // test data group
".*", 12000, 800); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Large.*", // test data group
".*", 20000000L, 600000L); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Small.*", // test data group
".*", 1000, 300); // test function
#if (LDBL_MANT_DIG < DBL_MANT_DIG * 2) && (LDBL_MANT_DIG != DBL_MANT_DIG)
//
// long double has only a little extra precision and errors may creep
// into the double results:
//
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Integer a values", // test data group
".*", 5, 3); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Small.*", // test data group
".*", 5, 3); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Large.*", // test data group
".*", 40, 20); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Bug.*", // test data group
".*", 300, 50); // test function
#endif
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Integer a values", // test data group
".*", 16000, 600); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Small.*", // test data group
".*", 2000, 200); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Large.*", // test data group
".*", 400000, 8000); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Bug cases.*", // test data group
".*", 2200000, 400000); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Bug cases.*", // test data group
".*", 1500000, 400000); // test function
//
// Finish off by printing out the compiler/stdlib/platform names,
// we do this to make it easier to mark up expected error rates.
//
std::cout << "Tests run with " << BOOST_COMPILER << ", "
<< BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl;
}
BOOST_AUTO_TEST_CASE( test_main )
{
expected_results();
BOOST_MATH_CONTROL_FP;
#if !defined(TEST) || (TEST == 1)
test_hypergeometric_mellin_transform<double>();
test_hypergeometric_laplace_transform<double>();
#endif
#ifndef BOOST_MATH_BUGGY_LARGE_FLOAT_CONSTANTS
#if !defined(TEST) || (TEST == 2)
test_spots(0.0F, "float");
#endif
#endif
#if !defined(TEST) || (TEST == 3)
test_spots(0.0, "double");
#endif
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
#if (!defined(TEST) || (TEST == 4)) && (DBL_MAX_EXP != LDBL_MAX_EXP)
test_spots(0.0L, "long double");
#endif
#ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
#if !defined(TEST) || (TEST == 5)
test_spots(boost::math::concepts::real_concept(0.1), "real_concept");
#endif
#endif
#endif
#if (!defined(TEST) || (TEST == 4)) && (DBL_MAX_EXP == LDBL_MAX_EXP)
test_spots(boost::multiprecision::cpp_bin_float_double_extended(), "cpp_bin_float_double_extended");
#endif
#if !defined(TEST) || (TEST == 6)
test_spots(boost::multiprecision::cpp_bin_float_quad(), "cpp_bin_float_quad");
#endif
#if !defined(TEST) || (TEST == 7)
typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<40> > dec_40;
test_spots(dec_40(), "dec_40");
#endif
}

77
test/test_1F1_log.hpp Normal file
View File

@@ -0,0 +1,77 @@
// Copyright John Maddock 2006.
// Copyright Paul A. Bristow 2007, 2009
// 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)
#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
#include <boost/math/concepts/real_concept.hpp>
#include <boost/math/special_functions/math_fwd.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/math/tools/stats.hpp>
#include <boost/math/tools/test.hpp>
#include <boost/math/tools/big_constant.hpp>
#include <boost/math/constants/constants.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/array.hpp>
#include "functor.hpp"
#include "handle_test_result.hpp"
#include "table_type.hpp"
#include <boost/math/special_functions/hypergeometric_1F1.hpp>
#include <boost/math/quadrature/exp_sinh.hpp>
#ifdef BOOST_MSVC
#pragma warning(disable:4127)
#endif
template <class Real, class T>
void do_test_1F1(const T& data, const char* type_name, const char* test_name)
{
typedef Real value_type;
typedef value_type(*pg)(value_type, value_type, value_type);
#if defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
pg funcp = boost::math::log_hypergeometric_1F1<value_type, value_type>;
#else
pg funcp = boost::math::log_hypergeometric_1F1;
#endif
boost::math::tools::test_result<value_type> result;
std::cout << "Testing " << test_name << " with type " << type_name
<< "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
//
// test hypergeometric_2F0 against data:
//
result = boost::math::tools::test_hetero<Real>(
data,
bind_func<Real>(funcp, 0, 1, 2),
extract_result<Real>(3));
handle_test_result(result, data[result.worst()], result.worst(), type_name, "log_hypergeometric_1F1", test_name);
std::cout << std::endl;
}
#ifndef SC_
#define SC_(x) BOOST_MATH_BIG_CONSTANT(T, 1000000, x)
#endif
template <class T>
void test_spots1(T, const char* type_name)
{
#include "hypergeometric_1f1_log_large.ipp"
do_test_1F1<T>(hypergeometric_1f1_log_large, type_name, "Large random values - log");
}
template <class T>
void test_spots(T z, const char* type_name)
{
test_spots1(z, type_name);
}

View File

@@ -0,0 +1,197 @@
// (C) 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)
#include "test_1F1_regularized.hpp"
#include <boost/multiprecision/cpp_bin_float.hpp>
void expected_results()
{
//
// Define the max and mean errors expected for
// various compilers and platforms.
//
const char* largest_type;
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
if(boost::math::policies::digits<double, boost::math::policies::policy<> >() == boost::math::policies::digits<long double, boost::math::policies::policy<> >())
{
largest_type = "(long\\s+)?double|real_concept|cpp_bin_float_quad|dec_40|cpp_bin_float_double_extended";
}
else
{
largest_type = "long double|real_concept|cpp_bin_float_quad|dec_40|cpp_bin_float_double_extended";
}
#else
largest_type = "(long\\s+)?double";
#endif
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"cpp_bin_float_quad|cpp_bin_float_double_extended", // test type(s)
"Integer a values", // test data group
".*", 25000, 800); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"cpp_bin_float_quad|cpp_bin_float_double_extended", // test type(s)
"Large.*", // test data group
".*", 500000, 20000); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"cpp_bin_float_quad|cpp_bin_float_double_extended", // test type(s)
"Small.*", // test data group
".*", 2000, 200); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Integer a values", // test data group
".*", 12000, 800); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Large.*", // test data group
".*", 20000000L, 600000L); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Small.*", // test data group
".*", 1000, 300); // test function
#if (LDBL_MANT_DIG < DBL_MANT_DIG * 2) && (LDBL_MANT_DIG != DBL_MANT_DIG)
//
// long double has only a little extra precision and errors may creep
// into the double results:
//
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Integer a values", // test data group
".*", 5, 3); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Small.*", // test data group
".*", 5, 3); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Large.*", // test data group
".*", 40, 20); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"double", // test type(s)
"Bug.*", // test data group
".*", 300, 50); // test function
#endif
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Integer a values", // test data group
".*", 16000, 600); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Small.*", // test data group
".*", 2000, 200); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Large.*", // test data group
".*", 400000, 8000); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
"dec_40", // test type(s)
"Bug cases.*", // test data group
".*", 2200000, 400000); // test function
add_expected_result(
".*", // compiler
".*", // stdlib
".*", // platform
largest_type, // test type(s)
"Bug cases.*", // test data group
".*", 1500000, 400000); // test function
//
// Finish off by printing out the compiler/stdlib/platform names,
// we do this to make it easier to mark up expected error rates.
//
std::cout << "Tests run with " << BOOST_COMPILER << ", "
<< BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl;
}
BOOST_AUTO_TEST_CASE( test_main )
{
expected_results();
BOOST_MATH_CONTROL_FP;
#if !defined(TEST) || (TEST == 1)
test_hypergeometric_mellin_transform<double>();
test_hypergeometric_laplace_transform<double>();
#endif
#ifndef BOOST_MATH_BUGGY_LARGE_FLOAT_CONSTANTS
#if !defined(TEST) || (TEST == 2)
test_spots(0.0F, "float");
#endif
#endif
#if !defined(TEST) || (TEST == 3)
test_spots(0.0, "double");
#endif
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
#if (!defined(TEST) || (TEST == 4)) && (DBL_MAX_EXP != LDBL_MAX_EXP)
test_spots(0.0L, "long double");
#endif
#ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
#if !defined(TEST) || (TEST == 5)
test_spots(boost::math::concepts::real_concept(0.1), "real_concept");
#endif
#endif
#endif
#if (!defined(TEST) || (TEST == 4)) && (DBL_MAX_EXP == LDBL_MAX_EXP)
test_spots(boost::multiprecision::cpp_bin_float_double_extended(), "cpp_bin_float_double_extended");
#endif
#if !defined(TEST) || (TEST == 6)
test_spots(boost::multiprecision::cpp_bin_float_quad(), "cpp_bin_float_quad");
#endif
#if !defined(TEST) || (TEST == 7)
typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<40> > dec_40;
test_spots(dec_40(), "dec_40");
#endif
}

View File

@@ -30,7 +30,7 @@ struct hypergeometric_1f1_gen
{
mp_t result;
try {
result = (mp_t)log(abs(boost::math::hypergeometric_pFq_precision({ mpfr_float(a1) }, { mpfr_float(mpfr_float(a2)) }, mpfr_float(z), 50, 25.0)));
result = (mp_t)log(abs(boost::math::hypergeometric_pFq_precision({ mpfr_float(a1) }, { mpfr_float(a2) }, mpfr_float(z), 70, 25.0)));
std::cout << a1 << " " << a2 << " " << z << " " << result << std::endl;
}
catch (...)
@@ -42,6 +42,11 @@ struct hypergeometric_1f1_gen
std::cout << "Rejecting over large value\n";
throw std::domain_error("");
}
if (fabs(result) < 1/1024.0)
{
std::cout << "Rejecting over small value\n";
throw std::domain_error("");
}
return result;
}
};
@@ -102,7 +107,7 @@ int main(int, char* [])
for (unsigned k = 0; k < v.size(); ++k)
{
std::cout << i << " " << j << " " << k << std::endl;
std::cout << v[i] << " " << (v[j] * 3) / 2 << " " << (v[j] * 5) / 4 << std::endl;
std::cout << v[i] << " " << (v[j] * 3) / 2 << " " << (v[k] * 5) / 4 << std::endl;
arg1 = make_single_param(v[i]);
arg2 = make_single_param(mp_t((v[j] * 3) / 2));
arg3 = make_single_param(mp_t((v[k] * 5) / 4));