AUTHOR: Piotr Jażdżyk
LINKEDIN: https://www.linkedin.com/in/pjazdzyk
- Overview
- Available Solvers
- Installation
- Quick Start
- Brent-Dekker Solver Guide
- Newton-Raphson Solver Guide
- NaN/Infinity Handling
- Tech Stack
- License
- Reference
Numenor Math is a Java library that groups numerical solvers and mathematical utilities. It provides robust, well-tested implementations of root-finding algorithms for single-variable equations.
The library currently includes two solvers:
| Solver | Type | Requires Bracket | Requires Initial Guess |
|---|---|---|---|
| Brent-Dekker | Bracketing (Bisection + Secant + Inverse Quadratic) | Yes (two points) | No |
| Newton-Raphson | Open (Derivative-based) | No | Yes (single point) |
A Java implementation of the improved Brent-Dekker algorithm based on modifications proposed by Zhengqiu Zhang. Uses a combination of Secant and Bisection numerical schemes with inverse quadratic interpolation. Features a two-phase automatic counterpart points evaluation procedure.
Best for: Functions where you can provide a bracket (two points with opposite signs), robust convergence guaranteed.
A derivative-based root-finding method that uses numerical differentiation for functions where the derivative is not available analytically. Converges quadratically near simple roots when the initial guess is sufficiently close.
Best for: Functions where you have a good initial guess and need fast convergence.
Add Maven dependency to your pom.xml:
<dependency>
<groupId>com.synerset</groupId>
<artifactId>numenor-math</artifactId>
<version>1.0.0</version>
</dependency>import com.synerset.numenormath.solvers.BrentSolver;
import java.util.function.DoubleUnaryOperator;
// Create solver instance
BrentSolver solver = BrentSolver.of("MySolver");
// Define function: 2x + 10 = 0
DoubleUnaryOperator linear = x -> 2 * x + 10;
// Find root with bracket [−50, 50]
double root = solver.findRoot(linear, -50, 50);
// Result: -5.0import com.synerset.numenormath.solvers.NewtonRaphsonSolver;
import java.util.function.DoubleUnaryOperator;
// Create solver instance
NewtonRaphsonSolver solver = NewtonRaphsonSolver.of("MySolver");
// Define function: x² - 4 = 0
DoubleUnaryOperator quadratic = x -> x * x - 4;
// Find root with initial guess
double root = solver.findRoot(quadratic, 3);
// Result: 2.0// Brent-Dekker
double root1 = BrentSolver.findRootOf(x -> 2 * x + 10, -10, 10);
// Newton-Raphson
double root2 = NewtonRaphsonSolver.findRootOf(x -> x * x - 25, 6);// Default instance
BrentSolver solver = BrentSolver.of();
// Named instance (useful for log identification)
BrentSolver solver = BrentSolver.of("MySolver");Any single-variable equation can be provided as a DoubleUnaryOperator:
I. Linear function: 2x + 10 = 0
DoubleUnaryOperator linear = x -> 2 * x + 10;II. Quadratic function: 2x² + 5x - 3 = 0
DoubleUnaryOperator quadratic = x -> 2 * x * x + 5 * x - 3;III. Complex nested function:
DoubleUnaryOperator logNested = x -> 93.3519196629417 -
(-237300 * Math.log(0.001638 * x) / (1000 * Math.log(0.001638 * x) - 17269));The solver requires two counterpart points a and b where f(a) and f(b) have opposite signs. If invalid points are provided, the two-phase evaluation procedure attempts to find valid brackets automatically.
// With function and bracket
double root = solver.findRoot(linear, -50, 50);
// Using default counterpart points (+50/-50)
double root = solver.findRoot(linear);
// Adjusting counterpart points for different roots
solver.setCounterpartPoints(-1, 2);
double root = solver.findRoot(quadratic);solver.setAccuracy(1E-12); // Set convergence tolerance
solver.setIterationsLimit(200); // Maximum iterations
solver.showDebugLogs(true); // Enable diagnostic output
solver.showSummaryLogs(true); // Enable summary logs// Default instance
NewtonRaphsonSolver solver = NewtonRaphsonSolver.of();
// Named instance
NewtonRaphsonSolver solver = NewtonRaphsonSolver.of("MySolver");The Newton-Raphson method requires only a single initial guess:
// Define function: x² - 4 = 0
DoubleUnaryOperator func = x -> x * x - 4;
// Find root starting from x = 3
double root = solver.findRoot(func, 3);
// Result: 2.0
// Find the other root with different initial guess
double root2 = solver.findRoot(func, -3);
// Result: -2.0solver.setAccuracy(1E-12); // Set convergence tolerance
solver.setIterationsLimit(200); // Maximum iterations
solver.setDerivativeStep(1E-8); // Numerical differentiation step
solver.setInitialGuess(5); // Set initial guess separately
solver.showDebugLogs(true); // Enable diagnostic output
solver.showSummaryLogs(true); // Enable summary logs| Advantage | Limitation |
|---|---|
| Faster convergence near simple roots | Requires good initial guess |
| No bracket needed | May diverge for poor guesses |
| Works with single point | Struggles with zero derivatives |
| Quadratic convergence | Can cycle for certain functions |
Both solvers throw BrentSolverException by default when NaN or Infinity values are detected. You can switch to graceful mode:
solver.setFailForNaN(false);
double result = solver.findRoot(someFunction, a, b);
// Returns best approximation found so far instead of throwingsolver.setFailForNaN(false);
double result = solver.findRoot(someFunction, initialGuess);
// Stops gracefully and returns current approximation- Two-phase counterpart evaluation: Added exponential bracket expansion as fallback for Brent-Dekker solver
- Newton-Raphson solver: New derivative-based root-finding method with numerical differentiation
- Near-zero counterpart safeguard: Fixed degenerate results when initial point is close to zero
- Reduced function evaluations: Eliminated redundant function calls in iteration loops
- Expanded test coverage: Comprehensive tests for standard functions, badly behaved functions, engineering equations, and edge cases
This project is licensed under the Apache License 2.0.
- [1] BRENT-DEKKER ITERATIVE SOLVER - Modified algorithm proposed by Zhengqiu Zhang / International Journal of Experimental Algorithms (IJEA), Volume (2) : Issue (1) : 2011
- [2] Press, W.H., Teukolsky, S.A., Vetterling, W.T. & Flannery, B.P. (2007). Numerical Recipes: The Art of Scientific Computing, 3rd Edition, Cambridge University Press. — Section 9.4: Newton-Raphson Method
I extend my heartfelt gratitude to the Silesian University of Technology as it is here that my professional identity was forged, transforming me into an engineer to my very core. Amicus Plato, sed magis amica veritas.