Next Article in Journal
A Novel and Practical Algorithmic Enhancement for Enumerating Maximal and Maximum k-Partite Cliques in k-Partite Graphs
Previous Article in Journal
An RMST-Integrated Machine Learning Framework for Interpretable Survival Analysis Under Non-Proportional Hazards: Application to the METABRIC Cohort
 
 
Font Type:
Arial Georgia Verdana
Font Size:
Aa Aa Aa
Line Spacing:
Column Width:
Background:
Article

Improvements to the Modified Anderson–Björck (modAB) Root-Finding Algorithm

by
Nedelcho Ganchovski
1,*,
Oscar Smith
2,
Christopher Rackauckas
2,3,
Lachezar Tomov
4 and
Alexander Traykov
5
1
Proektsoft EOOD, 1164 Sofia, Bulgaria
2
JuliaHub, Cambridge, MA 02138, USA
3
CSAIL, Massachusetts Institute of Technology, Cambridge, MA 02139, USA
4
Department of Computer Science, New Bulgarian University, 1618 Sofia, Bulgaria
5
Department of Structural Mechanics, University of Architecture, Civil Engineering and Geodesy, 1164 Sofia, Bulgaria
*
Author to whom correspondence should be addressed.
Algorithms 2026, 19(5), 332; https://doi.org/10.3390/a19050332
Submission received: 25 March 2026 / Revised: 14 April 2026 / Accepted: 21 April 2026 / Published: 24 April 2026

Abstract

The Modified Anderson–Björck method is a new, robust, and efficient bracketing root-finding algorithm. It combines bisection with the Anderson–Björk method to achieve both fast performance and worst-case optimality. It relies on linearity check criteria for switching methods and uses Anderson–Björk corrections to overcome the fixed endpoint issue of false-position. Initial benchmarks of this method have shown certain performance advantages compared to other methods, such as Ridders, Brent and ITP. In this paper, we propose further improvements to this method and perform some additional analysis and benchmarks of its behavior and performance.

1. Introduction

Iterative algorithms are generally fast but can easily diverge if an improper starting point is selected. Bracketing algorithms are more reliable in this respect. If the function is continuous in the interval [a, b] and has opposite signs at both ends, according to Bolzano’s theorem, at least one root exists inside [a, b], and the bracketing method is guaranteed to find it within a certain precision. Bisection is the simplest method, and it is also worst-case optimal. The required number of iterations is constant for a certain precision and does not depend on the function properties. It can be precomputed using the following equation:
n = log 2 x 2 x 1 2 ϵ
However, for well-behaved functions, other algorithms like false-position, Illinois [1], and Ridder’s [2] can provide significantly better performance, but for poorly behaved functions, they can perform significantly worse than bisection. Therefore, stability and performance are contradictory goals and achieving both is a challenging task. Some authors have noted that this can be done by combining bisection with a faster algorithm like false-position [3], secant or inverse-quadratic interpolation. Examples of these combinations include Brent’s method [4] and the ITP [5] method. Also, initial bisection steps can boost the performance of false-position and similar methods by bringing the starting point to more favorable conditions [6,7]. Although it is obtained through a combination of linear algorithms, the resulting algorithm shows nonlinear (bilinear) behavior and better convergence than using both algorithms separately. In all cases, the selection of proper switching criteria is of key importance for applying each method at the most appropriate place and thus maximizing the overall performance.

2. The Original Modified Anderson–Björck (modAB) Algorithm

On that basis, a new hybrid algorithm was proposed in 2023 [6] that combined bisection with Anderson–Björck’s (AB) method. The switching criteria is based on measuring the linearity of the function. In this way, linear interpolation is applied when the deviation of the curve from a straight line becomes small enough according to the following equation:
y 3 y m < k y 3 + y m ,
where y3 is the function value at the midpoint, ym is the chord ordinate at the same point and k is the limit deviation factor. After switching, the iterations continue as ordinary AB steps as follows:
  • An intermediate point is calculated by linear interpolation:
    x 3 = x 1 f x 2 x 2 f x 1 f x 2 f x 1
  • The ordinate of the end that remained fixed at the previous iteration is reduced by a factor m. For the left end, it is calculated by the expression y1 = f(x1) · m, where m = 1 − f(x3)/f(x2) if m > 0; otherwise, m = 0.5. For the right end, the equation is obtained by swapping indices 1 and 2, as follows: y2 = f(x2) · m, where m = 1 − f(x3)/f(x1) if m > 0; otherwise, m = 0.5.
An option to fall back to bisection is provided if AB fails to converge within a certain number of iterations. The original algorithm has been included in the Calcpad [8] and Root-Fortan [9] libraries. Although the algorithm has shown superior performance compared to others in tests, and later in practice, we have identified some drawbacks and opportunities for further improvements.

3. Drawbacks of the Original Algorithm

