6#ifndef THEORETICA_ROOTS_H
7#define THEORETICA_ROOTS_H
9#include "../core/function.h"
10#include "../calculus/deriv.h"
11#include "../autodiff/dual.h"
12#include "../autodiff/dual2.h"
13#include "../algebra/vec.h"
14#include "../complex/complex.h"
27 template<
typename RealFunction,
typename Vector = vec2>
29 RealFunction f,
real a,
real b,
unsigned int steps = 10) {
31 std::vector<Vector> res;
32 const real dx = (b - a) / (
real) steps;
34 for (
unsigned int i = 0; i < steps; ++i) {
36 const real x1 = a + i * dx;
37 const real x2 = a + (i + 1) * dx;
39 if(f(x1) * f(x2) <= 0)
40 res.push_back({x1, x2});
57 template<
typename RealFunction>
60 real tol = OPTIMIZATION_TOL,
61 unsigned int max_iter = OPTIMIZATION_BISECTION_ITER) {
68 if(f(a) * f(b) >= 0) {
77 unsigned int iter = 0;
79 while((x_max - x_min) > (2 * tol) && iter <= max_iter) {
81 x_avg = (x_max + x_min) / 2.0;
83 if(f(x_avg) * f(x_min) > 0)
119 template<
typename RealFunction>
121 RealFunction f,
real a,
real b,
real tol = OPTIMIZATION_TOL,
122 unsigned int n0 = 1,
real k1 = 0.0) {
142 const int monotone = (y_a < y_b) ? 1 : -1;
147 const long int n_max = n_half + n0;
149 real eps = tol * pow(2.0, n_max);
152 while((b - a) > (2 * tol) && iter <= n_max) {
156 const real x_f = (a * y_b - b * y_a) / (y_b - y_a);
157 const real x_half = 0.5 * (a + b);
161 const int sigma =
sgn(x_half - x_f);
162 const real delta = k1 * square(b - a);
164 if (delta <= abs(x_half - x_f))
165 x_t = x_f + sigma * delta;
171 const real r = eps - (b - a) / 2.0;
173 if (abs(x_t - x_half) <= r)
176 x_new = x_half - sigma * r;
180 const real y_new = f(x_new);
182 if (monotone * y_new > 0) {
185 }
else if (monotone * y_new < 0) {
196 if(abs(b - a) > 2 * tol) {
197 TH_MATH_ERROR(
"root_itp", (a + b) / 2.0, NO_ALGO_CONVERGENCE);
201 return (a + b) / 2.0;
216 template<
typename RealFunction>
218 RealFunction f, RealFunction Df,
real guess = 0.0,
219 real tol = OPTIMIZATION_TOL,
unsigned int max_iter = OPTIMIZATION_NEWTON_ITER) {
223 unsigned int iter = 0;
225 while(abs(f_x) > tol && iter <= max_iter) {
228 x = x - (f_x / Df(x));
232 if(iter > max_iter) {
255 real tol = OPTIMIZATION_TOL,
256 unsigned int max_iter = OPTIMIZATION_NEWTON_ITER) {
259 unsigned int iter = 0;
263 while(abs(s.Re()) > tol && iter <= max_iter) {
268 x = x - (s.Re() / s.Dual());
272 if(iter > max_iter) {
293 typename Type = real,
294 typename ComplexFunction = std::function<complex<Type>(complex<Type>)>
297 ComplexFunction f, ComplexFunction Df, complex<Type> guess,
298 real tol = OPTIMIZATION_TOL,
299 unsigned int max_iter = OPTIMIZATION_NEWTON_ITER) {
301 complex<Type> z = guess;
302 complex<Type> f_z = Type(
inf());
303 unsigned int iter = 0;
305 while(f_z * f_z.conjugate() > tol * tol && iter <= max_iter) {
308 z = z - (f_z / df(z));
312 if(iter > max_iter) {
314 return complex<Type>(
nan(),
nan());
333 template<
typename RealFunction>
335 RealFunction f, RealFunction Df,
336 RealFunction D2f,
real guess = 0,
337 real tol = OPTIMIZATION_TOL,
338 unsigned int max_iter = OPTIMIZATION_HALLEY_ITER) {
342 unsigned int iter = 0;
344 while(abs(f_x) > tol && iter <= max_iter) {
347 const real df_x = Df(x);
349 x = x - (2 * f_x * df_x) / (2 * square(df_x) - f_x * D2f(x));
353 if(iter > max_iter) {
377 real tol = OPTIMIZATION_TOL,
378 unsigned int max_iter = OPTIMIZATION_HALLEY_ITER) {
382 unsigned int iter = 0;
384 while(abs(s.Re()) > tol && iter <= max_iter) {
388 s = f(
dual2(x, 1, 0));
390 const real f_x = s.Re();
391 const real df_x = s.Dual1();
392 const real d2f_x = s.Dual2();
394 x = x - (2 * f_x * df_x) / (2 * square(df_x) - f_x * d2f_x);
398 if(iter > max_iter) {
417 template<
typename RealFunction>
419 RealFunction f,
real guess = 0,
420 real tol = OPTIMIZATION_TOL,
421 unsigned int max_iter = OPTIMIZATION_STEFFENSEN_ITER) {
425 unsigned int iter = 0;
427 while(abs(f_x) > tol && iter <= max_iter) {
429 const real f_x = f(x);
430 const real g_x = (f(x + f_x) / f_x) - 1;
436 if(iter > max_iter) {
462 template<
typename RealFunction>
464 RealFunction f, RealFunction Df,
465 RealFunction D2f,
real guess = 0,
466 real tol = OPTIMIZATION_TOL,
467 unsigned int max_iter = OPTIMIZATION_CHEBYSHEV_ITER) {
471 unsigned int iter = 0;
473 while(abs(f_x) > tol && iter <= max_iter) {
476 const real df_x = Df(x);
477 const real u = f_x / df_x;
479 x = x - u - square(u) * D2f(x) / (2.0 * df_x);
484 if(iter > max_iter) {
513 real tol = OPTIMIZATION_TOL,
514 unsigned int max_iter = OPTIMIZATION_CHEBYSHEV_ITER) {
518 unsigned int iter = 0;
520 while(abs(s.Re()) > tol && iter <= max_iter) {
522 s = f(
dual2(x, 1.0, 0.0));
524 const real f_x = s.Re();
525 const real df_x = s.Dual1();
526 const real u = f_x / df_x;
528 x = x - u - square(u) * s.Dual2() / (2.0 * df_x);
532 if(iter > max_iter) {
557 template<
typename RealFunction>
559 RealFunction f, RealFunction Df,
real guess = 0.0,
560 real tol = OPTIMIZATION_TOL,
561 unsigned int max_iter = OPTIMIZATION_OSTROWSKI_ITER) {
565 unsigned int iter = 0;
567 while(abs(f_x) > tol && iter <= max_iter) {
570 const real df_x = Df(x);
571 const real u = f_x / df_x;
572 const real f_xu = f(x - u);
574 x = x - u - (f_xu / df_x) * (f_x / (f_x - 2 * f_xu));
579 if(iter > max_iter) {
605 template<
typename RealFunction>
607 RealFunction f, RealFunction Df,
real guess = 0.0,
608 real tol = OPTIMIZATION_TOL,
609 unsigned int max_iter = OPTIMIZATION_JARRAT_ITER) {
613 unsigned int iter = 0;
615 while(abs(f_x) > tol && iter <= max_iter) {
618 const real df_x = Df(x);
619 const real u = f_x / df_x;
620 const real f_xu = Df(x - 2.0 * u / 3.0);
622 x = x - 0.5 * u + f_x / (df_x - 3 * f_xu);
626 if(iter > max_iter) {
649 template<
typename RealFunction>
652 real tol = OPTIMIZATION_TOL,
real steps = 10) {
662 std::vector<real> res;
663 res.reserve(intervals.size());
666 for (
unsigned int i = 0; i < intervals.size(); ++i) {
671 res.push_back(intervals[i][0]);
676 res.push_back(intervals[i][1]);
682 root_bisect(f, intervals[i][0], intervals[i][1], tol)
697 template<
typename Field>
699 const polynomial<Field>& p,
700 real tolerance = OPTIMIZATION_TOL,
701 unsigned int steps = 0) {
704 const unsigned int n = p.find_order();
708 Field a_hi = abs(p.coeff[n]);
712 for (
unsigned int i = 0; i < n; ++i)
713 a_sum += abs(p.coeff[i]);
716 const Field M =
max(a_hi, a_sum);
721 [p](
real x) {
return p(x); },
722 -M, M, tolerance, steps ? steps : (2 * n));
Second order dual number class.
Definition dual2.h:29
Dual number class.
Definition dual.h:28
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition error.h:225
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:198
real root_newton(RealFunction f, RealFunction Df, real guess=0.0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_NEWTON_ITER)
Find a root of a univariate real function using Newton's method.
Definition roots.h:217
real root_halley(RealFunction f, RealFunction Df, RealFunction D2f, real guess=0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_HALLEY_ITER)
Find a root of a univariate real function using Halley's method.
Definition roots.h:334
dual2 log2(dual2 x)
Compute the natural logarithm of a second order dual number.
Definition dual2_functions.h:166
std::vector< Vector > find_root_intervals(RealFunction f, real a, real b, unsigned int steps=10)
Find candidate intervals for root finding by evaluating a function at equidistant points inside an in...
Definition roots.h:28
std::vector< real > roots(RealFunction f, real a, real b, real tol=OPTIMIZATION_TOL, real steps=10)
Find the roots of a univariate real function inside a given interval, by first searching for candidat...
Definition roots.h:650
auto max(const Vector &X)
Finds the maximum value inside a dataset.
Definition dataset.h:330
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54
real root_bisect(RealFunction f, real a, real b, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_BISECTION_ITER)
Find the root of a univariate real function using bisection inside a compact interval [a,...
Definition roots.h:58
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:207
real root_itp(RealFunction f, real a, real b, real tol=OPTIMIZATION_TOL, unsigned int n0=1, real k1=0.0)
Find a root of a univariate real function using the ITP (Interpolate-Truncate-Project) method,...
Definition roots.h:120
real root_steffensen(RealFunction f, real guess=0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_STEFFENSEN_ITER)
Find a root of a univariate real function using Steffensen's method.
Definition roots.h:418
real root_ostrowski(RealFunction f, RealFunction Df, real guess=0.0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_OSTROWSKI_ITER)
Find a root of a univariate real function using Ostrowski's method.
Definition roots.h:558
real root_chebyshev(RealFunction f, RealFunction Df, RealFunction D2f, real guess=0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_CHEBYSHEV_ITER)
Find a root of a univariate real function using Chebyshev's method.
Definition roots.h:463
int sgn(real x)
Return the sign of x (1 if positive, -1 if negative, 0 if null)
Definition real_analysis.h:259
TH_CONSTEXPR real inf()
Get positive infinity in floating point representation.
Definition error.h:76
real root_jarrat(RealFunction f, RealFunction Df, real guess=0.0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_JARRAT_ITER)
Find a root of a univariate real function using Jarrat's method.
Definition roots.h:606
TH_CONSTEXPR int floor(real x)
Compute the floor of x Computes the maximum integer number that is smaller than x.
Definition real_analysis.h:271