1 /*!
2  * \file   tests/Math/BissectionAlgorithmTest.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   11/10/2020
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #ifdef NDEBUG
15 #undef NDEBUG
16 #endif /* NDEBUG */
17 
18 #include <cmath>
19 #include <limits>
20 #include <cassert>
21 #include <iostream>
22 
23 #include "TFEL/Tests/TestCase.hxx"
24 #include "TFEL/Tests/TestProxy.hxx"
25 #include "TFEL/Tests/TestManager.hxx"
26 
27 #include "TFEL/Math/General/IEEE754.hxx"
28 #include "TFEL/Math/RootFinding/BissectionAlgorithmBase.hxx"
29 
30 struct BissectionAlgorithmTest final : public tfel::tests::TestCase {
BissectionAlgorithmTestBissectionAlgorithmTest31   BissectionAlgorithmTest()
32       : tfel::tests::TestCase("TFEL/Math", "BissectionAlgorithmTest") {
33   }  // end of BissectionAlgorithmTest
executeBissectionAlgorithmTest34   tfel::tests::TestResult execute() override {
35     this->test1();
36     this->test2();
37     this->test3();
38     return this->result;
39   }  // end of execute
40  private:
test1BissectionAlgorithmTest41   void test1() {
42     TFEL_CONSTEXPR const auto eps = double(1.e-14);
43     TFEL_CONSTEXPR const auto x1 = double(7) / 5;
44     TFEL_CONSTEXPR const auto x2 = double(1.2);
45     auto a = tfel::math::BissectionAlgorithmBase<double>();
46     const auto& d = a.getData();
47     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmin));
48     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmax));
49     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmin));
50     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmax));
51     a.updateBounds(1, 2);
52     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
53     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
54     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmax));
55     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmax));
56     a.updateBounds(2, -3);
57     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
58     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
59     TFEL_TESTS_ASSERT(std::abs(d.xmax - 2) < eps);
60     TFEL_TESTS_ASSERT(std::abs(d.fmax + 3) < eps);
61     auto x = double{3};
62     a.iterate(x);
63     TFEL_TESTS_ASSERT(std::abs(x - x1) < eps);
64     a.updateBounds(1.4, -1);
65     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
66     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
67     TFEL_TESTS_ASSERT(std::abs(d.xmax - 1.4) < eps);
68     TFEL_TESTS_ASSERT(std::abs(d.fmax + 1) < eps);
69     x = x2;
70     a.iterate(x);
71     TFEL_TESTS_ASSERT(std::abs(x - x2) < eps);
72   }  // end of execute
test2BissectionAlgorithmTest73   void test2() {
74     TFEL_CONSTEXPR const auto eps = double(1.e-14);
75     TFEL_CONSTEXPR const auto x1 = double(7) / 5;
76     TFEL_CONSTEXPR const auto x2 = double(1.2);
77     auto a = tfel::math::BissectionAlgorithmBase<double>();
78     const auto& d = a.getData();
79     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmin));
80     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmax));
81     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmin));
82     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmax));
83     a.updateBounds(2, -3);
84     TFEL_TESTS_ASSERT(std::abs(d.xmin - 2) < eps);
85     TFEL_TESTS_ASSERT(std::abs(d.fmin + 3) < eps);
86     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmax));
87     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmax));
88     a.updateBounds(1, 2);
89     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
90     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
91     TFEL_TESTS_ASSERT(std::abs(d.xmax - 2) < eps);
92     TFEL_TESTS_ASSERT(std::abs(d.fmax + 3) < eps);
93     auto x = double{3};
94     a.iterate(x);
95     TFEL_TESTS_ASSERT(std::abs(x - x1) < eps);
96     a.updateBounds(1.4, -1);
97     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
98     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
99     TFEL_TESTS_ASSERT(std::abs(d.xmax - 1.4) < eps);
100     TFEL_TESTS_ASSERT(std::abs(d.fmax + 1) < eps);
101     x = x2;
102     a.iterate(x);
103     TFEL_TESTS_ASSERT(std::abs(x - x2) < eps);
104   }  // end of execute
test3BissectionAlgorithmTest105   void test3() {
106     TFEL_CONSTEXPR const auto eps = double(1.e-14);
107     TFEL_CONSTEXPR const auto x1 = double(7) / 5;
108     TFEL_CONSTEXPR const auto x2 = double(1.2);
109     auto a = tfel::math::BissectionAlgorithmBase<double>();
110     const auto& d = a.getData();
111     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmin));
112     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmax));
113     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmin));
114     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmax));
115     a.updateBounds(6, 2);
116     TFEL_TESTS_ASSERT(std::abs(d.xmin - 6) < eps);
117     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
118     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.xmax));
119     TFEL_TESTS_ASSERT(tfel::math::ieee754::isnan(d.fmax));
120     a.updateBounds(1, 2);
121     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
122     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
123     TFEL_TESTS_ASSERT(std::abs(d.xmax - 6) < eps);
124     TFEL_TESTS_ASSERT(std::abs(d.fmax - 2) < eps);
125     a.updateBounds(2, -3);
126     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
127     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
128     TFEL_TESTS_ASSERT(std::abs(d.xmax - 2) < eps);
129     TFEL_TESTS_ASSERT(std::abs(d.fmax + 3) < eps);
130     auto x = double{3};
131     a.iterate(x);
132     TFEL_TESTS_ASSERT(std::abs(x - x1) < eps);
133     a.updateBounds(1.4, -1);
134     TFEL_TESTS_ASSERT(std::abs(d.xmin - 1) < eps);
135     TFEL_TESTS_ASSERT(std::abs(d.fmin - 2) < eps);
136     TFEL_TESTS_ASSERT(std::abs(d.xmax - 1.4) < eps);
137     TFEL_TESTS_ASSERT(std::abs(d.fmax + 1) < eps);
138     x = x2;
139     a.iterate(x);
140     TFEL_TESTS_ASSERT(std::abs(x - x2) < eps);
141   }  // end of execute
142 };
143 
144 TFEL_TESTS_GENERATE_PROXY(BissectionAlgorithmTest, "BissectionAlgorithmTest");
145 
main()146 int main() {
147   auto& m = tfel::tests::TestManager::getTestManager();
148   m.addTestOutput(std::cout);
149   m.addXMLTestOutput("BissectionAlgorithm.xml");
150   return m.execute().success() ? EXIT_SUCCESS : EXIT_FAILURE;
151 }  // end of main
152