The original algorithm has several shortcomings that can be addressed:
  • The deviation factor k in Equation (2) has a fixed value of k = 0.25 as a good average estimate, experimentally tuned on a larger set of functions. However, this is not optimal because it does not account for the properties of the function in the selected interval.
  • Although the possibility of a redundant switch to AB was discussed in [6], not much research has been done on the subject. Only a simple bisection fallback is included as a safety mechanism if the algorithm fails to converge within the expected number of iterations. It is proposed empirically to be half of the required bisection steps. This is a simple and conservative approach, but in certain cases, it may result in unnecessary AB steps before the algorithm recognizes that it is not converging as intended.
  • The original algorithm uses the termination criteria of the false-position method: |xnxn−1| < ε. Further tests have shown that it fails for certain functions that are flat near the root, but with large ordinates at endpoints (>1/ε). This can cause the interpolation point to crawl very slowly along the abscissa, so the step may become lower than ε, even if we are still too far from the root.
  • The benchmarks in the original paper [6] were based on the number of iterations with a factor of two for Ridder’s method. However, the number of function evaluations is more closely related to the actual performance, especially when the function is computationally expensive.
  • In the original paper, we used 21 functions to benchmark the method performance. This set is very limited, which can lead to some distortion in the results. Therefore, the set may be considered insufficient to derive reliable conclusions. It may turn out that some algorithms are particularly suitable for a larger part of the functions in the set, showing a false advantage. That is why additional tests were performed in [7] with a set of 50 functions.

4. Improvements to the modAB Algorithm

In this paper, we propose a new version of the modAB algorithm, aiming for it to be more robust, reliable and efficient than the first one. This is achieved by fixing the above issues and making it more adaptive to the properties of the function.

4.1. Adaptive Value of Deviation Factor k

For highly curved functions like the one in Figure 1, symmetry plays a key role in the behavior of linear interpolation algorithms. If the endpoint ordinates are highly asymmetric, as shown in the left plot, it is possible for the root to occur at a greater distance. This will slow down performance, since there is not only a longer path to travel, but the step size also becomes smaller. If the endpoint values are nearly symmetric, the behavior improves significantly, even when both functions have the same deviation from the straight line.
For that reason, it is reasonable to include symmetry in the method’s switching criterion, and the factor k seems to be the right place to do so. For unsymmetric endpoints, we can keep k lower, forcing the algorithm to take more bisection steps. For symmetric endpoints, we can make k larger and allow the algorithm to switch faster to AB, since we expect it to be more favorable here. However, this is highly dependent on the shape of the function. Therefore, tuning it too much for specific types of functions is not justified. Instead, we can map the value of k against the endpoint ordinates by using a simple relationship that is fast to evaluate and does not bring significant overhead on each iteration.
For that purpose, we will introduce a new factor of symmetry r by using the following equation:
r = 1 y m y 2 y 1 ,
where y1 = f(x1), y2 = f(x2) and ym = 0.5 (y1 + y2) is the average value. Thus, we have r = 1 for symmetric and r = 0.5 for unsymmetric endpoint ordinates. Symmetry also ensures that the distance from the interpolation point to the root cannot exceed 0.5 (x2x1). Otherwise, it can approach the whole interval length of x2x1. But how do we take this into account in the deviation factor k? If we look closely at the above functions, we can see that the relationship between symmetry and convergence is not linear. Higher symmetry leads to both a shorter path and longer step size, which is a quadratic relationship. The simplest quadratic expression we can use is k = r2. Thus, we map k to the interval [0.25, 1], where 0.25 is our old value for k, but with an allowance to grow up to 1 for fully symmetric endpoints.

4.2. Adaptive Bisection Fallback Criterion

Instead of using a fixed number of expected iterations, we can apply a more precise criterion by measuring the actual performance of the AB algorithm after switching. A possible simple and direct approach is to check whether AB has shrunk the interval more than bisection would do. Assume that the algorithm switches from bisection to AB at the interval [a0, b0] with initial length
W 0 = b 0 a 0
After performing t more steps, a pure bisection method would reduce the length to W 0 / 2 t . Therefore, we will define a fallback threshold as follows:
T t = C W 0 2 t
where C is a safety factor. Let W t = b t a t denote the actual interval width after t AB steps. Then, the adaptive bisection fallback criterion becomes
W t > T t
Taking C = 2n will allow for a delay of n AB steps before switching back to bisection. Numerical experiments have shown that switching without a safety factor causes the algorithm to oscillate rapidly between methods, significantly degrading the performance. Therefore, the question is how to select a suitable value for C. One or two iterations proved to be insufficient to prevent oscillations. A reasonable value of n appeared to be between three and four. Larger values caused the algorithm to waste too many iterations on AB. Therefore, we can safely pick n = 4, and thence C = 24 = 16. For efficiency, we will not apply Equation (6) directly, but instead will initialize the threshold at switching to AB as T 0   = C W 0 . Then, we will update it on each AB iteration t using the equation T t = T t 1 / 2 .
To demonstrate how the new switching criteria works, we will take a nearly symmetrical function f(x) = x3 − 0.001 and solve the equation f(x) = 0 in the interval [−10, 10]. The plot is displayed in Figure 2.
Both the original and proposed algorithms switch to AB at the first iteration, finding themselves in a position to deal with a highly nonlinear and unsymmetric problem. After that, they show very different behavior, as summarized in Table 1 below. This demonstrates that using fixed switching criteria is not optimal and can possibly slow down the algorithm.

