File: erf_limits_test.cpp

package info (click to toggle)
scipy 1.16.0-1exp7
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 234,820 kB
  • sloc: cpp: 503,145; python: 344,611; ansic: 195,638; javascript: 89,566; fortran: 56,210; cs: 3,081; f90: 1,150; sh: 848; makefile: 785; pascal: 284; csh: 135; lisp: 134; xml: 56; perl: 51
file content (73 lines) | stat: -rw-r--r-- 2,412 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//  (C) Copyright John Maddock 2021.
//  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)

//
// This test verifies that the limits we use in the numerical approximations to erf/erc
// are indeed correct.  The values tested must of course match the values used in erf.hpp.
// See https://github.com/boostorg/math/issues/710
//

#define BOOST_TEST_MODULE erf_limits

#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/test/included/unit_test.hpp>

#include <cfloat>

BOOST_AUTO_TEST_CASE(limits_53_digits)
{
   double arg = 5.93f;

   double t = (double)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 1.0);

   arg = 5.9;
   BOOST_CHECK_LT(boost::math::erf(arg), 1.0);

   arg = 28;
   t = (double)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 0.0);

   arg = 27.2;

   BOOST_CHECK_GT(boost::math::erfc(arg), 0.0);
}

BOOST_AUTO_TEST_CASE(limits_64_digits)
{
   float arg = 6.6f;

   boost::multiprecision::cpp_bin_float_double_extended t = (boost::multiprecision::cpp_bin_float_double_extended)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 1.0);

#if (LDBL_MANT_DIG == 64) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
   arg = 6.5;
   BOOST_CHECK_LT(boost::math::erf(static_cast<long double>(arg)), 1.0L);
#endif
   arg = 110;
   t = (boost::multiprecision::cpp_bin_float_double_extended)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 0.0);

#if (LDBL_MANT_DIG == 64) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
   arg = 106.5;
   BOOST_CHECK_GT(boost::math::erfc(static_cast<long double>(arg)), 0.0L);
#endif
}

BOOST_AUTO_TEST_CASE(limits_113_digits)
{
   //
   // This limit is not actually used in the code, logged here for future reference...
   //
   float arg = 8.8f;

   boost::multiprecision::cpp_bin_float_quad t = (boost::multiprecision::cpp_bin_float_quad)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 1.0);

   arg = 110;
   t = (boost::multiprecision::cpp_bin_float_quad)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 0.0);
}