• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright John Maddock 2006.
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 #include <pch_light.hpp>
7 #include "test_legendre.hpp"
8 
9 //
10 // DESCRIPTION:
11 // ~~~~~~~~~~~~
12 //
13 // This file tests the legendre polynomials.
14 // There are two sets of tests, spot
15 // tests which compare our results with selected values computed
16 // using the online special function calculator at
17 // functions.wolfram.com, while the bulk of the accuracy tests
18 // use values generated with NTL::RR at 1000-bit precision
19 // and our generic versions of these functions.
20 //
21 // Note that when this file is first run on a new platform many of
22 // these tests will fail: the default accuracy is 1 epsilon which
23 // is too tight for most platforms.  In this situation you will
24 // need to cast a human eye over the error rates reported and make
25 // a judgement as to whether they are acceptable.  Either way please
26 // report the results to the Boost mailing list.  Acceptable rates of
27 // error are marked up below as a series of regular expressions that
28 // identify the compiler/stdlib/platform/data-type/test-data/test-function
29 // along with the maximum expected peek and RMS mean errors for that
30 // test.
31 //
32 
expected_results()33 void expected_results()
34 {
35    //
36    // Define the max and mean errors expected for
37    // various compilers and platforms.
38    //
39    const char* largest_type;
40 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
41    if(boost::math::policies::digits<double, boost::math::policies::policy<> >() == boost::math::policies::digits<long double, boost::math::policies::policy<> >())
42    {
43       largest_type = "(long\\s+)?double";
44    }
45    else
46    {
47       largest_type = "long double";
48    }
49 #else
50    largest_type = "(long\\s+)?double";
51 #endif
52    //
53    // Linux:
54    //
55    if((std::numeric_limits<long double>::digits <= 64)
56       && (std::numeric_limits<long double>::digits != std::numeric_limits<double>::digits))
57    {
58 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
59       add_expected_result(
60          ".*",                          // compiler
61          ".*",                          // stdlib
62          ".*",                          // platform
63          "double",                      // test type(s)
64          ".*",                          // test data group
65          ".*", 10, 5);                  // test function
66 #endif
67    }
68    if(std::numeric_limits<long double>::digits == 64)
69    {
70       add_expected_result(
71          ".*",                          // compiler
72          ".*",                          // stdlib
73          ".*",                          // platform
74          largest_type,                  // test type(s)
75          "Legendre Polynomials.*Large.*",      // test data group
76          "legendre_p", 1000, 200);  // test function
77       add_expected_result(
78          "Intel.*",                          // compiler
79          ".*",                          // stdlib
80          ".*",                          // platform
81          largest_type,                  // test type(s)
82          "Legendre Polynomials.*Large.*",      // test data group
83          "legendre_q", 10000, 1000);  // test function
84       add_expected_result(
85          ".*",                          // compiler
86          ".*",                          // stdlib
87          ".*",                          // platform
88          largest_type,                  // test type(s)
89          "Legendre Polynomials.*Large.*",      // test data group
90          "legendre_q", 7000, 1000);  // test function
91       add_expected_result(
92          ".*",                          // compiler
93          ".*",                          // stdlib
94          ".*",                          // platform
95          "real_concept",                  // test type(s)
96          "Legendre Polynomials.*Large.*",      // test data group
97          "legendre_p", 1000, 200);  // test function
98       add_expected_result(
99          ".*",                          // compiler
100          ".*",                          // stdlib
101          ".*",                          // platform
102          "real_concept",                  // test type(s)
103          "Legendre Polynomials.*Large.*",      // test data group
104          "legendre_q", 7000, 1000);  // test function
105    }
106    //
107    // Catch all cases come last:
108    //
109    add_expected_result(
110       ".*",                          // compiler
111       ".*",                          // stdlib
112       ".*",                          // platform
113       largest_type,                  // test type(s)
114       "Legendre Polynomials.*Large.*",      // test data group
115       "legendre_p", 500, 200);  // test function
116    add_expected_result(
117       ".*",                          // compiler
118       ".*",                          // stdlib
119       ".*",                          // platform
120       largest_type,                  // test type(s)
121       "Legendre Polynomials.*Large.*",      // test data group
122       "legendre_q", 5400, 500);  // test function
123    add_expected_result(
124       ".*",                          // compiler
125       ".*",                          // stdlib
126       ".*",                          // platform
127       largest_type,                  // test type(s)
128       "Legendre Polynomials.*",      // test data group
129       "legendre_p", 300, 80);  // test function
130    add_expected_result(
131       ".*",                          // compiler
132       ".*",                          // stdlib
133       ".*",                          // platform
134       largest_type,                  // test type(s)
135       "Legendre Polynomials.*",      // test data group
136       "legendre_q", 100, 50);  // test function
137    add_expected_result(
138       "Intel.*",                          // compiler
139       ".*",                          // stdlib
140       ".*",                          // platform
141       largest_type,                  // test type(s)
142       "Associated Legendre Polynomials.*",      // test data group
143       ".*", 300, 20);  // test function
144    add_expected_result(
145       ".*",                          // compiler
146       ".*",                          // stdlib
147       ".*",                          // platform
148       largest_type,                  // test type(s)
149       "Associated Legendre Polynomials.*",      // test data group
150       ".*", 200, 20);  // test function
151 
152    add_expected_result(
153       ".*",                          // compiler
154       ".*",                          // stdlib
155       ".*",                          // platform
156       "real_concept",                  // test type(s)
157       "Legendre Polynomials.*Large.*",      // test data group
158       "legendre_p", 500, 200);  // test function
159    add_expected_result(
160       ".*",                          // compiler
161       ".*",                          // stdlib
162       ".*",                          // platform
163       "real_concept",                  // test type(s)
164       "Legendre Polynomials.*Large.*",      // test data group
165       "legendre_q", 5400, 500);  // test function
166    add_expected_result(
167       ".*",                          // compiler
168       ".*",                          // stdlib
169       ".*",                          // platform
170       "real_concept",                  // test type(s)
171       "Legendre Polynomials.*",      // test data group
172       "legendre_p", 300, 80);  // test function
173    add_expected_result(
174       ".*",                          // compiler
175       ".*",                          // stdlib
176       ".*",                          // platform
177       "real_concept",                  // test type(s)
178       "Legendre Polynomials.*",      // test data group
179       "legendre_q", 100, 50);  // test function
180    add_expected_result(
181       ".*",                          // compiler
182       ".*",                          // stdlib
183       ".*",                          // platform
184       "real_concept",                  // test type(s)
185       "Associated Legendre Polynomials.*",      // test data group
186       ".*", 200, 20);  // test function
187    //
188    // Finish off by printing out the compiler/stdlib/platform names,
189    // we do this to make it easier to mark up expected error rates.
190    //
191    std::cout << "Tests run with " << BOOST_COMPILER << ", "
192       << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl;
193 }
194 
195 
BOOST_AUTO_TEST_CASE(test_main)196 BOOST_AUTO_TEST_CASE( test_main )
197 {
198    BOOST_MATH_CONTROL_FP;
199    test_spots(0.0F, "float");
200    test_spots(0.0, "double");
201 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
202    test_spots(0.0L, "long double");
203    test_spots(boost::math::concepts::real_concept(0.1), "real_concept");
204 #endif
205 
206    expected_results();
207 
208    test_legendre_p(0.1F, "float");
209    test_legendre_p(0.1, "double");
210 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
211    test_legendre_p(0.1L, "long double");
212 #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
213    test_legendre_p(boost::math::concepts::real_concept(0.1), "real_concept");
214 #endif
215 #else
216    std::cout << "<note>The long double tests have been disabled on this platform "
217       "either because the long double overloads of the usual math functions are "
218       "not available at all, or because they are too inaccurate for these tests "
219       "to pass.</note>" << std::endl;
220 #endif
221 
222    test_legendre_p_prime<float>();
223    test_legendre_p_prime<double>();
224    test_legendre_p_prime<long double>();
225 
226    int ulp_distance = test_legendre_p_zeros_double_ulp(1, 100);
227    BOOST_CHECK(ulp_distance <= 2);
228    test_legendre_p_zeros<float>();
229    test_legendre_p_zeros<double>();
230    test_legendre_p_zeros<long double>();
231 }
232