4.3. New Termination Check

Instead of the false-position convergence check |xnxn−1| < ε, we will use a more robust and reliable bisection-style check bnan < εabs + εrel · |xn|, where an and bn are the endpoints of the interval at iteration n, and εabs and εrel are the absolute and relative tolerances, respectively. This criterion is not applicable for the pure false-position method because of the fixed endpoint issue, but the AB corrections always cause the interval to shrink from both sides. However, for some functions, shrinking from the other side may require one or two extra steps, after the solution has converged from one side. Nevertheless, this trade-off is justified by the improved robustness and reliability of the method.
Additionally, we can separate the convergence checks along x and y. Since the x-check does not depend on the y-value, we can move it to the top and thus save one function evaluation.

4.4. The Improved Algorithm

After implementing the above improvements and refactoring the structure, we arrive at the following improved version of the modAB algorithm (Algorithm 1):
Algorithm 1: The improved modAB algorithm.
1. Calculate points p1: x1, y1 = f(x1) and p2: x2, y2 = f(x2)
2. initialize “method” to “bisection” and “side” to “none”
3. for iter = 1 to maxIterations
4.   if “method” is “bisection” then:
5.      calculate x3 as the midpoint: x3 = (x1 + x2)/2
6.   else if method is “Anderson-Björck” then:
7.      calculate x3 as the secant point: x3 = (x1*y2y1*x2)/(y2y1)
8.   end
9.   if the x-convergence check x2x1εabs + εrel*|x3| is satisfied then:
10.      stop and return x3 as a result (avoids redundant evaluation of y3 = f(x3))
11.   end
12.   if “method” is “bisection” then:
13.      calculate p3: x3, y3 = f(x3)
14.      calculate the average ordinate by the equation: ym = (y1 + y2)/2
15.      calculate r to Equation (4) and k = r2
16.      if the function is close enough to linear, satisfying that _
       |ymy3| < k (|y3| + |ym|) then:
17.          change the method to “Anderson-Björck”
18.      end
19.   else if method is “Anderson-Björck” then:
20.      calculate p3: x3, y3 = f(x3) and clamp it between p1 and p2 _
         (in case floating point round-off errors shoot it outside the interval)
21.   end
22.   if the y-convergence check y3 = 0 is satisfied then:
23.      stop and return x3 as a result
24.   end
25.   if y1 and y3 have equal signs then:
26.      if “method” is “Anderson-Björck” then: (apply AB correction)
27.         if “side” is “right” then
28.               calculate m = 1 − y3/y1
29.               if m ≤ 0 then: divide y2 by 2 else: multiply y2 by m
30.         else:
31.            change “side” to “right”
32.         end
33.      end
34.      for both methods, shrink the interval from left by setting p1 = p3
35.   else
36.      if “method” is “Anderson-Björck” then:
37.         if “side” is “left” then:
38.            calculate m = 1 − y3/y2
39.            if m ≤ 0 then: divide y1 by 2 else: multiply y1 by m
40.         else:
41.            change “side” to “left”
42.         end
43.      end
44.      for both methods, shrink the interval from right by setting p2 = p3
45.   end
46.   if AB fails to shrink the interval more than bisection would, then:
47.      reset the method back to “bisection”
48.   end
49. end
50. return error, if failed to converge for the expected number of iterations

4.5. Convergence

Since the modAB algorithm represents a modification of Anderson–Björck’s method [10], guarded by bisection, it should naturally inherit its superlinear convergence, estimated to be between 1.7 and 1.8. This assumption corresponds well to the results from the numerical experiments presented below. The proposed changes are aimed mostly at improving the worst-case scenarios where the original AB algorithm struggles to converge. However, more rigorous convergence analysis will be performed in future and published in a separate paper.

4.6. Practical Use and Implementation in Software

The source code of the algorithm is listed in Appendix A. It has also been translated into Julia, Python, Cython, C, C++ and Zig languages. The modAB algorithm is included in Calcpad v7.6.2 [8], SciML/NonlinearSolve.jl v4.17.1 [11], JuliaMath/Roots.jl v2.2.11 [12], and ROOT.CERN v6-40-00-rc1 [13] libraries for scientific computations. It can be used in Python v3.x via the PyModAB v1.0.3 [14] package. For all implementations, modAB demonstrated superior performance compared to the existing algorithms, according to the benchmarks.

5. Numerical Experiments

The improved modAB algorithm is benchmarked against the original version and seven classical algorithms: bisection, false-position, Illinois [1], Anderson–Björck [9], ITP [5], Ridders [2] and Brent [4,15]. For this purpose, they are also implemented in C# programming language.
An extended set of 92 functions is used for the benchmarks. To avoid bias, they are collected from papers by authors of other algorithms and independent comparative studies as follows:
  • Sérgio Galdino [16]: f01f30
  • Custom functions [7]: f31f32
  • Steven A. Stage [17]: f33f40
  • Swift & Lindfield [18]: f41f50
  • Alojz Suhadolnik [19]: f51f62
  • Oliveira & Takahashi [5]: f63f83
  • SciML Benchmarks suite [11]: f84f92
