]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | /* |
2 | * Copyright Evan Miller, 2020 | |
3 | * Use, modification and distribution are subject to the | |
4 | * Boost Software License, Version 1.0. (See accompanying file | |
5 | * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | */ | |
20effc67 TL |
7 | |
8 | #include <pch_light.hpp> | |
9 | #include <boost/math/concepts/real_concept.hpp> | |
10 | #include "test_jacobi_theta.hpp" | |
11 | ||
12 | // Test file for the Jacobi Theta functions, a.k.a the four horsemen of the | |
13 | // Jacobi elliptic integrals. At the moment only Wolfrma Alpha spot checks are | |
14 | // used. We should generate extra-precise numbers with NTL::RR or some such. | |
15 | ||
16 | void expected_results() | |
17 | { | |
18 | // | |
19 | // Define the max and mean errors expected for | |
20 | // various compilers and platforms. | |
21 | // | |
22 | // | |
23 | add_expected_result( | |
24 | ".*", // compiler | |
25 | ".*", // stdlib | |
26 | ".*", // platform | |
27 | ".*", // test type(s) | |
28 | ".*Small Tau.*", // test data group | |
29 | ".*", 1000, 200); // test function | |
30 | ||
31 | add_expected_result( | |
32 | ".*", // compiler | |
33 | ".*", // stdlib | |
34 | ".*", // platform | |
35 | ".*", // test type(s) | |
36 | ".*Wolfram Alpha.*", // test data group | |
37 | ".*", 60, 15); // test function | |
38 | ||
39 | // Catch all cases come last: | |
40 | // | |
41 | add_expected_result( | |
42 | ".*", // compiler | |
43 | ".*", // stdlib | |
44 | ".*", // platform | |
45 | ".*", // test type(s) | |
46 | ".*", // test data group | |
47 | ".*", 20, 5); // test function | |
48 | // | |
49 | // Finish off by printing out the compiler/stdlib/platform names, | |
50 | // we do this to make it easier to mark up expected error rates. | |
51 | // | |
52 | std::cout << "Tests run with " << BOOST_COMPILER << ", " | |
53 | << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl; | |
54 | } | |
55 | ||
56 | BOOST_AUTO_TEST_CASE( test_main ) | |
57 | { | |
58 | expected_results(); | |
59 | BOOST_MATH_CONTROL_FP; | |
60 | BOOST_MATH_STD_USING | |
61 | ||
62 | using namespace boost::math; | |
63 | ||
64 | BOOST_CHECK_THROW(jacobi_theta1(0.0, 0.0), std::domain_error); | |
65 | BOOST_CHECK_THROW(jacobi_theta1(0.0, 1.0), std::domain_error); | |
66 | ||
67 | BOOST_CHECK_THROW(jacobi_theta2(0.0, 0.0), std::domain_error); | |
68 | BOOST_CHECK_THROW(jacobi_theta2(0.0, 1.0), std::domain_error); | |
69 | ||
70 | BOOST_CHECK_THROW(jacobi_theta3(0.0, 0.0), std::domain_error); | |
71 | BOOST_CHECK_THROW(jacobi_theta3(0.0, 1.0), std::domain_error); | |
72 | ||
73 | BOOST_CHECK_THROW(jacobi_theta4(0.0, 0.0), std::domain_error); | |
74 | BOOST_CHECK_THROW(jacobi_theta4(0.0, 1.0), std::domain_error); | |
75 | ||
76 | BOOST_CHECK_THROW(jacobi_theta1tau(0.0, 0.0), std::domain_error); | |
77 | BOOST_CHECK_THROW(jacobi_theta1tau(0.0, -1.0), std::domain_error); | |
78 | ||
79 | BOOST_CHECK_THROW(jacobi_theta2tau(0.0, 0.0), std::domain_error); | |
80 | BOOST_CHECK_THROW(jacobi_theta2tau(0.0, -1.0), std::domain_error); | |
81 | ||
82 | BOOST_CHECK_THROW(jacobi_theta3tau(0.0, 0.0), std::domain_error); | |
83 | BOOST_CHECK_THROW(jacobi_theta3tau(0.0, -1.0), std::domain_error); | |
84 | ||
85 | BOOST_CHECK_THROW(jacobi_theta4tau(0.0, 0.0), std::domain_error); | |
86 | BOOST_CHECK_THROW(jacobi_theta4tau(0.0, -1.0), std::domain_error); | |
87 | ||
88 | double eps = std::numeric_limits<double>::epsilon(); | |
89 | for (double q=0.0078125; q<1.0; q += 0.0078125) { // = 1/128 | |
90 | for (double z=-8.0; z<=8.0; z += 0.125) { | |
91 | test_periodicity(z, q, 100 * eps); | |
92 | test_argument_translation(z, q, 100 * eps); | |
93 | test_sums_of_squares(z, q, 100 * eps); | |
94 | // The addition formula is complicated, cut it some extra slack | |
95 | test_addition_formulas(z, constants::ln_two<double>(), q, sqrt(sqrt(eps))); | |
96 | test_duplication_formula(z, q, 100 * eps); | |
97 | test_transformations_of_nome(z, q, 100 * eps); | |
98 | test_watsons_identities(z, 0.5, q, 101 * eps); | |
99 | test_landen_transformations(z, -log(q)/constants::pi<double>(), sqrt(eps)); | |
100 | test_elliptic_functions(z, q, 5 * sqrt(eps)); | |
101 | } | |
102 | test_elliptic_integrals(q, 10 * eps); | |
103 | } | |
104 | ||
105 | test_special_values(eps); | |
106 | ||
107 | for (double s=0.125; s<3.0; s+=0.125) { | |
108 | test_mellin_transforms(2.0 + s, eps, 3 * eps); | |
109 | test_laplace_transforms(s, eps, 4 * eps); | |
110 | } | |
111 | ||
112 | test_spots(0.0F, "float"); | |
113 | test_spots(0.0, "double"); | |
114 | #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | |
115 | test_spots(0.0L, "long double"); | |
116 | #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS | |
117 | test_spots(concepts::real_concept(0), "real_concept"); | |
118 | #endif | |
119 | #else | |
120 | std::cout << "<note>The long double tests have been disabled on this platform " | |
121 | "either because the long double overloads of the usual math functions are " | |
122 | "not available at all, or because they are too inaccurate for these tests " | |
123 | "to pass.</note>" << std::endl; | |
124 | #endif | |
125 | } |