forge ⚙️
A deterministic metaheuristic optimization substrate in Rust.
forge is to optimization what surtgis-core is to raster data: a shared engine
that several tools in the author's ecosystem consume rather than an application
in itself. Every optimizer speaks one interface — the Problem trait —
minimizes by convention, counts objective evaluations as its budget, rejects
non-finite candidates, and is reproducible for a given seed.
Crate name: published on crates.io as
metalforge(the nameforge-corewas taken); the library is imported asforge_core:[] = { = "0.1", = "metalforge" }use ;
Why not just use argmin / optirustic?
Generic Rust optimization crates exist. forge's value is not to reimplement them but to provide:
- Geoscientific global optimizers the generic libraries omit — DDS and SCE-UA — central to hydrological calibration.
- Certified determinism via one seedable RNG (
Rng, SplitMix64), the same generator used acrossanvil-coreandrainflow-core. - One unified
Problemtrait for the whole ecosystem.
The DDS and SCE-UA implementations are migrated from rainflow-core, where they
were validated against airGR (GR4J calibration NSE 0.7956 vs 0.7957).
Status — v0.2 (audit release)
v0.2.0 is the result of a full fidelity/correctness audit against the source
papers (and, for L-SRTDE, the author's public reference implementation):
exact evaluation budgets everywhere, input validation at every entry point,
NaN-robust adaptive memories, L-SRTDE rebuilt on its true two-population
scheme, CMA-ES boundary handling made consistent (clamped steps feed the
adaptation), SMS-EMOA's paper Reduce rule, NSGA-III's persistent ideal point,
and a golden-value test + CI matrix that turn the "identical with or without
rayon" claim into checked evidence. Additive API changes now bump the minor
version (Algorithm/StopReason/BoundsError are #[non_exhaustive]).
| Component | State |
|---|---|
Problem / bounds / Maximize adapter |
✅ |
Deterministic Rng (SplitMix64) + split streams |
✅ |
| DDS (Tolson & Shoemaker 2007) | ✅ |
| SCE-UA (Duan et al. 1992) | ✅ |
| Differential Evolution (Storn & Price 1997) | ✅ |
| PSO (Kennedy & Eberhart 1995) | ✅ |
| L-SHADE adaptive DE (Tanabe & Fukunaga 2014; CEC-winning lineage) | ✅ |
| L-SRTDE success-rate adaptive DE (Stanovov & Semenkin 2024; CEC 2024 winner) | ✅ |
| CMA-ES (Hansen & Ostermeier 2001) | ✅ |
| NSGA-II multi-objective (Deb et al. 2002) | ✅ |
| NSGA-III reference-point many-objective (Deb & Jain 2014) | ✅ |
| SMS-EMOA hypervolume MOEA, 2-3 objectives (Beume et al. 2007) | ✅ |
Simulated Annealing (combinatorial, via Anneal trait) |
✅ |
| GLUE uncertainty estimation (Beven & Binley 1992) | ✅ |
| IPOP/BIPOP-CMA-ES restarts (Auger & Hansen 2005; Hansen 2009) | ✅ v0.3 |
| PA-DDS multi-objective DDS, HV-contribution selection (Asadzadeh & Tolson 2013) | ✅ v0.3 |
| MOEA/D Tchebycheff decomposition (Zhang & Li 2007) | ✅ v0.3 |
| Constraints: Deb feasibility rules adapter + ε-constrained L-SHADE (Takahama & Sakai) | ✅ v0.3 |
Quality indicators: HV, HV contributions, GD, IGD, GD⁺, IGD⁺ (indicators module) |
✅ v0.3 |
| Test functions (sphere, Rosenbrock, Rastrigin, ZDT1, DTLZ2) | ✅ |
| Convergence + determinism tests | ✅ |
| Contract tests (exact budgets, NaN robustness, input validation) | ✅ |
Golden-value determinism test + CI feature matrix (rayon on/off) |
✅ |
rainflow consumes forge (DDS/SCE-UA) |
✅ |
anvil consumes forge (combinatorial SA, byte-identical) |
✅ |
Uniform Optimizer trait + MultiProblem + Anneal |
✅ |
| Rayon island/ensemble parallelism (deterministic) | ✅ |
Parallel tempering (replica exchange, via Anneal) |
✅ |
Published on crates.io as metalforge |
✅ |
Cross-checked vs pymoo (HV/IGD; see validation/) |
✅ |
COCO/BBOB-style benchmark (fixed-target ERT; see bench/) |
✅ |
| COCO-format data logging (IOHanalyzer-loadable) + MA-BBOB-style affine instances | ✅ v0.3 |
| DREAM_ZS formal Bayesian MCMC (companion to GLUE) | ⬜ v0.4 |
| PyO3 / WASM targets | ⬜ later |
Quick start
use ;
use Sphere;
let problem = new;
let report = default.optimize;
assert!;
Maximization (e.g. NSE/KGE) wraps the problem so the minimizing core stays the single convention:
use ;
use ;
let p = Maximize;
let report = default.optimize;
assert!;
Robust restarts via independent islands — deterministic regardless of
scheduling, and identical with or without the rayon feature:
use ;
use Rastrigin;
let problem = new;
// 8 islands, base seed 42; island i is seeded mix_seed(42, i).
let report = ensemble;
assert!;
Enable the thread pool with --features rayon (off by default to keep the core
dependency-free). The result is byte-identical either way.
Combinatorial problems use simulated annealing through the Anneal trait, which
supports incremental move evaluation (O(touched) per step):
use ;
// Number partitioning: split weights into two groups of equal sum.
let p = Partition ;
let result = Sa
.optimize;
assert!; // perfect partition found
Layout
forge-core— traits, algorithms, deterministic RNG, termination criteria.- (planned) targets: native (Rayon) + Python (PyO3) + CLI runner + WASM demo.
License
MIT OR Apache-2.0.