metalforge 0.3.0

forge: a deterministic metaheuristic optimization substrate in Rust. Unified Problem/MultiProblem/Anneal traits; DDS, SCE-UA, DE, L-SHADE, L-SRTDE, PSO, CMA-ES, NSGA-II/III, SMS-EMOA, simulated annealing, parallel tempering and GLUE uncertainty; reproducible by seed; optional Rayon parallelism.
Documentation
//! # forge-core
//!
//! 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 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** (the portfolio's
//! certified-determinism seal).
//!
//! ## What sets it apart
//!
//! Generic Rust optimization crates exist (`argmin`, `optirustic`). forge's
//! value is not to reimplement them but to provide:
//!
//! 1. **Geoscientific global optimizers** the generic libraries omit — **DDS**
//!    and **SCE-UA** — central to hydrological calibration.
//! 2. **Certified determinism** via one seedable RNG ([`Rng`]).
//! 3. **One unified [`Problem`] trait** 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).
//!
//! ## Quick start
//!
//! ```
//! use forge_core::{Dds, Optimizer, Termination};
//! use forge_core::testfn::Sphere;
//!
//! let problem = Sphere::new(5);
//! let report = Dds::default().optimize(&problem, &Termination::budget(2000));
//! assert!(report.best_value() < 1e-2);
//! ```
//!
//! Maximization (e.g. NSE/KGE in rainflow) wraps the problem so the minimizing
//! core stays the single convention:
//!
//! ```
//! use forge_core::{Optimizer, Sce, Termination};
//! use forge_core::problem::{func, Maximize};
//!
//! // Maximize a concave bump peaking at x = 2.
//! let p = Maximize(func(vec![(-10.0, 10.0)], |x| -(x[0] - 2.0).powi(2)));
//! let report = Sce::default().optimize(&p, &Termination::budget(3000));
//! assert!((report.best()[0] - 2.0).abs() < 0.1);
//! assert!(report.best_value_maximized() > -1e-2);
//! ```
//!
//! Robust restarts via independent islands (deterministic with or without the
//! `rayon` feature):
//!
//! ```
//! use forge_core::{ensemble, De, Termination};
//! use forge_core::testfn::Rastrigin;
//!
//! let problem = Rastrigin::new(3);
//! let report = ensemble(&De::default(), &problem, &Termination::budget(5000), 8, 42);
//! assert!(report.best_value() < 1.0);
//! ```
//!
//! Multi-objective optimization with NSGA-II returns a Pareto front:
//!
//! ```
//! use forge_core::{NsgaII, Termination};
//! use forge_core::problem::multi_func;
//!
//! // Schaffer N.1: minimize x² and (x−2)²; Pareto-optimal x ∈ [0, 2].
//! let sch = multi_func(vec![(-5.0, 5.0)], 2, |x| vec![x[0] * x[0], (x[0] - 2.0).powi(2)]);
//! let front = NsgaII::default().optimize(&sch, &Termination::budget(6000));
//! assert!(!front.is_empty());
//! ```

pub mod algo;
pub mod constraint;
pub mod indicators;
pub mod problem;
pub mod rng;
pub mod solution;
pub mod termination;
pub mod testfn;

pub use algo::{
    ensemble, Algorithm, Anneal, Behavioral, CmaEs, Dds, De, EpsilonLShade, Glue, GlueResult,
    GlueSample, LShade, LSrtde, Moead, NsgaII, NsgaIII, Optimizer, Padds, PaddsSelection,
    ParallelTempering, Pso, Restart, RestartCmaEs, Sa, SaResult, Sce, Schedule, SmsEmoa,
    TemperingResult,
};
pub use problem::{
    func, multi_func, validate, validate_multi, BoundsError, Maximize, MultiProblem, Problem,
};
pub use rng::Rng;
pub use solution::{MultiSolution, ParetoFront, Report, Solution, StopReason};
pub use termination::Termination;