{ "cells": [ { "cell_type": "markdown", "id": "b4ba420e", "metadata": {}, "source": [ "# `spsa-sumo` — SPSA calibration against a production simulator (Balakrishna 2007)\n", "\n", "**What.** `spsa-sumo` is the T2 (`ADR-002`) estimation track's first GUARDED\n", "estimator: Spall's (1992) simultaneous-perturbation stochastic approximation\n", "(`[spall1992multivariate]`), but with its inner assignment ORACLE swapped for\n", "a real production simulator — the shipped `sumo-marouter` adapter (adr-027) —\n", "instead of the repo's in-process MSA/AON oracle. This is Balakrishna,\n", "Ben-Akiva & Koutsopoulos' (2007) black-box simulator-in-the-loop calibration\n", "paradigm (`[balakrishna2007offline]`,\n", "[docs/REFERENCES.md](../../docs/REFERENCES.md)), made real: SPSA descends the\n", "link-count misfit under `marouter`'s own hardcoded cost law, two simulator\n", "runs per iteration.\n", "\n", "**Why it is in the benchmark.** T2's whole thesis is that ANY OD-emitting\n", "method — a 1980 balancing loop, a GLS solve, a simulator-in-the-loop\n", "calibration — is scored by the SAME unchanged pinned-`bfw` certifier\n", "(ADR-002 Decision 2). This row proves the thesis costs nothing extra: **zero**\n", "changes to the task, runner, or certifier were needed to plug a real\n", "subprocess engine in as the black box. See\n", "[docs/design/adr-028-spsa-sumo.md](../../docs/design/adr-028-spsa-sumo.md) for\n", "the full derivation (demand-ONLY scope; the joint demand+supply contribution\n", "is honestly NOT shipped) and every measured anchor.\n", "\n", "**Scope.** The `sp_calls=0` disclosure (never fabricated) and the\n", "`sp_calls`-only budget refusal it forces, a certified recovery anchor through\n", "the UNCHANGED pinned-`bfw` certifier, and the box-projection lesson (a REAL\n", "adversarial-review finding: an earlier draft emitted a point different from\n", "the one it certified — P1 broken by an evaluation-time-only clip)." ] }, { "cell_type": "markdown", "id": "19352c4c", "metadata": {}, "source": [ "## How this notebook is graded\n", "\n", "**A notebook never claims a number it does not compute in that cell.** Every\n", "scored quantity below — `od_feasible`, `certificate_gap`, `obs_count_rmse`,\n", "`od_rmse` — comes from the SAME `ODCertifier` every other T2 estimator here\n", "is scored by, re-assigning the emitted OD through its own pinned `bfw`\n", "reference, never from `spsa-sumo`'s self-report\n", "([README](../../README.md), *Certified, not self-reported*)." ] }, { "cell_type": "code", "execution_count": 1, "id": "b2450e80", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:55:56.348196Z", "iopub.status.busy": "2026-07-21T13:55:56.347855Z", "iopub.status.idle": "2026-07-21T13:55:58.485761Z", "shell.execute_reply": "2026-07-21T13:55:58.484527Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "paradigm : estimation\n", "deterministic : False (seeded, macroreplicated)\n", "seedable : True\n", "provides_gap : False\n" ] } ], "source": [ "# Setup. `spsa-sumo`'s inner oracle is `sumo-marouter`, so it needs the\n", "# optional `sumo` extra (`pip install tabench[sumo]`) -- guarded exactly like\n", "# `src/tabench/models/__init__.py`, the FIRST guarded T2 estimator\n", "# (`estimation/__init__.py`).\n", "#\n", "# The inline backend is Agg-based: figures render headlessly into the\n", "# notebook, so CI can execute tutorials without a display. NEVER\n", "# matplotlib.use(\"Agg\") in-kernel -- it silently suppresses inline capture.\n", "%matplotlib inline\n", "try:\n", " import sumo # noqa: F401 (the eclipse-sumo wheel; absence -> ModuleNotFoundError)\n", "except ModuleNotFoundError as exc:\n", " if exc.name != \"sumo\":\n", " raise\n", " raise ModuleNotFoundError(\n", " \"spsa-sumo needs the optional 'sumo' extra: pip install tabench[sumo]\"\n", " ) from exc\n", "\n", "from tabench import Budget, PriorBaseline, run_estimation_experiment, two_route_scenario, viz\n", "from tabench.estimation import ESTIMATOR_REGISTRY, SumoSPSAEstimator\n", "\n", "assert \"spsa-sumo\" in ESTIMATOR_REGISTRY\n", "caps = SumoSPSAEstimator.capabilities\n", "print(f\"paradigm : {caps.paradigm}\")\n", "print(f\"deterministic : {caps.deterministic} (seeded, macroreplicated)\")\n", "print(f\"seedable : {caps.seedable}\")\n", "print(f\"provides_gap : {caps.provides_gap}\")" ] }, { "cell_type": "markdown", "id": "dc33f4a1", "metadata": {}, "source": [ "## The `sp_calls=0` disclosure, and the fabricated-`sp_calls` trap it prevents\n", "\n", "`marouter` exposes no shortest-path (Dijkstra) count. The tempting shortcut —\n", "charging `2 * k_inner` per SPSA iteration as a stand-in `sp_calls`, since\n", "each iteration runs two inner solves — would FABRICATE a hardware-free work\n", "unit the engine never actually reports. `spsa-sumo` instead discloses\n", "`sp_calls = 0` on every checkpoint, and refuses an `sp_calls`-only budget up\n", "front (it cannot bound a loop on an axis the oracle does not expose) rather\n", "than silently ignoring it." ] }, { "cell_type": "code", "execution_count": 2, "id": "ea1c8edb", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:55:58.490708Z", "iopub.status.busy": "2026-07-21T13:55:58.490403Z", "iopub.status.idle": "2026-07-21T13:56:01.112708Z", "shell.execute_reply": "2026-07-21T13:56:01.111761Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "checkpoints : 5, all sp_calls==0 : True\n", "sp_calls-only budget refused : spsa-sumo cannot honor an sp_calls-only budget (its marouter oracle exposes no …\n" ] } ], "source": [ "_RECOVERY_EST = {\n", " \"sensors\": {\"kind\": \"explicit\", \"links\": [0, 2]},\n", " \"heldout\": {\"kind\": \"explicit\", \"links\": [1, 3]},\n", " \"noise\": \"none\",\n", " \"n_periods\": 3,\n", " \"prior\": {\"kind\": \"stale\", \"cv\": 0.3},\n", "}\n", "scenario = two_route_scenario(sue_theta=None)\n", "\n", "res_disclosure = run_estimation_experiment(\n", " scenario, [SumoSPSAEstimator(iters=5)], Budget(iterations=1000),\n", " seed=13, macroreps=1, estimation=_RECOVERY_EST,\n", ")\n", "sp_rows = [r for r in res_disclosure.rows if r[\"estimator\"] == \"spsa-sumo\"]\n", "print(f\"checkpoints : {len(sp_rows)}, all sp_calls==0 : {all(r['sp_calls'] == 0 for r in sp_rows)}\")\n", "assert all(r[\"sp_calls\"] == 0 for r in sp_rows)\n", "\n", "try:\n", " run_estimation_experiment(\n", " scenario, [SumoSPSAEstimator(iters=3)], Budget(sp_calls=500),\n", " seed=0, macroreps=1, estimation=_RECOVERY_EST,\n", " )\n", " raise AssertionError(\"expected an sp_calls-only budget to be refused\")\n", "except ValueError as exc:\n", " print(f\"sp_calls-only budget refused : {exc}\"[:110] + \"…\")" ] }, { "cell_type": "markdown", "id": "e9cac8d3", "metadata": {}, "source": [ "## The recovery anchor, certified through the UNCHANGED pinned-`bfw` certifier\n", "\n", "Clean counts, a stale prior, on the asymmetric two-route instance (never\n", "Braess in CI — GitHub runners are slower than the dev box). Zero changes to\n", "the task, runner, or certifier were needed for this row: `ODCertifier`\n", "re-assigns the emitted OD through its OWN pinned `bfw` reference regardless\n", "of which black box produced it — the whole point of T2." ] }, { "cell_type": "code", "execution_count": 3, "id": "24af77fe", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:56:01.115766Z", "iopub.status.busy": "2026-07-21T13:56:01.115411Z", "iopub.status.idle": "2026-07-21T13:56:11.259755Z", "shell.execute_reply": "2026-07-21T13:56:11.258697Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "certified od_feasible : 1\n", "certificate_converged : 1\n", "certificate_gap : 0.00e+00\n", "obs_count_rmse spsa-sumo/prior : 0.0665 / 0.3509\n", "od_rmse spsa-sumo/prior : 0.0892 / 0.4708\n" ] } ], "source": [ "res = run_estimation_experiment(\n", " scenario, [PriorBaseline(), SumoSPSAEstimator(iters=20)], Budget(iterations=1000),\n", " seed=13, macroreps=1, estimation=_RECOVERY_EST,\n", ")\n", "last = {row[\"estimator\"]: row for row in res.rows}\n", "prior, spsa = last[\"prior\"], last[\"spsa-sumo\"]\n", "\n", "print(f\"certified od_feasible : {spsa['od_feasible']:.0f}\")\n", "print(f\"certificate_converged : {spsa['certificate_converged']:.0f}\")\n", "print(f\"certificate_gap : {float(spsa['certificate_gap']):.2e}\")\n", "print(f\"obs_count_rmse spsa-sumo/prior : {float(spsa['obs_count_rmse']):.4f} / \"\n", " f\"{float(prior['obs_count_rmse']):.4f}\")\n", "print(f\"od_rmse spsa-sumo/prior : {float(spsa['od_rmse']):.4f} / \"\n", " f\"{float(prior['od_rmse']):.4f}\")\n", "\n", "assert spsa[\"od_feasible\"] == 1.0\n", "assert spsa[\"certificate_converged\"] == 1.0\n", "assert abs(float(spsa[\"certificate_gap\"])) < 1e-6\n", "assert float(spsa[\"obs_count_rmse\"]) < 0.6 * float(prior[\"obs_count_rmse\"]) # loose: ~5x measured\n", "assert float(spsa[\"od_rmse\"]) < 0.6 * float(prior[\"od_rmse\"])" ] }, { "cell_type": "markdown", "id": "2c1b0f12", "metadata": {}, "source": [ "## The box-projection lesson (adr-028 Decision 6, a real adversarial-review finding)\n", "\n", "Balakrishna et al. impose a box constraint on the demand estimate. An EARLIER\n", "draft applied it only inside the oracle hook (`_assign_obs`), invisible to\n", "the parent SPSA loop: the loss was measured at the CLIPPED point while\n", "best-iterate tracking stored the RAW out-of-box candidate — so a binding box\n", "once emitted an out-of-box OD whose self-report described a DIFFERENT point\n", "(P1 broken: emitted != evaluated). The fix surfaces the thesis's own two\n", "projections as loop hooks (`_project`/`_project_log`) applied BEFORE `loss()`\n", "and best-iterate tracking. Demonstrated live: a seed where the box genuinely\n", "binds (a far, stale prior + a tight ceiling below truth)." ] }, { "cell_type": "code", "execution_count": 4, "id": "38840089", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:56:11.262878Z", "iopub.status.busy": "2026-07-21T13:56:11.262588Z", "iopub.status.idle": "2026-07-21T13:56:17.693883Z", "shell.execute_reply": "2026-07-21T13:56:17.692950Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "box ceiling (3x prior) : 2.6691\n", "emitted demand : 2.6691 (the box BINDS -- SPSA wants to climb past it)\n", "self-report vs certified honesty diff : 0.0005 (collapses to the mapping-floor scale -- the fix)\n" ] } ], "source": [ "HI_FRAC = 3.0\n", "est = SumoSPSAEstimator(iters=12, c=0.8, step_clip=2.0, demand_hi_frac=HI_FRAC)\n", "res_box = run_estimation_experiment(\n", " scenario, [est], Budget(iterations=1000), seed=14, macroreps=1,\n", " estimation={**_RECOVERY_EST, \"prior\": {\"kind\": \"stale\", \"cv\": 0.6}},\n", ")\n", "box_rows = [r for r in res_box.rows if r[\"estimator\"] == \"spsa-sumo\"]\n", "assert box_rows and all(r[\"od_feasible\"] == 1.0 for r in box_rows)\n", "\n", "hi = float(est._hi_vec[0]) # 3 * prior[0, 1] on the single active OD pair\n", "emitted = float(res_box.bundles[(\"spsa-sumo\", \"m0\")].final.od_matrix[0, 1])\n", "print(f\"box ceiling (3x prior) : {hi:.4f}\")\n", "print(f\"emitted demand : {emitted:.4f} (the box BINDS -- SPSA wants to climb past it)\")\n", "assert emitted <= hi + 1e-9 # in-box: fails under a clip-removal mutation of _project\n", "\n", "last_box = box_rows[-1]\n", "honesty_diff = abs(float(last_box[\"self_obs_count_rmse\"]) - float(last_box[\"obs_mean_count_rmse\"]))\n", "print(f\"self-report vs certified honesty diff : {honesty_diff:.4f} \"\n", " \"(collapses to the mapping-floor scale -- the fix)\")\n", "assert honesty_diff < 0.05" ] }, { "cell_type": "markdown", "id": "d8f95eaa", "metadata": {}, "source": [ "## Visualize\n", "\n", "The certified artifact is the emitted OD's re-assigned link flows on a road\n", "`Network`, so `tabench.viz` applies (adr-035's viz rule)." ] }, { "cell_type": "code", "execution_count": 5, "id": "2bd8582a", "metadata": { "execution": { "iopub.execute_input": "2026-07-21T13:56:17.696642Z", "iopub.status.busy": "2026-07-21T13:56:17.696433Z", "iopub.status.idle": "2026-07-21T13:56:17.993712Z", "shell.execute_reply": "2026-07-21T13:56:17.991590Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from tabench import BiconjugateFrankWolfeModel, Demand, RngBundle, Scenario, Trace\n", "\n", "# two_route_scenario carries no built-in ReferenceSolution; recompute the truth\n", "# assignment in-cell (never quoted), the same _pinned_ue pattern the `spsa`\n", "# tutorial uses.\n", "truth_trace = Trace()\n", "BiconjugateFrankWolfeModel().solve(\n", " scenario, Budget(iterations=5000, target_relative_gap=1e-10), RngBundle(0), truth_trace\n", ")\n", "truth_flows = truth_trace.final.link_flows\n", "\n", "recovered_trace = Trace()\n", "BiconjugateFrankWolfeModel().solve(\n", " Scenario(\"spsa-sumo-recovered\", scenario.network, Demand(res.bundles[(\"spsa-sumo\", \"m0\")].final.od_matrix)),\n", " Budget(iterations=5000, target_relative_gap=1e-10), RngBundle(0), recovered_trace,\n", ")\n", "display(viz.plot_network_flows(scenario.network, truth_flows))\n", "display(viz.plot_flow_scatter(\n", " (\"truth\", truth_flows),\n", " {\"spsa-sumo recovered\": recovered_trace.final.link_flows},\n", "))" ] }, { "cell_type": "markdown", "id": "e7e1a6ad", "metadata": {}, "source": [ "## Takeaways & pointers\n", "\n", "- **Zero certificate changes.** `ODCertifier` scored this row through the\n", " identical pinned-`bfw` map every other T2 estimator uses — the T2 thesis's\n", " whole point, proven by construction here.\n", "- **Disclosed, never fabricated.** `sp_calls=0` on every checkpoint, and the\n", " budget contract refuses an axis the oracle cannot honor rather than\n", " quietly ignoring it.\n", "- **A real adversarial-review fix, not a hypothetical.** The box-projection\n", " regression above is the exact repro that caught P1 broken (emitted ≠\n", " evaluated) in an earlier draft — demonstrated, not just described.\n", "- **Where next.** `dtalite-tap`\n", " ([03-dtalite-tap.ipynb](03-dtalite-tap.ipynb)) for the second external\n", " engine; the joint demand+supply scope that is honestly NOT shipped here, and\n", " the corner-plateau caveat it inherits, in\n", " [docs/design/adr-028-spsa-sumo.md](../../docs/design/adr-028-spsa-sumo.md)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" }, "tabench": { "covers": [], "requires_extra": "sumo", "track": "external", "unit": "spsa-sumo" } }, "nbformat": 4, "nbformat_minor": 5 }