Plots of all functions with equations and root values are presented in the Supplementary File: Test Functions.pdf. The benchmarks are based on the number of function evaluations, which are more indicative of the actual performance than the number of iterations, especially for computationally expensive functions. The results are presented in Table 2.
Additionally, we have benchmarked the time performance of the above algorithms for the same set of functions using the BenchmarkDotNet tool [20]. The results are presented in Table 3.
If we plot both the number of evaluations and benchmark times side by side, we can see that the time differences are greater for all algorithms, except for bisection, as displayed in Figure 3.
For computationally expensive functions, the number of evaluations governs because most of the time is spent on the function itself. For lightweight functions, the computational overhead of the algorithm can be important. Bisection is the simplest method, so it shows better results in time than in number of evaluations. ITP is on the opposite side. It is very efficient in terms of evaluation count, but computationally intensive. Its larger overhead per iteration downgrades its performance in the time domain. ModAB uses simple linear interpolation (with endpoint corrections) and bisection. This makes it very lightweight, and introduces very little overhead per iteration, especially when bisection is dominant. This is an advantage when multiple simple equations must be solved in a tight loop.

6. Discussion

The results show an improvement of about 7% in the proposed modAB algorithm compared to the original one, requiring 1741 total evaluations vs. 1857, respectively. If we keep the same convergence check, the effect of improving the method switching and fallback criteria is about 10% (1672 total evaluations). Therefore, the new convergence check slows down the algorithm by 3%; however, providing robustness is always more important than speed. Compared to the original Anderson–Björck algorithm, there is an improvement of about 1.78 times. The new modAB algorithm also outperforms Ridder’s by 1.3 times, ITP by 1.61 times and Brent by 1.65 times.
Compared to the original 2023 version, the proposed changes save 116 evaluations. Also, 45 functions are improved, and 10 functions are made worse, mostly by between one and two evaluations, except for f70, for which five evaluations are added. The greatest improvement is observed for f78, where the updated linearity check allows AB to take over in time, and save 42 evaluations. The new adaptive bisection fallback provides the most help to f92, saving 17 evaluations.
For well-behaved functions, the new algorithm often shows the best performance (38 functions) or remains between one and two evaluations behind the winner. For poorly behaved functions, the guarding role of bisection appears to work, providing no more than 55 evaluations in the worst case. This is probably due to spurious switching from bisection to AB and the fallback. It can also be noted that after extending the number of test functions, the relationships between the efficiencies of the separate algorithms are preserved. This indicates that the conclusions previously derived in [6] were not distorted by the chosen set of functions.
By analyzing the standard deviation and error in Table 2 and Table 3, we can observe that the modAB algorithm provides more uniform and consistent behavior for various types of functions.

7. Conclusions

The proposed method is suitable for use as a general-purpose algorithm for solving nonlinear equations in numerical libraries and software where guaranteed convergence, robustness and high performance are required but no preliminary information about the specific properties of the function and its derivatives is available.

Supplementary Materials

The following supporting information can be downloaded at https://www.mdpi.com/article/10.3390/a19050332/s1: [CSharp code] folder: complete C# source code; Test Functions.pdf file: equations and plots of functions with the corresponding roots; Test Results.xlsx file: detailed benchmark results, including root values and function values.

Author Contributions

Project administration, N.G.; methodology, N.G.; software, N.G., O.S. and C.R.; validation, O.S., C.R. and L.T.; writing—original draft preparation, N.G.; writing—review and editing, O.S., C.R., L.T. and A.T. All authors have read and agreed to the published version of the manuscript.

Funding

This research received no external funding.

Data Availability Statement

The original contributions presented in this study are included in the article/Supplementary Materials. Further inquiries can be directed to the corresponding author.

Acknowledgments

The authors express their gratitude to the reviewers for providing their valuable comments and recommendations, which significantly contributed to the improvement of the final version of this article.

Conflicts of Interest

Author Nedelcho Ganchovski was employed by the company Proektsoft EOOD. Authors Oscar Smith and Christopher Rackauckas were employed by the company JuliaHub. The remaining authors declare that the research was conducted in the absence of any commercial or financial relationships that could be construed as a potential conflict of interest.

Abbreviations

The following abbreviations are used in this manuscript:
ABAnderson–Björck
modABModified Anderson–Björck
ITPInterpolate, Truncate, Project

Appendix A

