{"slug": "show-hn-incremental-delta-bar-delta-sutton-s-1992-rule-in-rust", "title": "Show HN: Incremental Delta-Bar-Delta (Sutton's 1992 Rule) in Rust", "summary": "A Rust crate called idbd implements Incremental Delta-Bar-Delta, the per-input learning-rate rule Sutton published in 1992, alongside Autostep (Mahmood et al., 2012) as allocation-free online learners with no dependencies and no unsafe code, requiring Rust 1.85 or newer. In the browser demo's guessing game, a tuned fixed step on rescaled readings scored 89% to IDBD's 85% over ten runs, and the author states the reading scales are where IDBD's edge comes from and that a fixed speed on rescaled readings does as well. The repository ships the library, an unpublished lab crate reproducing the paper's two experiments with recorded seeds, a wasm-bindgen adapter, and a behavior specification of 63 scenarios in 13 rules.", "body_md": "IDBD (Sutton, 1992) is the LMS rule with one learning rate per input. It keeps\n`beta_i = ln(alpha_i)` for every input and moves it by gradient descent on the squared error,\nso an input whose corrections keep pointing the same way gets a larger step and an input whose\ncorrections cancel out gets a smaller one. No input is marked as relevant in advance.\n\n<sub>One run of the story page's guessing game. A tuned fixed step on rescaled readings scores 89% to IDBD's 85% over ten runs, see [Results](#results).</sub>\n\nThis repository has three parts:\n\n- `idbd` , the crate: IDBD and Autostep (Mahmood et al., 2012) as checked, atomic,\nallocation-free online learners. No dependencies, no`unsafe` , Rust 1.85 or newer.\n- `idbd-lab` : an approximate reproduction of the paper's two experiments, plus new tasks, with\nevery result below produced from recorded seeds.\n- A browser demo that runs the same Rust through WebAssembly: a story page for people who have never trained a model, and an Explorer for those who have.\n\n| Path | Contents | \n|---|---|\n| [`crates/idbd`](https://github.com/minikin/idbd/blob/main/crates/idbd) | The library. | \n| [`crates/idbd-lab`](https://github.com/minikin/idbd/blob/main/crates/idbd-lab) | Unpublished. Seeded tasks, an LMS baseline, experiment and benchmark binaries. | \n| [`crates/idbd-wasm`](https://github.com/minikin/idbd/blob/main/crates/idbd-wasm) | Unpublished. The `wasm-bindgen` adapter used by the demo. | \n| [`web`](https://github.com/minikin/idbd/blob/main/web) | The story page and the Explorer, static, with Playwright tests. | \n| [`docs`](https://github.com/minikin/idbd/blob/main/docs) | Reproduction instructions, generated results and benchmarks. | \n| [`features/idbd.feature`](https://github.com/minikin/idbd/blob/main/features/idbd.feature) | The behavior specification: 63 scenarios in 13 rules. | \n\n```\n[dependencies]\nidbd = \"0.1\"\nphp\nuse idbd::{Config, Idbd};\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    // Initial step size 0.05, meta step size theta 0.01.\n    let mut learner = Idbd::new(3, Config::new(0.05, 0.01)?)?;\n    let report = learner.update(&[0.5, -1.0, 1.0], 2.0)?;\n    println!(\"error before learning: {}\", report.error);\n    Ok(())\n}\n```\n\n`update` predicts, measures the error, adapts the step sizes and then the weights, in Sutton's\norder. A failed update returns a typed error and leaves the learner bit for bit as it was. The\nlearning path does not allocate.\n\n[`examples/latency.rs`](https://github.com/minikin/idbd/blob/main/crates/idbd/examples/latency.rs) is a complete streaming application:\ninput and target scaling, predicting before learning, skipping an invalid sample, and\ncheckpointing the learner with its stream position. Run it with\n`cargo run -p idbd --example latency`. The [crate README](https://github.com/minikin/idbd/blob/main/crates/idbd/README.md) covers the\nupdate equations, configuration, bounds, checkpoints, when to use IDBD and its limitations.\n\nThe story page explains IDBD with Family Assistant, a home with twelve sensors and a power meter. Four of the sensors add to the meter, each during its own hours of the day, and the sensors read on different scales. The page shows the live readings, plots one fixed learning speed that is late on small readings and nervous on large ones, walks through one update in slow motion, and then lets you play: you mark the hours in which you think each sensor adds to the meter, and IDBD and a tuned fixed-speed learner watch three simulated days and draw their own answer. Every learning value on the page comes from the crate. The reading scales are where IDBD's edge comes from. The page says so, and that a fixed speed on rescaled readings does as well.\n\nThe Explorer runs IDBD, LMS and untuned Autostep side by side on Sutton's 20-input task, with replay, export and a guided single update.\n\n```\njust web-serve   # build, then serve the story at http://127.0.0.1:8173 and /explorer.html\n```\n\nEvery number below was produced by the binaries in `crates/idbd-lab` with recorded seeds. The\npaper's random draws are unpublished, so these are approximate replications. Each results page\nlists the protocol differences.\n\n**Experiment 1 (Figure 3).** 20 inputs, 5 relevant, one sign flip every 20 samples, 20,000\nwarm-up and 10,000 measured samples, 20 seeds, no bounds. Mean squared error with one standard\nerror:\n\n| Learner | Best parameter in our grid | MSE | Sutton (1992) | \n|---|---|---|---|\n| LMS | alpha 0.03 | 3.402 +/- 0.017 | about 3.5 | \n| IDBD, initial alpha 0.05 | theta 0.015 | 1.525 +/- 0.007 | about 1.5 | \n\nAt theta 0.02, 5 of 20 IDBD runs failed with a step-size overflow. LMS at alpha 0.09 reached an\nMSE of 129.7, off the plot, and diverged at alpha 0.1.\n[Details and plot](https://github.com/minikin/idbd/blob/main/docs/results/sutton1992-experiment1/README.md).\n\n**Experiment 2 (Figures 4 and 5).** theta 0.001, 250,000 samples, 5 seeds. The relevant inputs'\nstep sizes end at 0.129 on average (paper: 0.13 +/- 0.015). The irrelevant inputs end between\n0.00726 and 0.00783, slightly above the paper's \"all below 0.007\". A fixed-rate sweep over the\nrelevant inputs has its minimum at alpha 0.13 to 0.14 (paper: 0.13 +/- 0.01).\n[Details and plots](https://github.com/minikin/idbd/blob/main/docs/results/sutton1992-experiment2/README.md).\n\n**Evaluation against LMS (new tasks).** LMS alpha and IDBD theta were each chosen on tuning\nseeds 1001 to 1005, then evaluated on seeds 1 to 10:\n\n| Task | LMS MSE | IDBD MSE | \n|---|---|---|\n| Sutton 1992 task | 3.422 +/- 0.021 | 1.516 +/- 0.010 | \n| Drifting coefficients (extension) | 0.219 +/- 0.002 | 0.110 +/- 0.001 | \n| Changing relevance (extension) | 3.428 +/- 0.027 | 2.519 +/- 0.024 | \n| Stationary | both below 1e-38 | both below 1e-38 | \n\nThese are noise-free synthetic tasks where a few inputs matter and the relationship changes.\nThey do not show that IDBD beats a tuned LMS in general. [Method and per-seed\nresults](https://github.com/minikin/idbd/blob/main/docs/results/evaluation/README.md).\n\n**Autostep (new tasks, same protocol).** Autostep (Mahmood et al., 2012) at the paper's\ndefault mu = 0.01, with no tuning, against the tuned learners above:\n\n| Task | Autostep, default mu | Autostep, mu tuned | \n|---|---|---|\n| Sutton 1992 task | 2.267 +/- 0.016 | 2.052 +/- 0.027 (mu 0.1) | \n| Drifting coefficients (extension) | 0.185 +/- 0.004 | 0.132 +/- 0.003 (mu 0.1) | \n| Changing relevance (extension) | 4.022 +/- 0.028 | 3.448 +/- 0.032 (mu 0.03) | \n| Stationary | below 1e-30 | below 1e-32 | \n\nOn these tasks untuned Autostep beat tuned LMS on two of three nonstationary tasks and trailed\ntuned IDBD on all of them. At mu = 1, 19 of 20 tuning runs stopped when a step size underflowed\nto zero. [Method, mu sweep and step sizes](https://github.com/minikin/idbd/blob/main/docs/results/autostep/README.md).\n\n**The Family Assistant home (new task).** Twelve sensors on their own reading scales, four of\nwhich add to the power draw during fixed hours of the day, one reading a minute for three days.\nThis is the task behind the story page's game. The score is the overlap of the hours a\nlearner's weights mark with the true hours, pooled over all sensors.\n\n| Learner | Mean squared error | Bar score | Overlap on the 4 sensors that matter | \n|---|---|---|---|\n| LMS, alpha 0.01 (tuned) | 0.514 +/- 0.004 | 0.38 | 0.43 | \n| IDBD, theta 0.07 (tuned) | 0.384 +/- 0.003 | 0.85 | 0.88 | \n| LMS on rescaled readings, alpha 0.03 (tuned) | 0.411 +/- 0.003 | 0.89 | 0.89 | \n\nIDBD found all four sensors on every evaluation seed and marked Wi-Fi data use an hour late.\nThe last row divides every reading by its sensor's scale first, as this README recommends. With\nthe scales evened out, the tuned fixed step draws bars as good as IDBD's, so on this home IDBD's\nedge comes from the different reading scales.\n[Method, sensors and every bar](https://github.com/minikin/idbd/blob/main/docs/results/family/README.md).\n\n**Performance.** On an Apple M4 Max, one IDBD update with 20 features takes about 95 ns and costs\nabout 5 ns per feature up to 10,000 features. A standalone loop of one `exp` call per input takes\n85 to 97% as long as the update, a reference cost, not a measured split. An Autostep update costs\n2.37 to 2.69 times an IDBD update. [Method and full table](https://github.com/minikin/idbd/blob/main/docs/benchmarks.md).\n\n```\ncargo run --release -p idbd-lab --bin sutton1992-exp1   # Experiment 1, about 3 s (see docs/reproduction.md)\ncargo run --release -p idbd-lab --bin sutton1992-exp2   # Experiment 2 and the Figure 5 sweep\ncargo run --release -p idbd-lab --bin evaluate          # IDBD against LMS on four tasks\ncargo run --release -p idbd-lab --bin autostep-eval     # untuned Autostep against both\ncargo run --release -p idbd-lab --bin family-eval       # the Family Assistant home\ncargo run --release -p idbd-lab --bin bench             # core timings\n```\n\nEach binary writes CSV, SVG and Markdown under `docs/results` (or `--out <dir>`). Reruns on the\nsame build and platform reproduce the files byte for byte, except the timings in\n`docs/benchmarks.md`. [docs/reproduction.md](https://github.com/minikin/idbd/blob/main/docs/reproduction.md)\nlists the generator, seeds, grids and sign-flip timing.\n\n```\njust web-setup   # once: install Playwright with Chromium, Firefox and WebKit\njust web-test    # rebuild, then run the Playwright tests in all three browsers\njust readme-assets   # re-render the README images from the demo\n```\n\nThe build needs the `wasm32-unknown-unknown` target, `wasm-bindgen-cli` 0.2.113 (the version\npinned in `crates/idbd-wasm`) and Node.js. The house is drawn with three.js 0.170.0, pinned in\n`web/package.json`, and in 2D when WebGL is missing or the visitor prefers reduced motion. The\nsite is static: after `just web-build`, any file server that sends `.wasm` as\n`application/wasm` can host `web/`.\n\n`just web-site` copies only `index.html`, `explorer.html`, `styles.css`, `src/`, `story/`,\nthree.js from `vendor/` and the two files the pages load from `pkg/` into `_site/`.\n`just web-deploy` deploys `_site/` to Cloudflare as the assets-only Worker in `wrangler.jsonc`,\nafter `wrangler login` or with `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` set. The `Demo`\nworkflow does the same on any manual run, and on every push to `main` once the repository\nvariable `DEPLOY_DEMO` is `true`. It needs both values as repository secrets.\n\nRichard S. Sutton. *Adapting Bias by Gradient Descent: An Incremental Version of\nDelta-Bar-Delta.* In Proceedings of the Tenth National Conference on Artificial Intelligence\n(AAAI-92), pages 171-176, 1992. [https://cdn.aaai.org/AAAI/1992/AAAI92-027.pdf](https://cdn.aaai.org/AAAI/1992/AAAI92-027.pdf)\n\nLicensed under either the [Apache License, Version 2.0](https://github.com/minikin/idbd/blob/main/LICENSE-APACHE) or the\n[MIT license](https://github.com/minikin/idbd/blob/main/LICENSE-MIT), at your option.", "url": "https://wpnews.pro/news/show-hn-incremental-delta-bar-delta-sutton-s-1992-rule-in-rust", "canonical_source": "https://github.com/minikin/idbd", "published_at": "2026-11-10 20:08:54+00:00", "updated_at": "2026-11-10 20:23:26.055300+00:00", "lang": "en", "topics": ["machine-learning", "ai-research", "developer-tools"], "entities": ["idbd", "Incremental Delta-Bar-Delta", "Richard Sutton", "Autostep", "Mahmood et al.", "Rust", "WebAssembly", "wasm-bindgen"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-incremental-delta-bar-delta-sutton-s-1992-rule-in-rust", "markdown": "https://wpnews.pro/news/show-hn-incremental-delta-bar-delta-sutton-s-1992-rule-in-rust.md", "text": "https://wpnews.pro/news/show-hn-incremental-delta-bar-delta-sutton-s-1992-rule-in-rust.txt", "jsonld": "https://wpnews.pro/news/show-hn-incremental-delta-bar-delta-sutton-s-1992-rule-in-rust.jsonld"}}