RootForge is a C++ library of classical numerical and mathematical algorithms, built to be dropped into other software as a lightweight, dependency-free computation engine. It also ships with an optional ImGui-based desktop GUI that lets you explore and run every function in the library interactively — no need to write test code to see how a method behaves.
The project is organized as a set of small, focused modules under the
RootForge namespace: general-purpose math helpers, numerical calculus
(differentiation, integration, ODE solving), root-finding, interpolation,
and a full symbolic-ish Polynomial class with FFT-based multiplication.
- Project Idea
- Features at a Glance
- Project Structure
- Requirements
- Building
- The GUI: RootForge Library Explorer
- Library Reference
- Using RootForge as a Library in Your Own Project
- Known Limitations
- Roadmap Ideas
- License
Most small-to-medium C++ projects that need numerical methods end up either pulling in a heavyweight dependency (Eigen, GSL, Boost.Math) or reinventing the same handful of algorithms badly. RootForge aims to sit in between:
- Self-contained — no external math dependency, just the STL.
- Educational and inspectable — every algorithm is implemented from first principles (Newton-Raphson, Simpson's rule, RK4, Lagrange interpolation, etc.) so it's easy to read, learn from, and modify.
- Reusable — organized into clean headers/namespaces so any subset can be copied into another project.
- Interactive — the included GUI turns the whole library into a point-and-click calculator, useful for testing, demos, teaching, or just sanity-checking a method before wiring it into real code.
| Area | What's inside |
|---|---|
| Mathematical Functions | sign, fractional part, custom power, primality/sieve, factorial, roots of unity, Gamma function (exact + Spouge approximation), log-Gamma, binomial coefficients, erf/erfc, Taylor-series exp/sin/cos/ln, simplified square roots |
| Differentiation | forward, backward, centered, second-order centered, and Richardson-extrapolated derivatives |
| Integration | trapezoidal rule, midpoint rule, Simpson's 1/3 rule, Richardson-extrapolated Simpson, 3-point Gaussian quadrature |
| Root Finding | Newton's method for nth roots, Bisection, Newton-Raphson, Secant, Regula Falsi |
| Interpolation | linear interpolation, numerical (Lagrange-form) polynomial interpolation, explicit Lagrange polynomial construction |
| ODE Solvers | Euler's method, RK4, explicit Midpoint method, RK2 (Heun's), and a vector/system RK4 solver for coupled first-order ODEs |
| Polynomial | evaluation (real & complex), addition, subtraction, scalar multiplication, long division, FFT-based multiplication, differentiation, integration, numerical derivative/integral, deflation-based root finding (Newton-Horner), and the quadratic formula |
| GUI | A full ImGui desktop app — "RootForge Library Explorer" — that exposes nearly every function above through menus and input fields |
RootForge/
├── CMakeLists.txt # Build configuration (fetches GLFW, links OpenGL + ImGui)
├── RootForge.h # Umbrella header (includes every module)
├── RootForgeCore.h # Shared types: Function, DFunction, NFunction, Status, NumericalResult
├── MathematicalFunctions.h/.cpp# General-purpose math utilities
├── NumericalAnalysis.h/.cpp # Differentiation, Integration, Root, Interpolation, ODE namespaces
├── Polynomial.h/.cpp # Polynomial class
├── NumberTheory.h # (referenced by RootForge.h — add your own implementation)
├── GUI_Test.cpp # Entry point for the ImGui "Library Explorer" application
└── imgui/ # Dear ImGui sources + GLFW/OpenGL3 backends (not vendored here — see Requirements)
Note:
RootForge.hincludesNumberTheory.h, which isn't part of this snapshot of the project. If you're only using the computation modules (not the umbrella header), include the specific headers you need instead (RootForgeCore.h,MathematicalFunctions.h,NumericalAnalysis.h,Polynomial.h) to avoid that dependency.
To build the GUI application:
- CMake 3.14+
- A C++14-capable compiler
- OpenGL (provided by your OS)
- GLFW — fetched automatically by
CMakeLists.txtviaFetchContent - Dear ImGui — not fetched automatically; place the
imguifolder (includingbackends/imgui_impl_glfw.cppandbackends/imgui_impl_opengl3.cpp) at the project root before building
To use the math library alone (no GUI): just a C++14 compiler and the STL — no third-party dependencies at all.
# 1. Clone Dear ImGui into the project root (one-time setup)
git clone https://github.com/ocornut/imgui.git
# 2. Configure and build
mkdir build && cd build
cmake ..
cmake --build .
# 3. Run
./RootForgeCMake will fetch and build GLFW automatically the first time you configure.
GUI_Test.cpp builds a single-window desktop app with a simple, repeatable
workflow:
- Pick a Library from the first dropdown — Mathematical Functions, Differentiation, Integration, Root Finding, Interpolation, ODE Solvers, or Polynomial.
- Pick a Function from the second dropdown — options update automatically based on the chosen library.
- Fill in the inputs that appear for that specific function (numbers,
or comma-separated lists for vector inputs like
1, 2, 3). - Press Calculate — the result appears immediately below, and is also appended to a scrollable History panel so you can compare runs.
- Repeat as many times as you like, switching libraries/functions freely.
On functions that need a callable f(x) or dy/dx = f(x, y): the
library itself has no expression parser, so instead of free-text math
input, the GUI offers a small dropdown of predefined test functions for
Differentiation, Integration, and Root Finding (e.g. x² - 4, sin(x),
eˣ - 2, x³ - x - 2), and predefined dy/dx forms for the ODE solvers
(e.g. dy/dx = y, dy/dx = x + y). SystemRK4 runs a fixed illustrative
2-equation system (a simple harmonic oscillator: y₀' = y₁, y₁' = -y₀).
Some functions (taylorExp, taylorSin, taylorCos, taylorLn,
NewtonMethod) also print a detailed iteration/error report to the
console via NumericalResult::ShowResult, in addition to the value shown
in the GUI.
using Function = std::function<double(double)>; // f(x)
using DFunction = std::function<double(double, double)>; // f(x, y)
using NFunction = std::function<double(double, vector<double>)>; // f(x, y-vector)
enum class Status { Success, InvalidInput, DivisionByZero, MaxIterations, NotConverged };
struct NumericalResult {
double value, absError, relativeError, percentError;
std::size_t iterations;
Status status;
static void ShowResult(const NumericalResult result); // prints a formatted report
};Namespace: RootForge::MathematicalFunctions
| Function | Signature | Notes |
|---|---|---|
sgn |
int sgn(double x) |
-1, 0, or 1 |
FractionalPart |
double FractionalPart(double x) |
x - floor(x) |
power |
double power(double a, double n) |
Fast exponentiation by squaring for integer n; falls back to exp(n·ln(a)) for fractional n |
is_integer |
bool is_integer(double num) |
|
sieve_of_eratosthenes |
vector<int> sieve_of_eratosthenes(int n) |
Returns all primes ≤ n |
factorial |
long double factorial(long n) |
Computed via prime-factorization for large-n stability |
nthRoot |
vector<complex<double>> nthRoot(int n, bool invert = false) |
The n-th roots of unity |
Gamma |
double Gamma(double n) |
Exact for integers/half-integers, NAN otherwise |
SpougeGamma |
double SpougeGamma(double n) |
Spouge's approximation, works for general real n |
LogGamma |
double LogGamma(double n) |
log(Gamma(n)) |
BinomialCoeff |
long BinomialCoeff(long n, long k) |
|
erf / erfc |
double erf(double x) / double erfc(double x) |
Numerically integrated via Simpson's rule |
taylorExp / taylorSin / taylorCos / taylorLn |
double taylorX(double a, double x) |
Taylor-series evaluation with a built-in error report |
simplify_sqrt |
string simplify_sqrt(int n) |
Simplifies √n into a√b form |
isPrime |
bool isPrime(int n) |
Namespace: RootForge::Differentiation
forwardDifference(f, x, h)backwardDifference(f, x, h)centeredDifference(f, x, h)D2centeredDifference(f, x, h)— second derivativeRichardsonExtrapolationDiff(f, x, h)— 4th-order accurate via Richardson extrapolation of the centered difference
Namespace: RootForge::Integration
trapezoidal(f, start, end, n)midpoint(f, start, end, n)simpsons_13(f, start, end, n)— requires an evennRichardsonExtrapolationInt(f, start, end, n)— Richardson-extrapolated Simpson's ruleGaussianQuadrature(f, a, b)— 3-point Gauss-Legendre quadrature
Namespace: RootForge::Root
NewtonMethod(num, n)— computes the n-th root ofnumBisection(f, start, end)— requires a sign change over[start, end]NewtonRaphson(f)— starts fromx = 1, uses the centered difference as the derivativeSecant(f)— automatically searches[-100, 100]for a bracketing sign changeRegulaFalsi(f)— same automatic bracketing asSecant
Namespace: RootForge::Interpolation
LinearInterpolation(x1, y1, x2, y2, x_i)NumericalPolyInterpolation(x_axis, y_axis, x)— evaluates the Lagrange interpolant at a point without building it explicitlyLagrangePolyInterpolation(x_axis, y_axis)— returns the explicit interpolating polynomial's coefficients
Namespace: RootForge::ODE
EulerMethod(f, x0, y0, h, target)RK4(f, x0, y0, h, target)— classic 4th-order Runge-KuttaMidpoint(f, x0, y0, h, target)— explicit midpoint methodRK2(f, x0, y0, h, target)— Heun's methodSystemRK4(functions, x0, y, h, target)— RK4 for a system of coupled first-order ODEs, whereyis the initial state vector andfunctions[i]computesdy_i/dx
Class: Polynomial (top-level, not inside RootForge)
Coefficients are stored low-to-high degree: coeffs[0] is the constant
term, coeffs[coeffs.size()-1] is the leading coefficient.
| Method | What it does |
|---|---|
Polynomial(coefficients) |
Constructs from a coefficient vector; also builds a callable RootForge::Function |
degree() |
coeffs.size() - 1 |
evaluate(x) / evaluate(complex<double> x) |
Horner's method evaluation, real or complex |
add(p1, p2) |
Static; polynomial addition |
negate(p1, p2) |
Static; computes p1 - p2 |
ScalarProd(p, x) |
Static; scales all coefficients by x |
divide(p1, p2) |
Static; returns {quotient, remainder} |
multiply(p1, p2) |
Static; FFT-based multiplication using nthRoot |
NewtonHorner(p) |
Static; finds all real roots by repeated Newton-Raphson + deflation |
Differentiate(p) |
Static; term-by-term derivative |
Integrate(p) |
Static; term-by-term antiderivative (constant of integration = 0) |
NumericalDiff(x) |
Centered-difference derivative at x |
NumericalInt(x_start, x_end) |
Simpson's-rule definite integral |
quadratic_formula(a, b, c) |
Static; prints the real or complex roots of ax² + bx + c to the console |
You don't need the GUI to use RootForge — the computational modules have no dependency on ImGui/GLFW/OpenGL at all. To embed it in another project:
#include "RootForgeCore.h"
#include "MathematicalFunctions.h"
#include "NumericalAnalysis.h"
#include "Polynomial.h"
int main() {
// Root-find sin(x) = 0 near x = 3
double root = RootForge::Root::Bisection([](double x){ return sin(x); }, 3.0, 4.0);
// Integrate x^2 from 0 to 1
double area = RootForge::Integration::simpsons_13(
[](double x){ return x * x; }, 0.0, 1.0, 100);
// Work with a polynomial: 3x^2 + 2x - 5
Polynomial p({-5, 2, 3});
double y = p.evaluate(2.0);
}Add the corresponding .cpp files to your build (MathematicalFunctions.cpp,
NumericalAnalysis.cpp, Polynomial.cpp) and you're set — no GUI-related
sources or dependencies required.
NumberTheory.h, referenced by the umbrellaRootForge.hand byCMakeLists.txt, is not implemented in this snapshot — include the specific headers you need instead ofRootForge.hif you hit a missing header error.MathematicalFunctions::FFTis declared in the header but has no implementation yet.- Several root-finding and ODE routines (
Secant,RegulaFalsi,NewtonRaphson) don't take convergence/iteration caps, so a poorly chosen test function can loop for a long time or diverge. Gamma()only returns exact results for integer and half-integer arguments; useSpougeGamma()for a general real-valued approximation.- The GUI's differentiation/integration/root-finding tools use a fixed set of predefined test functions rather than a free-form expression parser.
- Implement
NumberTheory.handFFTto complete the umbrella header. - Add a lightweight expression parser so the GUI can accept arbitrary
f(x)input instead of a preset list. - Add convergence/iteration limits and
Status/NumericalResultreturns consistently across all root-finding and ODE methods. - Add unit tests (e.g. with Catch2 or GoogleTest) for each module.
This project is licensed under the MIT License.
See the LICENSE file for details.