Table A1. Source code of the algorithm in C# programming language.
Table A1. Source code of the algorithm in C# programming language.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
// Struct to store calculation nodes abscissas and ordinates
private struct Node {
    public double X; public double Y;
    public Node(double x, double y) { X = x; Y = y; }
    public Node(double x, Func<double, double> F) { X = x; Y = F(x); }
    public static double Sec(Node p1, Node p2) =>
     (p1.X * p2.Y - p1.Y * p2.X) / (p2.Y - p1.Y);
    public static double Mid(Node p1, Node p2) => (p1.X + p2.X) / 2.0;
}
// Initializes the interval and checks if bracketing is applicable
private static bool Initialize(double x1, double x2, Func<double, double> F,
    out Node p1, out Node p2) {
    if (x1 > x2) {
     p1 = new(x2, F); p2 = new(x1, F);
    } else {
     p1 = new(x1, F); p2 = new(x2, F);
    }
  return Math.Sign(p1.Y) != Math.Sign(p2.Y);
}
// Finds the root of F(x) = 0 within the interval [x1, x2] with the specified
// absolute (aTol) and relative (rTol) precisions, using the improved modAB
// algorithm. F(x) must be continuous and sign(F(x1)) ≠ sign(F(x2))
public static double ModAB(Func<double, double> F, double x1, double x2,
    double aTol = 1e-14, double rTol = 1e-14, int maxIterations = 200) {
    if (!Initialize(x1, x2, F, out Node p1, out Node p2)) return double.NaN;
    var bisection = true;      // Initialize the method to bisection
    var side = 0;         // Store the side that moved last:
                // -1 for left, 1 for right, 0 for none
    var threshold = p2.X - p1.X; // Threshold to reset to bisection
    const double C = 16; // Safety factor of 4 iterations behind the threshold
    for (int i = 1; i <= MaxIterations; ++i) {
     var x3 = bisection ? Node.Mid(p1, p2) : Node.Sec(p1, p2);
     // Check for x-convergence and return the result
     if (p2.X - p1.X <= aTol + rTol * Math.Abs(x3)) return x3;
     Node p3;
     if (bisection) {
         p3 = new Node(x3, F);
         double y1 = p1.Y, y2 = p2.Y;
         var ym = 0.5 * (y1 + y2);
         var r = 1 - Math.Abs(ym / (y2 - y1)); // Symmetry factor
         var k = r * r;             // Deviation factor
         // If function is close enough to linear
         if (Math.Abs(ym - p3.Y) < k * (Math.Abs(p3.Y) + Math.Abs(ym))) {
        bisection = false; // switch to false-position
        threshold = (p2.X - p1.X) * C;
       }
     } else {
       // Clamp the secant point to the interval [p1.X, p2.X]
       // Otherwise, for very flat functions, floating-point
       // round-off errors can shoot the point outside
       if (x3 <= p1.X)
        p3 = p1;
       else if (x3 >= p2.X)
        p3 = p2;
       else
        p3 = new Node(x3, F); // Evaluate only if not clamped

       threshold * = 0.5;
     }
     // Check for y-convergence and return the result
     if (p3.Y == 0) return x3;
     if (Math.Sign(p1.Y) == Math.Sign(p3.Y)) {
       if (side == 1) {
         var m = 1 - p3.Y / p1.Y;   // Apply Anderson-Björck correction
         p2.Y *= m <= 0 ? 0.5 : m;  // to the right side
       }
       else if (!bisection) side = 1;
       p1 = p3;
     } else {
       if (side == -1) {
         var m = 1 - p3.Y / p2.Y;   // Apply Anderson-Björck correction
         p1.Y *= m <= 0 ? 0.5 : m;  // to the left side
       }
       else if (!bisection) side = -1;
       p2 = p3;
     }
     // If Anderson-Björck fails to shrink the interval enough
     if (p2.X - p1.X > threshold) {
       bisection = true; // reset to bisection
       side = 0;
     }
   }
   return double.NaN; // When failed to converge within maxIterations
}

