• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright Raffi Enficiaud 2019.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 
8 //[example_code
9 #define BOOST_TEST_MODULE example84
10 #include <boost/test/included/unit_test.hpp>
11 #include <random>
12 #include <cmath>
13 
14 // this function does not compute properly the polynomial root estimation
15 // in the case of a double root.
16 template <class random_generator_t>
estimate_polynomial_roots(random_generator_t & gen,std::function<double (double)> polynomial)17 std::pair<double, double> estimate_polynomial_roots(
18   random_generator_t& gen,
19   std::function<double(double)> polynomial) {
20 
21   using namespace std;
22 
23   std::uniform_real_distribution<> dis(-10, 10);
24   double x1 = dis(gen);
25   double x2 = dis(gen);
26   double fx1 = polynomial(x1);
27   double fx2 = polynomial(x2);
28 
29   BOOST_TEST_INFO_SCOPE("sample1 = " << x1);
30   BOOST_TEST_INFO_SCOPE("sample2 = " << x2);
31 
32   // from Vieta formula
33   double minus_b = x2 + x1 - (fx2 - fx1) / (x2 - x1);
34   double c = (x1 * fx2 - x2 * fx1 + x2 * x1 * x1 - x1 * x2 * x2) / (x1 - x2);
35 
36   BOOST_TEST(minus_b * minus_b >= 4*c);
37 
38   return std::make_pair(
39     (minus_b - sqrt(minus_b * minus_b - 4 * c)) / 2,
40     (minus_b + sqrt(minus_b * minus_b - 4 * c)) / 2);
41 }
42 
BOOST_AUTO_TEST_CASE(quadratic_estimation)43 BOOST_AUTO_TEST_CASE(quadratic_estimation)
44 {
45   std::random_device rd;
46   unsigned int seed = rd();
47   std::mt19937 gen(seed);
48   std::uniform_int_distribution<> dis(-10, 10);
49 
50   BOOST_TEST_MESSAGE("Seed = " << seed);
51 
52   for(int i = 0; i < 50; i++) {
53     BOOST_TEST_INFO_SCOPE("trial " << i+1);
54     int root1 = dis(gen);
55     int root2 = dis(gen);
56     if(root1 > root2) {
57       std::swap(root1, root2);
58     }
59     BOOST_TEST_INFO_SCOPE("root1 = " << root1);
60     BOOST_TEST_INFO_SCOPE("root2 = " << root2);
61 
62     std::pair<double, double> estimated = estimate_polynomial_roots(
63       gen,
64       [root1, root2](double x) -> double { return (x - root1) * (x - root2); });
65 
66     BOOST_TEST(estimated.first == double(root1), 10. % boost::test_tools::tolerance());
67     BOOST_TEST(estimated.second == double(root2), 10. % boost::test_tools::tolerance());
68   }
69 }
70 //]
71 
BOOST_AUTO_TEST_CASE(making_it_fail)72 BOOST_AUTO_TEST_CASE(making_it_fail)
73 {
74   // cheating a bit ... but shhhh, do not show in the docs ...
75   BOOST_FAIL("Making it fail always on all platforms");
76 }
77