From d28a77a63d4ad1c4410e900f4bf9147d06cc34f8 Mon Sep 17 00:00:00 2001 From: John Dyreby Date: Sat, 28 Feb 2026 12:47:36 -0600 Subject: [PATCH 1/2] Clean up AGENTS.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add twine-observers crate - Replace stale pseudocode with accurate prose covering all three problem types - Simplify Observer section to one line covering closures and () - Drop Solution field list and module file inventory — these vary per solver and are trivially read from source - Drop solver function signature — was already wrong for Euler Closes #267 --- AGENTS.md | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f86034e..1ca870b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,44 +6,28 @@ Rust framework for numerical problem solving. See README.md for usage examples. - **twine-core** (`crates/core`): Shared traits and types - **twine-solvers** (`crates/solvers`): Solver implementations, organized by problem type +- **twine-observers** (`crates/observers`): Reusable `Observer` implementations ## Core Abstraction -``` -Model::call(input) -> output -Problem::input(x) -> model_input -Problem::residuals|objective(input, output) -> metric -Solver::solve(model, problem, bracket, config, observer) -> Solution -``` +Three problem types: equation (root-finding), optimization, and ODE. All follow the same pattern: -Solvers are generic over Model and Problem. Problems adapt solver variables (`x: [f64; N]`) -to model inputs and extract metrics from outputs. +- `Model::call(input) -> Result` +- `Problem::input(x) -> model_input` — maps solver variables to model input +- `Problem` extracts a metric from input/output (residuals, objective, or derivative) -## Observer Pattern - -Solvers emit events; observers optionally return actions. +Solvers are generic over `Model` and `Problem`. -```rust -trait Observer { - fn observe(&mut self, event: &Event) -> Option; -} - -impl Observer for () { - fn observe(&mut self, _: &E) -> Option { None } -} -``` +## Observer Pattern -Events expose solver state (current point, bracket, errors). -Actions steer behavior (stop early, assume sign/worse for recovery). +`Observer` is defined in `twine-core`. Closures and `()` both implement it — `()` is the no-op observer. Solvers emit events; observers optionally return actions to steer behavior (stop early, assume worse, etc.). ## Solver Conventions -- Public functions: `solve`/`minimize`/`maximize` with observer, `*_unobserved` without -- Module structure: one file per concern (bracket, config, event, action, solution, error) +- Public API: `solve`/`minimize`/`maximize` (with observer) and `*_unobserved` variants - Config validation at entry, not per-iteration -- `Solution` contains: status, solver variable, objective/residual, snapshot (input+output), iters -## Workflow notes +## Workflow Feature branches may include temporary workflow docs (e.g. TODO.md). Do not merge them to main. From 3cc5c02844b121647664ab313970c9607d47d58d Mon Sep 17 00:00:00 2001 From: John Dyreby Date: Sat, 28 Feb 2026 12:49:19 -0600 Subject: [PATCH 2/2] =?UTF-8?q?Drop=20workflow=20note=20=E2=80=94=20SCRATC?= =?UTF-8?q?HPAD=20is=20gitignored?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1ca870b..27b1baf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,10 +27,6 @@ Solvers are generic over `Model` and `Problem`. - Public API: `solve`/`minimize`/`maximize` (with observer) and `*_unobserved` variants - Config validation at entry, not per-iteration -## Workflow - -Feature branches may include temporary workflow docs (e.g. TODO.md). Do not merge them to main. - ## Testing Use `approx::assert_relative_eq!` for floating point comparisons.