References

  1. Dowell, M.; Jarratt, P. A modified regula falsi method for computing the root of an equation. BIT 1971, 11, 168–174. [Google Scholar] [CrossRef]
  2. Ridders, C. A new algorithm for computing a single root of a real continuous function. IEEE Trans. Circuits Syst. 1979, 26, 979–980. [Google Scholar] [CrossRef]
  3. Sabharwal, C. Blended Root Finding Algorithm Outperforms Bisection and Regula Falsi Algorithms. Mathematics 2019, 7, 1118. [Google Scholar] [CrossRef]
  4. Brent, R. An algorithm with guaranteed convergence for finding a zero of a function. Comput. J. 1971, 14, 422–425. [Google Scholar] [CrossRef]
  5. Oliveira, I.; Takahashi, R. An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality. ACM Trans. Math. Softw. 2021, 47, 5. [Google Scholar] [CrossRef]
  6. Ganchovski, N.; Traykov, A. Modified Anderson-Björck’s method for solving non-linear equations in structural mechanics. IOP Conf. Ser. Mater. Sci. Eng. 2023, 1276, 012010. [Google Scholar] [CrossRef]
  7. Ganchovski, N. Structural Analysis by Functional Modelling in the Cloud. Ph.D. Thesis, UACEG, Sofia, Bulgaria, 2025. [Google Scholar]
  8. Ganchovski, N. Calcpad—A Free and Open-Source Software for Engineering Calculations. Available online: https://calcpad.eu/ (accessed on 16 April 2026).
  9. Williams, J. Roots-Fortran: Root Solvers for Modern Fortran; NASA JSC: Houston, TX, USA, 2025; Available online: https://jacobwilliams.github.io/roots-fortran/ (accessed on 25 March 2026).
  10. Anderson, N.; Björck, Å. A new high order method of regula falsi type for computing a root of an equation. BIT 1973, 13, 253–264. [Google Scholar] [CrossRef]
  11. Pal, A.; Holtorf, F.; Larsson, A.; Loman, T.; Utkarsh; Schäfer, F.; Qu, Q.; Edelman, A.; Rackauckas, C. NonlinearSolve.jl: High-Performance and Robust Solvers for Systems of Nonlinear Equations in Julia. ACM Trans. Math. Softw. 2026, 52, 1. [Google Scholar] [CrossRef]
  12. Verzani, J. Roots.jl: Root Finding Functions for Julia. 2020. Available online: https://github.com/JuliaMath/Roots.jl (accessed on 25 March 2026).
  13. Brun, R.; Rademakers, F. ROOT—An Object Oriented Data Analysis Framework. Nucl. Inst. Meth. Phys. Res. A 1997, 389, 81–86. [Google Scholar] [CrossRef]
  14. PyModAB—Fast and Robust Root-Finding Library Using the Modified Anderson-Bjork Method. Available online: https://pypi.org/project/pymodab/ (accessed on 10 April 2026).
  15. Press, W.; Teukolsky, S.; Vetterling, W.; Flannery, B. Numerical Recipes: The Art of Scientific Computing, 3rd ed.; Cambridge University Press: Cambridge, MA, USA, 2007. [Google Scholar]
  16. Galdino, S. A family of regula falsi root-finding methods. In Proceedings of 2011 World Congress on Engineering and Technology; IEEE Press: Shanghai, China, 2011; pp. 514–517. [Google Scholar]
  17. Stage, S.A. Comments on An Improvement to the Brent’s Method. Int. J. Exp. Algorithms 2013, 4, 1–16. [Google Scholar]
  18. Swift, A.; Lindfield, G.R. Comparison of a continuation method with Brent’s method for the numerical solution of a single nonlinear equation. Comput. J. 1978, 21, 359–362. [Google Scholar] [CrossRef][Green Version]
  19. Suhadolnik, A. Combined bracketing methods for solving nonlinear equations. Appl. Math. Lett. 2012, 25, 1755–1760. [Google Scholar] [CrossRef]
  20. BenchmarkDotNet: Powerful. NET Library for Benchmarking. Available online: https://benchmarkdotnet.org/ (accessed on 10 April 2026).
