Numerical Optimization in Rust
Basin is a solver framework with a generic executor loop over pluggable solvers, multiple linear-algebra backends, first-class constraints, and a wasm-first design.
A Small Example
Implement CostFunction and Gradient, then hand your
problem, a solver, and a starting point to the Executor. Here it's gradient
descent on the Rosenbrock valley — drag the sliders, or click the
plot to move the start, and watch the run and the code update
together.
use basin::{BasicState, CostFunction, Executor, Gradient, GradientDescent}; struct Rosenbrock; impl CostFunction for Rosenbrock { type Param = Vec<f64>; type Output = f64; type Error = std::convert::Infallible; fn cost(&self, x: &Vec<f64>) -> Result<f64, std::convert::Infallible> { Ok((1.0 - x[0]).powi(2) + 100.0 * (x[1] - x[0].powi(2)).powi(2)) }} impl Gradient for Rosenbrock { type Gradient = Vec<f64>; fn gradient(&self, x: &Vec<f64>) -> Result<Vec<f64>, std::convert::Infallible> { Ok(vec![ -2.0 * (1.0 - x[0]) - 400.0 * x[0] * (x[1] - x[0].powi(2)), 200.0 * (x[1] - x[0].powi(2)), ]) }} fn main() { let solver = GradientDescent::new(0.001); let state = BasicState::new(vec![-1.2, 1.0]); let result = Executor::new(Rosenbrock, solver, state) .max_iter(500) .run() .unwrap(); println!("x = {:?} (f = {})", result.param(), result.cost());}Run output appears here once the solver runs.Want to see it move? The visualizer animates these trajectories live, compiled to wasm.
What's in the box
Pluggable solvers
Gradient descent, Nelder–Mead, L-BFGS / L-BFGS-B, Gauss–Newton, Levenberg–Marquardt, CMA-ES and more — driven by one shared executor loop.
Multiple backends
Run on plain Vec<f64>, nalgebra, ndarray, or faer. Each backend sits behind a single feature — no per-version feature explosion.
First-class constraints
Box bounds are part of the problem and enforced at the type level: handing a constrained problem to an unconstrained solver is a compile error.
Composable termination
Gradient, parameter, and cost tolerances, iteration and time budgets — configured uniformly across solvers, bound to the state each one exposes.
Runs in the browser
wasm-first by design: the default build pulls in no BLAS/LAPACK or threads, so basin compiles to wasm32 out of the box.
Paper-anchored
Solvers track published algorithms (Nocedal’s L-BFGS-B, Nielsen’s LM damping, Hansen’s CMA-ES) rather than ad-hoc variants.
Compare solvers on classical problems
Benchmarks and head-to-head solver comparisons are on the way. In the meantime, explore the docs or watch solvers converge in the visualizer.