odme-dtalite — DTALite’s static ODME as one more guarded T2 estimator (Zhou & Taylor 2014)¶
What. odme-dtalite (T2, ADR-042) is the estimation track’s second
engine-in-the-loop estimator and its first ODME row. DTALite 0.8.1’s PyPI wheel
hides an Origin-Destination Matrix Estimation routine (performODME) inside
the same static assignment() entry the dtalite-tap T1 adapter (adr-029)
already wraps — it runs when settings.csv carries odme_mode=1. Given a seed
OD, a target OD, and sensor link counts (obs_volume), it re-weights the
route-flows the base Frank-Wolfe assignment discovered so the modeled link
volumes approach the counts ([zhou2014dtalite],
docs/REFERENCES.md).
Why it is in the benchmark. T2’s whole thesis is that ANY OD-emitting method
is scored by the SAME pinned-bfw certifier. odme-dtalite ships as a GUARDED
STATIC estimator riding that UNCHANGED certifier (the adr-028 ideal: zero task,
runner, or certifier changes) — the estimator emits an OD, the certifier
re-assigns it under the declared BPR. It is a row, not a new question.
How this notebook is graded¶
A notebook never claims a number it does not compute in that cell. Every
scored quantity below — od_feasible, certificate_gap, obs_count_rmse,
heldout_count_rmse — comes from the SAME ODCertifier every other T2
estimator here is scored by, re-assigning the emitted OD through its own pinned
bfw reference, never from odme-dtalite’s self-report
(README, Certified, not self-reported).
# Setup. `odme-dtalite` needs the optional `dtalite` extra
# (`pip install tabench[dtalite]`). We probe it WITHOUT importing it: `import
# DTALite` prints a banner and ctypes-loads an OpenMP engine into the host
# (adr-029), so the estimator only ever runs it in a throwaway subprocess.
#
# The inline backend renders figures headlessly so CI can execute tutorials
# without a display. NEVER matplotlib.use("Agg") in-kernel -- it silently
# suppresses inline capture.
%matplotlib inline
import importlib.util
if importlib.util.find_spec("DTALite") is None:
raise ModuleNotFoundError(
"odme-dtalite needs the optional 'dtalite' extra: pip install tabench[dtalite]",
name="DTALite",
)
import matplotlib.pyplot as plt
from tabench import Budget, PriorBaseline, run_estimation_experiment
from tabench.data import load_scenario
from tabench.estimation import DtaliteODMEEstimator
# THE marquee anchor (adr-042): siouxfalls UE (BPR power-4, 528 OD pairs), clean
# counts, sensors random coverage 0.5, held-out coverage 0.2, stale prior cv=0.3.
# Sioux-Falls scale is DELIBERATE: DTALite's ODME has a hardcoded ABSOLUTE
# convergence floor (tol=1), so Braess-scale demand (~6) would no-op with "0
# iterations". At this scale realistic deviations clear the floor.
MARQUEE = {
"sensors": {"kind": "random", "coverage": 0.5},
"heldout": {"kind": "random", "coverage": 0.2},
"noise": "none", "n_periods": 1, "prior": {"kind": "stale", "cv": 0.3},
}
SEED = 7
scenario = load_scenario("siouxfalls")
print(f"scenario: {scenario.name}, {scenario.network.n_zones} zones / "
f"{scenario.network.n_links} links, BPR power {scenario.network.power[0]:.0f}")
scenario: siouxfalls, 24 zones / 76 links, BPR power 4
The recovery anchor, certified through the UNCHANGED pinned-bfw certifier¶
Zero changes to the task, runner, or certifier were needed for this row:
ODCertifier re-assigns the emitted OD through its OWN pinned bfw reference
regardless of which engine produced it — the whole point of T2. One non-obvious
engine pin makes it work: odme-dtalite writes route_output=1 so DTALite
populates the route history its ODME reconstruction reads (with the lean
route_output=0, the reconstruction collapses and the OD inflates ~40 %, a
degenerate estimate — measured, adr-042).
res = run_estimation_experiment(
scenario, [PriorBaseline(), DtaliteODMEEstimator()], Budget(iterations=100),
seed=SEED, macroreps=1, estimation=MARQUEE,
)
last = {row["estimator"]: row for row in res.rows}
prior, odme = last["prior"], last["odme-dtalite"]
print(f"certified od_feasible : {odme['od_feasible']:.0f}")
print(f"certificate_converged : {odme['certificate_converged']:.0f}")
print(f"certificate_gap : {float(odme['certificate_gap']):.2e}")
print(f"obs_count_rmse odme / prior : {float(odme['obs_count_rmse']):.1f} / "
f"{float(prior['obs_count_rmse']):.1f}")
print(f"heldout_count_rmse odme / prior (rank): {float(odme['heldout_count_rmse']):.1f} / "
f"{float(prior['heldout_count_rmse']):.1f}")
print(f"od_rmse odme / prior : {float(odme['od_rmse']):.1f} / "
f"{float(prior['od_rmse']):.1f}")
# Certified, feasible, and a real improves-on-prior on the count fit it calibrates
# AND the ranking held-out count fit (loose bounds; the .so can shift the decimals).
assert odme["od_feasible"] == 1.0 and odme["certificate_converged"] == 1.0
assert float(odme["obs_count_rmse"]) < 0.6 * float(prior["obs_count_rmse"])
assert float(odme["heldout_count_rmse"]) < 0.9 * float(prior["heldout_count_rmse"])
certified od_feasible : 1
certificate_converged : 1
certificate_gap : 9.51e-07
obs_count_rmse odme / prior : 365.3 / 994.8
heldout_count_rmse odme / prior (rank): 556.6 / 816.5
od_rmse odme / prior : 264.5 / 267.4
The disclosed envelope, and that the ODME descent actually fired¶
DTALite’s ODME is bounded by hardcoded, non-configurable engine constants (part
of the pinned 0.8.1 identity, like marouter’s linear vdf): a
[0.5·min, 1.5·max]-of-(seed,target) recovery box, penalty weights
w_link=0.1 / w_od=0.01, and the absolute tol=1 convergence floor plus a fixed
400-iteration descent. demand_target_frac (default 1.0) is the one documented
dial — a one-sided widening of the box (>1 raises the upper bound only).
od_rmse barely moves because Sioux Falls OD is not linearly identifiable from
these sensors (od_identifiable = 0, reported) — odme-dtalite is a
count-matcher, honestly.
bundle = res.bundles[("odme-dtalite", "m0")]
odme_iters = float(bundle.trace.final.self_report["engine_odme_iterations"])
print(f"ODME gradient iterations executed : {odme_iters:.0f} (>0: cleared the tol=1 floor)")
print(f"od_identifiable : {odme['od_identifiable']:.0f} "
"(0 -> od_rmse is descriptive, not ranked)")
print(f"demand_target_frac (hashed factor): "
f"{DtaliteODMEEstimator().factor_values['demand_target_frac']}")
assert odme_iters > 0 # never a 'Convergence reached after 0 iterations' no-op
ODME gradient iterations executed : 69 (>0: cleared the tol=1 floor)
od_identifiable : 0 (0 -> od_rmse is descriptive, not ranked)
demand_target_frac (hashed factor): 1.0
Anti-laundering — the certifier scores the OD, never DTALite’s self-report¶
The sacred property: the ONLY channel from odme-dtalite to the harness is the
emitted OD matrix. ODCertifier re-runs its own bfw and never reads DTALite’s
bookkeeping, so a buggy or adversarial run can at worst emit a bad OD that
certifies honestly — it cannot forge a good certificate. DTALite reports a rosy
count fit (its stalled-assignment, box-clamped predicted volumes); the certifier
ignores it. That gap is the measured engine-in-the-loop bias, provenance only.
self_fit = float(bundle.trace.final.self_report["obs_count_rmse"])
certified = float(odme["obs_count_rmse"])
print(f"DTALite self-reported obs_count_rmse : {self_fit:.2f} (its own optimistic view)")
print(f"pinned-bfw CERTIFIED obs_count_rmse : {certified:.1f} (what the leaderboard sees)")
print(f"engine-in-the-loop bias (self << certified): {self_fit < 0.5 * certified}")
assert self_fit < 0.5 * certified # the certifier did not trust the self-report
DTALite self-reported obs_count_rmse : 8.06 (its own optimistic view)
pinned-bfw CERTIFIED obs_count_rmse : 365.3 (what the leaderboard sees)
engine-in-the-loop bias (self << certified): True
fig, ax = plt.subplots(figsize=(5.2, 3.2))
labels = ["obs_count_rmse", "heldout_count_rmse\n(ranking)"]
prior_vals = [float(prior["obs_count_rmse"]), float(prior["heldout_count_rmse"])]
odme_vals = [float(odme["obs_count_rmse"]), float(odme["heldout_count_rmse"])]
x = range(len(labels))
ax.bar([i - 0.2 for i in x], prior_vals, width=0.4, label="prior baseline")
ax.bar([i + 0.2 for i in x], odme_vals, width=0.4, label="odme-dtalite")
ax.set_xticks(list(x)); ax.set_xticklabels(labels)
ax.set_ylabel("certified count RMSE"); ax.set_title("odme-dtalite vs prior (pinned-bfw certified)")
ax.legend(); fig.tight_layout()
Takeaways¶
odme-dtaliteis a guarded static estimator on the UNCHANGED pinned-bfwcertifier — the adr-028 zero-certifier-change ideal, a second engine afterspsa-sumo.It measurably beats the prior on the certified count fit at the Sioux Falls marquee, with the ODME descent actually firing (>0 iterations) — the anchor is chosen to clear DTALite’s hardcoded
tol=1floor.Its engine envelope (the
[0.5,1.5]×box, the hardcoded weights/tol, theroute_output=1requirement, thelink_performance.csvcorruption it routes around by readingod_performance.csvonly) is disclosed as an honest scope boundary. Single-mode demand-only; multiclass ODME is a deferred follow-up.