Figure 1. Plot of function f x = 11 · x 11 c , for c = 1 and 5.
Figure 1. Plot of function f x = 11 · x 11 c , for c = 1 and 5.
Algorithms 19 00332 g001
Figure 2. Plot of function f(x) = x3 − 0.001, for x ∈ [−10, 10].
Figure 2. Plot of function f(x) = x3 − 0.001, for x ∈ [−10, 10].
Algorithms 19 00332 g002
Figure 3. Combined benchmark results.
Figure 3. Combined benchmark results.
Algorithms 19 00332 g003
Table 1. Comparison of switching criteria in the original and the proposed methods.
Table 1. Comparison of switching criteria in the original and the proposed methods.
AlgorithmIteration Number
Switch to ABFallback to BisectionSwitch to ABConverge and Quit
The original modAB 2023 [6] fixed criteria1243440
The proposed new adaptive criteria171524
Table 2. Benchmark results for solving fnn(x) = 0 in the interval [a; b].
Table 2. Benchmark results for solving fnn(x) = 0 in the interval [a; b].
FunctionIntervalMethod
abbsfpillABITPRidBremodAB 1modAB 2
f01(x) = x3 − 10.51.53341091041033
f02(x) = x2 (x2/3 + sqrt(2) · sin(x)) − sqrt(x)/180.11488712123916131212
f03(x) = 11x11 − 10.114810816235014121315
f04(x) = x3 + 1−1.80495013111212101010
f05(x) = x3 − 2x − 523473298511481012
f06(x) = 2x · exp(−5) + 1 − 2 · exp(−5x)01493010101314101210
f07(x) = 2x · exp(−10) + 1 − 2 · exp(−10x)01493113111514121311
f08(x) = 2x · exp(−20) + 1 − 2 · exp(−20x)01493113131712121312
f09(x) = (1 + (1 − 5)2) · x2 − (1 − 5x)20149171294816101211
f10(x) = (1 + (1 − 10)2) · x2 − (1 − 10x)201491410912161099
f11(x) = (1 + (1 − 20)2) · x2 − (1 − 20x)20149121081016999
f12(x) = x2 − (1 − x)5014941109111491211
f13(x) = x2 − (1 − x)1001498312104916101212
f14(x) = x2 − (1 − x)20014917112125016131312
f15(x) = (1 + (1 − 5)4) · x − (1 − 5x)401499971012899
f16(x) = (1 + (1 − 10)4) · x − (1 − 10x)40149676912788
f17(x) = (1 + (1 − 20)4) · x − (1 − 20x)40149676912788
f18(x) = exp(−5x) · (x − 1) + x5014881108371491111
f19(x) = exp(−10x) · (x − 1) + x100148202149111691312
f20(x) = exp(−20x) · (x − 1) + x20014820222101216131314
f21(x) = x2 + sin(x/5) − 1/4014934109101211129
f22(x) = x2 + sin(x/10) − 1/401483311910121099
f23(x) = x2 + sin(x/20) − 1/401483212910121099
f24(x) = (x + 2) · (x + 1) · (x − 3)32.64.6482029110851801374948
f25(x) = (x − 4)5 · log(x)3.65.64820217418851621184948
f26(x) = (sin(x) − x/4)324482029110851781374948
f27(x) = (81 − p(x) · (108 − p(x) · (54 − p(x) · (12 −
p(x))))) · sign (p(x) − 3), where p(x) = x + 1.11111
131420235382224311414
f28(x) = sin(x − 7.143)3)78462028710250701314746
f29(x) = exp((x − 3)5) − 12.64.6122025946318301212
f30(x) = exp((x − 3)5) − exp(x − 1)454720252575016141413
f31(x) = π − 1/x0.055511921575316121312
f32(x) = 4 − tan(x)01.5489214115116131314
f33(x) = cos(x) − x3045020015151118151312
f34(x) = cos(x) − x−11953111091116101011
f35(x) = sqrt(abs(x − 2/3)) · if(x ≤ 2/3; 1; −1) − 0.1−119531516135424111817
f36 (x) = abs(x − 2/3)0.2 · if(x ≤ 2/3; 1; −1)−119534447544654445455
f37(x) = (x − 7/9)3 + (x − 7/9) · 10−3−1195220225271324311816
f38(x) = if(x ≤ 1/3; −0.5; 0.5)−119535361615356535453
f39(x) = if(x ≤ 1/3; −10−3; 1 − 10−3)−119532021721725584835453
f40(x) = if(x = 0; 0.0; 1/(x − 2/3))−1195381001005560555453
f41(x) = 2x · exp(−5) − 2 · exp(−5x) + 1010523314131714131513
f42(x) = (x2x − 6) · (x2 − 3x + 2)0π50231291618101312
f43(x) = x3−11.5502029411352841245150
f44(x) = x5−11.55020218320252561275150
f45(x) = x7−11.55020220220252521355150
f46(x) = (exp(−5x) − x − 0.5)/x50.090.74820225235014151414
f47(x) = 1/sqrt(x) − 2 · log (5 · 103 · sqrt(x)) + 0.80.00050.54815516134918161616
f48(x) = 1/sqrt(x) − 2 · log(5 · 107 · sqrt(x)) + 0.80.00050.5484415132018161914
f49(x) = if (x ≤ 0; −x3x − 1; x1/3x − 1)−1149261291212111212
f50(x) = x3 − 2xx + 3−32504115131614121211
f51(x) = log(x)0.5550281291212101110
f52(x) = (10 − x) · exp(−10x) − x10 + 10.585120238205418171515
f53(x) = exp(sin(x)) − x − 11.04493211111218141313
f54(x) = 2 · sin(x) − 10.1π/3481698121281011
f55(x) = (x − 1) · exp(−x)0.01.549701310124111010
f56(x) = (x − 1)3 − 11.53485713101114111111
f57(x) = exp(x2 + 7x − 30) − 12.63.54720221315014121211
f58(x) = atan(x) − 11.0850261291312101210
f59(x) = exp(x) − 2x − 10.234914716141214131212
f60(x) = exp(−x) − x − sin(x)0.025015981116899
f61(x) = x2 − sin(x)2 − 1−12493313131318111213
f62(x) = sin(x) − x/2π/2π4832108101491010
f63(x) = x · exp(x) − 1−11493012101210101111
f64(x) = tan(x − 1/10)−115040881112998
f65(x) = sin(x) + 0.5−114911981116899
f66(x) = 4x5 + x2 + 1−11493313111516101313
f67(x) = x + x10 − 1−11495013115112121412
f68(x) = πxe−1149151081110899
f69(x) = log(abs(x − 10/9))−1150641391012101010
f70(x) = 1/3 + sign(x) · abs(x)1/3 + x3−11501313111616111217
f71(x) = (x + 2/3)/(x + 101/100)−1149202167511613108
f72(x) = (x · 106 − 1)3−11503335161395150
f73(x) = exp(x) · (x · 106 − 1)3−1150202951145161415150
f74(x) = (x − 1/3)2 · atan(x − 1/3)−11502029311251821425150
f75(x) = sign(3x − 1) · (1 − sqrt(1 − (3x − 1)2/81))−112720228372338662727
f76(x) = if(x > (1 − 106)/106; (1 + 106)/106; −1)−11494937375052495039
f77(x) = if (x ≠ 1/21; 1/(21 x − 1); 0)−11501495955166535150
f78(x) = x2/4 + ceiling(x/2) − 0.5−1150505655504051519
f79(x) = ceiling(10x − 1) + 0.5−11504852524738471514
f80(x) = x + sin(x · 106)/10 + 10−3−11502422222526212525
f81(x) = if (x > −1; 1 + sin(1/(x + 1)); −1)−11495215145140512014
f82(x) = 202x − 2 · floor((2x + 10−2)/(2 · 10−2)) − 0.1−1150333136455
f83(x) = (202x − 2 · floor((2x + 10−2)/(2 · 10−2)) − 0.1)3−1150202737051701255150
f84(x) = (x − 1) · (x − 2) · (x − 3) · (x − 4) · (x − 5) − 0.050.55.54966975320888
f85(x) = sin(x) − 0.5x − 0.3−10.010.0521413114720121211
f86(x) = exp(x) − 1 − xx2/2 − 0.005−2.02.05120219192220161515
f87(x) = 1/(x − 0.5) − 2 − 0.050.62.04813614551161289
f88(x) = log(x) − x + 2 − 0.050.13.0502913111716131414
f89(x) = sin(20x) + 0.1 x − 0.1−4.05.0511717151720171613
f90(x) = x3 − 2x2 + x − 0.025−1.02.05117513135218151313
f91(x) = x · sin(1/x) − 0.1 − 0.010.011.0491313113914131313
f92(x) = x3 − 0.001−101053202242025528244225
Total number of evaluations 441081322907309527982256288018571741
Average number of evaluations 47.988.431.633.630.424.531.320.218.9
Relative to modAB 2 2.534.671.671.781.611.301.651.071.00
Maximal number of evaluations 5320220220255841425455
Geometric mean 46.352.019.217.523.919.118.315.915.0
Best at (number of functions) 138105265221238
Worst at (number of functions) 38436731101
Median 49.048.513.011.022.016.012.013.012.0
Standard deviation 7.679.041.048.219.020.540.216.015.1
Standard error 0.808.234.275.031.982.134.191.671.58
bsfpillABITPRidBremodAB 1modAB 2
Legend: bs—bisection; Bre—Brent; fp—false-position; Rid—Ridders; ill—Illinois; AB—Anderson–Björck; ITP—Interpolate, Truncate, Project; modAB 1—Modified Anderson–Björck—the original 2022 version; modAB 2—Modified Anderson–Björck (the proposed version). Note: The best algorithm for each function is highlighted.
Table 3. Total execution times * for all functions in us (microseconds).
Table 3. Total execution times * for all functions in us (microseconds).
AlgorithmMeanErrorStdDevRelative
Bisection86.57 us0.832 us0.738 us1.75
FalsePosition321.77 us3.561 us2.974 us6.51
Illinois104.75 us1.353 us1.265 us2.12
Anderson–Björck122.19 us1.205 us1.127 us2.47
ITP193.37 us1.604 us1.339 us3.92
Ridders66.61 us1.275 us1.309 us1.35
Brent119.56 us1.213 us1.134 us2.42
modAB 151.58 us1.013 us1.352 us1.04
modAB 249.39 us0.323 us0.269 us1.00
* BenchmarkDotNet v0.15.8, .NET 10.0.5 x64 RyuJIT x86-64-v4; Windows 11 (10.0.26200.8037/25H2/2025Update/HudsonValley2); Intel Core i7-1065G7 CPU 1.30 GHz eight logical and four physical cores + 16 GB RAM; 1 the original version; 2 the proposed version.
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content.

