NumCpp  2.10.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
Bisection.hpp
Go to the documentation of this file.
1 #pragma once
34 
35 #include <cmath>
36 #include <functional>
37 #include <utility>
38 
39 #include "NumCpp/Core/Types.hpp"
41 
42 namespace nc::roots
43 {
44  //================================================================================
45  // Class Description:
48  class Bisection : public Iteration
49  {
50  public:
51  //============================================================================
52  // Method Description:
58  Bisection(const double epsilon, std::function<double(double)> f) noexcept :
59  Iteration(epsilon),
60  f_(std::move(f))
61  {
62  }
63 
64  //============================================================================
65  // Method Description:
72  Bisection(const double epsilon, const uint32 maxNumIterations, std::function<double(double)> f) noexcept :
73  Iteration(epsilon, maxNumIterations),
74  f_(std::move(f))
75  {
76  }
77 
78  //============================================================================
79  // Method Description:
82  ~Bisection() override = default;
83 
84  //============================================================================
85  // Method Description:
92  double solve(double a, double b)
93  {
95  checkAndFixAlgorithmCriteria(a, b);
96 
97  double x = 0.5 * (a + b);
98  double fx = f_(x);
99 
100  while (std::fabs(fx) >= epsilon_)
101  {
102  x = calculateX(x, a, b, fx);
103  fx = f_(x);
104 
106  }
107 
108  return x;
109  }
110 
111  private:
112  //============================================================================
113  const std::function<double(double)> f_;
114 
115  //============================================================================
116  // Method Description:
122  void checkAndFixAlgorithmCriteria(double &a, double &b) const noexcept
123  {
124  // Algorithm works in range [a,b] if criteria f(a)*f(b) < 0 and f(a) > f(b) is fulfilled
125  if (f_(a) < f_(b))
126  {
127  std::swap(a, b);
128  }
129  }
130 
131  //============================================================================
132  // Method Description:
141  static double calculateX(double x, double &a, double &b, double fx) noexcept
142  {
143  if (fx < 0)
144  {
145  b = x;
146  }
147  else
148  {
149  a = x;
150  }
151 
152  return 0.5 * (a + b);
153  }
154  };
155 } // namespace nc::roots
Definition: Bisection.hpp:49
Bisection(const double epsilon, const uint32 maxNumIterations, std::function< double(double)> f) noexcept
Definition: Bisection.hpp:72
double solve(double a, double b)
Definition: Bisection.hpp:92
~Bisection() override=default
Bisection(const double epsilon, std::function< double(double)> f) noexcept
Definition: Bisection.hpp:58
ABC for iteration classes to derive from.
Definition: Iteration.hpp:46
Iteration(double epsilon) noexcept
Definition: Iteration.hpp:54
const double epsilon_
Definition: Iteration.hpp:116
void resetNumberOfIterations() noexcept
Definition: Iteration.hpp:94
void incrementNumberOfIterations()
Definition: Iteration.hpp:105
dtype f(GeneratorType &generator, dtype inDofN, dtype inDofD)
Definition: f.hpp:56
Definition: Bisection.hpp:43
void swap(NdArray< dtype > &inArray1, NdArray< dtype > &inArray2) noexcept
Definition: swap.hpp:42
std::uint32_t uint32
Definition: Types.hpp:40