Skip to content

pjazdzyk/numenor-math

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Numenor Math


Numerical solvers and math utilities for Java

AUTHOR: Piotr Jażdżyk
LINKEDIN: https://www.linkedin.com/in/pjazdzyk

Numenor Math Vulnerabilities   Security Rating   Quality Gate Status  


Table of Contents


Overview

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)

Available Solvers

Brent-Dekker Solver

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.

Newton-Raphson Solver

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.


Installation

Add Maven dependency to your pom.xml:

<dependency>
  <groupId>com.synerset</groupId>
  <artifactId>numenor-math</artifactId>
  <version>1.0.0</version>
</dependency>

Quick Start

Using Brent-Dekker Solver (bracketing method)

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.0

Using Newton-Raphson Solver (open method)

import 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

Static one-liner

// Brent-Dekker
double root1 = BrentSolver.findRootOf(x -> 2 * x + 10, -10, 10);

// Newton-Raphson
double root2 = NewtonRaphsonSolver.findRootOf(x -> x * x - 25, 6);

Brent-Dekker Solver Guide

Creating a Solver

// Default instance
BrentSolver solver = BrentSolver.of();

// Named instance (useful for log identification)
BrentSolver solver = BrentSolver.of("MySolver");

Defining Functions

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));

Finding Roots

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);

Configuration

solver.setAccuracy(1E-12);           // Set convergence tolerance
solver.setIterationsLimit(200);      // Maximum iterations
solver.showDebugLogs(true);          // Enable diagnostic output
solver.showSummaryLogs(true);        // Enable summary logs

Newton-Raphson Solver Guide

Creating a Solver

// Default instance
NewtonRaphsonSolver solver = NewtonRaphsonSolver.of();

// Named instance
NewtonRaphsonSolver solver = NewtonRaphsonSolver.of("MySolver");

Finding Roots

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.0

Configuration

solver.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

When to Use Newton-Raphson

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

NaN/Infinity Handling

Both solvers throw BrentSolverException by default when NaN or Infinity values are detected. You can switch to graceful mode:

Brent-Dekker

solver.setFailForNaN(false);
double result = solver.findRoot(someFunction, a, b);
// Returns best approximation found so far instead of throwing

Newton-Raphson

solver.setFailForNaN(false);
double result = solver.findRoot(someFunction, initialGuess);
// Stops gracefully and returns current approximation

What's New in 1.0.0

  • 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

Tech Stack

Core:
Java 21   Maven  

Testing:
JUnit 5  

CI/CD:
GitHub Actions   SonarCloud  


License

This project is licensed under the Apache License 2.0.


Reference

  • [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

Acknowledgments

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.

About

A collection of high performance Java root finding algorithms featuring an enhanced Brent-Dekker solver with automated bracketing and a robust numerical Newton-Raphson implementation.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages