Twine
Twine is a Rust framework for defining and solving numerical problems.
Models are useful for solving problems. Twine ties together your Model, a Problem you want to solve, and a Solver that does the work.
How It Works
Define a model:
use Infallible;
use Model;
/// A simple polynomial: f(x) = x³ - 3x
;
Find where the output equals a target by defining an equation problem:
use Infallible;
use EquationProblem;
use bisection;
/// Drive the model output to a target value.
;
let solution = solve_unobserved.unwrap;
// solution.x = 1.0 (where x³ - 3x = -2)
Find the minimum or maximum by defining an optimization problem with the same model:
use Infallible;
use OptimizationProblem;
/// Define an objective from the model input and output.
/// Solvers choose whether to minimize or maximize.
;
// Use with any optimization solver
// golden_section::minimize(&Polynomial, ObjectiveOutput, [-2.0, 2.0]) → x = 1.0
// golden_section::maximize(&Polynomial, ObjectiveOutput, [-2.0, 2.0]) → x = -1.0
// Same model, same problem, same bracket, just minimize vs maximize
These examples use a simple polynomial, but the same pattern works with any Model, including large, multi-physics engineering systems.
Observers
Solvers are domain-agnostic and know nothing about what your model represents. Observers bridge that gap by receiving events during execution and steering solver behavior based on domain knowledge you provide.
use Observer;
use ;
/// Logs each iteration and stops early when the residual is good enough.
let observer = GoodEnough ;
let solution = solve.unwrap;
// iter 1: residual = 2.500000
// iter 2: residual = -2.750000
// iter 3: residual = -0.484375
// iter 4: residual = 0.785156
// iter 5: residual = 0.097656
// solution.status = StoppedByObserver
GoodEnough is just an example, but notice what makes it work: it's generic over E: HasResidual and A: CanStopEarly, not over bisection specifically. Any observer written against capability traits like these works across all solvers that expose them, not just bisection. The real power shows up in domain-specific observers — for example, an observer that recognizes a thermodynamic constraint violation and tells the solver to search elsewhere, turning an unsolvable problem into a solvable one.
Crates
twine-core: TheModeltrait, Problem traits, and theObservertrait.twine-solvers: Solver algorithms organized by problem type (e.g.,equation::bisection,optimization::golden_section).twine-observers: Capability traits for cross-solver observers (e.g.,HasResidual,CanStopEarly) and visualization tools likePlotObserver.
Twine Models
Twine is domain-agnostic by design. For opinionated, domain-specific models and model-building tools, see the companion project Twine Models.