]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright John Maddock 2015. |
2 | // Use, modification and distribution are subject to the | |
3 | // Boost Software License, Version 1.0. (See accompanying file | |
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #ifdef _MSC_VER | |
7 | # pragma warning(disable : 4756) // overflow in constant arithmetic | |
8 | // Constants are too big for float case, but this doesn't matter for test. | |
9 | #endif | |
10 | ||
11 | #include <boost/math/concepts/real_concept.hpp> | |
12 | #define BOOST_TEST_MAIN | |
13 | #include <boost/test/unit_test.hpp> | |
92f5a8d4 | 14 | #include <boost/test/tools/floating_point_comparison.hpp> |
7c673cae FG |
15 | #include <boost/math/special_functions/math_fwd.hpp> |
16 | #include <boost/array.hpp> | |
17 | #include "functor.hpp" | |
18 | ||
19 | #include "handle_test_result.hpp" | |
20 | #include "table_type.hpp" | |
21 | ||
22 | #ifndef SC_ | |
23 | #define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L)) | |
24 | #endif | |
25 | ||
26 | template <class Real, typename T> | |
27 | void do_test_ellint_d2(const T& data, const char* type_name, const char* test) | |
28 | { | |
29 | #if !(defined(ERROR_REPORTING_MODE) && !defined(ELLINT_D2_FUNCTION_TO_TEST)) | |
30 | typedef Real value_type; | |
31 | ||
32 | std::cout << "Testing: " << test << std::endl; | |
33 | ||
34 | #ifdef ELLINT_D2_FUNCTION_TO_TEST | |
35 | value_type(*fp2)(value_type, value_type) = ELLINT_D2_FUNCTION_TO_TEST; | |
36 | #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS) | |
37 | value_type (*fp2)(value_type, value_type) = boost::math::ellint_d<value_type, value_type>; | |
38 | #else | |
39 | value_type (*fp2)(value_type, value_type) = boost::math::ellint_d; | |
40 | #endif | |
41 | boost::math::tools::test_result<value_type> result; | |
42 | ||
43 | result = boost::math::tools::test_hetero<Real>( | |
44 | data, | |
45 | bind_func<Real>(fp2, 1, 0), | |
46 | extract_result<Real>(2)); | |
47 | handle_test_result(result, data[result.worst()], result.worst(), | |
48 | type_name, "ellint_d", test); | |
49 | ||
50 | std::cout << std::endl; | |
51 | #endif | |
52 | } | |
53 | ||
54 | template <class Real, typename T> | |
55 | void do_test_ellint_d1(T& data, const char* type_name, const char* test) | |
56 | { | |
57 | #if !(defined(ERROR_REPORTING_MODE) && !defined(ELLINT_D1_FUNCTION_TO_TEST)) | |
58 | typedef Real value_type; | |
59 | boost::math::tools::test_result<value_type> result; | |
60 | ||
61 | std::cout << "Testing: " << test << std::endl; | |
62 | ||
63 | #ifdef ELLINT_D1_FUNCTION_TO_TEST | |
64 | value_type(*fp1)(value_type) = ELLINT_D1_FUNCTION_TO_TEST; | |
65 | #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS) | |
66 | value_type (*fp1)(value_type) = boost::math::ellint_d<value_type>; | |
67 | #else | |
68 | value_type (*fp1)(value_type) = boost::math::ellint_d; | |
69 | #endif | |
70 | result = boost::math::tools::test_hetero<Real>( | |
71 | data, | |
72 | bind_func<Real>(fp1, 0), | |
73 | extract_result<Real>(1)); | |
74 | handle_test_result(result, data[result.worst()], result.worst(), | |
75 | type_name, "ellint_d (complete)", test); | |
76 | ||
77 | std::cout << std::endl; | |
78 | #endif | |
79 | } | |
80 | ||
81 | template <typename T> | |
82 | void test_spots(T, const char* type_name) | |
83 | { | |
84 | BOOST_MATH_STD_USING | |
85 | // Function values calculated on http://functions.wolfram.com/ | |
86 | // Note that Mathematica's EllipticE accepts k^2 as the second parameter. | |
92f5a8d4 | 87 | static const boost::array<boost::array<T, 3>, 11> data1 = {{ |
7c673cae FG |
88 | { { SC_(0.5), SC_(0.5), SC_(0.040348098248931543984282958654503585) } }, |
89 | {{ SC_(0), SC_(0.5), SC_(0) }}, | |
90 | { { SC_(1), SC_(0.5), SC_(0.28991866293419922467977188008516755) } }, | |
91 | { { SC_(1), T(1), SC_(0.38472018607562056416055864584160775) } }, | |
92 | { { SC_(-1), T(1), SC_(-0.38472018607562056416055864584160775) } }, | |
93 | { { SC_(-1), T(0.5), SC_(-0.28991866293419922467977188008516755) } }, | |
94 | { { SC_(-10), T(0.5), SC_(-5.2996914501577855803123384771117708) } }, | |
95 | { { SC_(10), SC_(-0.5), SC_(5.2996914501577855803123384771117708) } }, | |
92f5a8d4 | 96 | { { SC_(0.125), SC_(1.5), SC_(0.000655956467603362564458676111698495009248974444516843) } }, |
7c673cae FG |
97 | }}; |
98 | ||
99 | do_test_ellint_d2<T>(data1, type_name, "Elliptic Integral E: Mathworld Data"); | |
100 | ||
101 | #include "ellint_d2_data.ipp" | |
102 | ||
103 | do_test_ellint_d2<T>(ellint_d2_data, type_name, "Elliptic Integral D: Random Data"); | |
104 | ||
105 | // Function values calculated on http://functions.wolfram.com/ | |
106 | // Note that Mathematica's EllipticE accepts k^2 as the second parameter. | |
107 | static const boost::array<boost::array<T, 2>, 3> data2 = {{ | |
108 | { { SC_(0.5), SC_(0.87315258189267554964563356323264341) } }, | |
109 | { { SC_(1.0) / 1024, SC_(0.78539844427788694671464428063604776) } }, | |
110 | { { boost::math::tools::root_epsilon<T>(), SC_(0.78539816339744830961566084581987572) } } | |
111 | }}; | |
112 | ||
113 | do_test_ellint_d1<T>(data2, type_name, "Elliptic Integral E: Mathworld Data"); | |
114 | ||
115 | #include "ellint_d_data.ipp" | |
116 | ||
117 | do_test_ellint_d1<T>(ellint_d_data, type_name, "Elliptic Integral D: Random Data"); | |
118 | ||
119 | BOOST_MATH_CHECK_THROW(boost::math::ellint_d(T(1)), std::domain_error); | |
120 | BOOST_MATH_CHECK_THROW(boost::math::ellint_d(T(-1)), std::domain_error); | |
121 | BOOST_MATH_CHECK_THROW(boost::math::ellint_d(T(1.5)), std::domain_error); | |
122 | BOOST_MATH_CHECK_THROW(boost::math::ellint_d(T(-1.5)), std::domain_error); | |
123 | } | |
124 |