Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ModABRootFinder.cxx
Go to the documentation of this file.
1// @(#)root/mathcore:$Id$
2// Authors: Nedelcho Ganchovski 03/03/2026
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2026 CERN *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 * *
12 **********************************************************************/
13
15#include "Math/IFunctionfwd.h"
16#include "Math/Error.h"
17#include <cmath>
18
19namespace ROOT::Math {
20
22{
23 // Set function to solve and the interval in where to look for the root.
24
25 fFunction = &f;
26 // invalid previous status
27 fStatus = -1;
28 if (xmin > xmax) {
29 fXMin = xmax;
30 fXMax = xmin;
31 } else {
32 fXMin = xmin;
33 fXMax = xmax;
34 }
35 return true;
36}
37
38const char *ModABRootFinder::Name() const
39{
40 return "ModABRootFinder";
41}
42
43namespace {
44int sign(double x)
45{
46 return (x > 0) - (x < 0);
47}
48} // namespace
49
51{
52 // Returns the X value corresponding to the function value fy for (xmin<x<xmax).
53
54 if (!fFunction) {
55 MATH_ERROR_MSG("ModABRootFinder::Solve", "Function has not been set");
56 return false;
57 }
58 double x1 = fXMin, y1 = (*fFunction)(x1);
59 if (y1 == 0.0) {
60 fRoot = x1;
61 fStatus = 0;
62 return true;
63 }
64 double x2 = fXMax, y2 = (*fFunction)(x2);
65 if (y2 == 0.0) {
66 fRoot = x2;
67 fStatus = 0;
68 return true;
69 }
70 if (sign(y1) == sign(y2)) {
71 MATH_ERROR_MSG("ModABRootFinder::Solve", "Function values at the interval endpoints have the same sign");
72 return false;
73 }
74 int side = 0;
75 bool bisection = true;
76 double threshold = x2 - x1;
77 const double C = 16;
78 for (int i = 1; i <= maxIter; ++i) {
79 double x3, y3;
80 if (bisection) {
81 x3 = (x1 + x2) / 2.0;
82 y3 = (*fFunction)(x3);
83 double ym = (y1 + y2) / 2.0;
84 double r = 1 - std::fabs(ym / (y2 - y1));
85 double k = r * r;
86 if (std::fabs(ym - y3) < k * (std::fabs(y3) + std::fabs(ym))) {
87 bisection = false;
88 threshold = (x2 - x1) * C;
89 }
90 } else {
91 x3 = (x1 * y2 - y1 * x2) / (y2 - y1);
92 // Clamp x3 when floating point round-off errors shoots it out of the bracketing interval. Assign also y values
93 // to avoid redundant re-evaluation
94 if (x3 <= x1) {
95 x3 = x1;
96 y3 = y1;
97 } else if (x3 >= x2) {
98 x3 = x2;
99 y3 = y2;
100 } else
101 y3 = (*fFunction)(x3);
102
103 threshold /= 2.0;
104 }
105 fRoot = x3;
106 fNIter = i;
107 double eps = absTol + relTol * std::abs(x3);
108 if (std::fabs(y3) == 0.0 || x2 - x1 <= eps) {
109 fStatus = 0;
110 return true;
111 }
112 if (y1 * y3 > 0.0) {
113 if (side == 1) {
114 double m = 1 - y3 / y1;
115 if (m <= 0)
116 y2 /= 2;
117 else
118 y2 *= m;
119 } else if (!bisection)
120 side = 1;
121
122 x1 = x3;
123 y1 = y3;
124 } else {
125 if (side == -1) {
126 double m = 1 - y3 / y2;
127 if (m <= 0)
128 y1 /= 2;
129 else
130 y1 *= m;
131 } else if (!bisection)
132 side = -1;
133
134 x2 = x3;
135 y2 = y3;
136 }
137 if (x2 - x1 > threshold) {
138 bisection = true;
139 side = 0;
140 }
141 }
142 fNIter = maxIter;
143 MATH_ERROR_MSG("ModABRootFinder::Solve", "Search didn't converge");
144 fStatus = -2;
145 return false;
146}
147} // namespace ROOT::Math
#define MATH_ERROR_MSG(loc, str)
Definition Error.h:83
#define f(i)
Definition RSha256.hxx:104
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
float xmin
float xmax
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition IFunction.h:157
const char * Name() const override
Return name of root finder algorithm ("ModABRootFinder").
const IGenFunction * fFunction
bool Solve(int maxIter=100, double absTol=1E-8, double relTol=1E-10) override
Returns the X value corresponding to the function value fy for (xmin<x<xmax).
bool SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup) override
Sets the function for the rest of the algorithms.
Double_t x[n]
Definition legend1.C:17
TMarker m
Definition textangle.C:8