Share and Cite

MDPI and ACS Style

Ganchovski, N.; Smith, O.; Rackauckas, C.; Tomov, L.; Traykov, A. Improvements to the Modified Anderson–Björck (modAB) Root-Finding Algorithm. Algorithms 2026, 19, 332. https://doi.org/10.3390/a19050332

AMA Style

Ganchovski N, Smith O, Rackauckas C, Tomov L, Traykov A. Improvements to the Modified Anderson–Björck (modAB) Root-Finding Algorithm. Algorithms. 2026; 19(5):332. https://doi.org/10.3390/a19050332

Chicago/Turabian Style

Ganchovski, Nedelcho, Oscar Smith, Christopher Rackauckas, Lachezar Tomov, and Alexander Traykov. 2026. "Improvements to the Modified Anderson–Björck (modAB) Root-Finding Algorithm" Algorithms 19, no. 5: 332. https://doi.org/10.3390/a19050332

APA Style

Ganchovski, N., Smith, O., Rackauckas, C., Tomov, L., & Traykov, A. (2026). Improvements to the Modified Anderson–Björck (modAB) Root-Finding Algorithm. Algorithms, 19(5), 332. https://doi.org/10.3390/a19050332

Note that from the first issue of 2016, this journal uses article numbers instead of page numbers. See further details here.

Article Metrics

Back to TopTop