Monotone Forced-Response Adapter
Implementation & benchmark of arXiv:2607.03942 — ThermoForce: A Physics-Structured Interventional World Model for Building HVAC Control
Source paper: ThermoForce: A Physics-Structured Interventional World Model for Building HVAC Control arXiv:2607.03942 ⓘ · analyzed Aug 30, 2026
AI-generated research hypothesis, automatically tested. Not peer-reviewed.
Idea description
Separate a pretrained sequence model's passive prediction from the causal effect of an action, and learn only the latter with a compact monotone adapter. The adapter receives the current latent state and an action deviation, but its action-to-output Jacobian is constrained to have the physically correct sign, preventing intervention predictions that move opposite to the applied control.
Formulas
Mathematical statement
The paper's central construction is the additive response decomposition \(\hat{T}_{t+h}=\hat{T}^{\,\mathrm{free}}_{t+h}+\hat{T}^{\,\mathrm{forced}}_{t+h}\). Here \(t\) is the current time, \(h\) is a forecast horizon, \(\hat{T}_{t+h}\) is the counterfactual future temperature, \(\hat{T}^{\,\mathrm{free}}_{t+h}\) is the control-independent prediction from a frozen time-series foundation model, and \(\hat{T}^{\,\mathrm{forced}}_{t+h}\) is the incremental response caused by HVAC actuation. The surrounding text states that the forced-response operator is monotone in the control input by construction. Adapt this as \(\hat{y}_{t+h}(u_{t:t+h-1})=f_{\theta_0}(x_{t-L:t},c_{t:t+h})+g_\phi(z_t,u_{t:t+h-1})\), where \(f_{\theta_0}\) is a frozen passive backbone, \(x\) is the observed history, \(c\) are exogenous covariates, \(z_t\) is the backbone latent state, and \(g_\phi\) is a small trainable forced-response module. For a scalar action \(u\) whose positive direction should increase the target, enforce \(\partial g_\phi/\partial u\geq0\) by parameterizing every action-mixing weight as \(W_u=\operatorname{softplus}(A_u)\); for cooling, reverse the output sign. A causal impulse form is \(g_\phi=\sum_{k=0}^{h-1}K_{\phi,k}(z_t)\,\Delta u_{t+k}\), with \(K_{\phi,k}\geq0\), so every action effect has the correct sign while its magnitude and temporal dependence remain learned.
Implementation notes
Integrate this at the output head of a pretrained sequence predictor used as a world model, not inside the backbone. First run the frozen backbone on the recent observation history and exogenous context to obtain the passive forecast \(y^{free}_{t+1:t+H}\) and latent state \(z_t\). Add a two-layer MLP or horizon-wise depthwise one-dimensional convolution that maps \(z_t\) and the planned action sequence \(u_{t:t+H-1}\) to the forced residual. Use: z, y_free = backbone(history, context).detach(); A = kernel_mlp(z); K = softplus(A); delta_u = u - u_reference; forced[h] = sum_k K[h,k] * delta_u[k]; y_hat = y_free + sign * forced. Set sign=+1 for an action that increases the target and sign=-1 for an action such as cooling that decreases it. For multiple action channels, use separate nonnegative kernels and fixed signed output vectors. Train only adapter parameters \(\phi\) on intervention trajectories with Huber or squared error on future targets, optionally adding the zero-action penalty \(\|g_\phi(z,0)\|^2\). Estimate the reference action from the no-actuation operating point or training-set median; initially do not fine-tune the backbone. The nonnegative kernel constraint is computed analytically through softplus; kernel smoothness or exponential decay may be added empirically. First test on a small Transformer or TSMixer pretrained on passive trajectories of a synthetic controlled dynamical system, using 1%, 5%, and 20% intervention data. Compare against an unconstrained residual head at equal parameter count. Measure intervention-effect error \(\|[\hat y(u)-\hat y(0)]-[y(u)-y(0)]\|\), wrong-sign frequency, passive forecast error, and model-predictive-control reward. Success means lower effect error and nearly zero wrong-sign predictions without degrading passive forecasting.
Verification
Stage 1 · Toy mechanism gate: Passed ✓
Stage 2 · Mechanism transferred to benchmark: Confirmed ✓
Stage 2 · Practical benchmark result: Inconclusive
Methodology: 8 paired seeds, permutation test (p<0.05) against a learning-rate-tuned baseline. How verification works
Stage 1 — Mechanism check agent confidence 8/10
Built a frozen passive backbone plus a softplus-constrained forced-response adapter and verified the mechanism numerically. The action Jacobian stayed positive with minimum observed 0.387, zero action produced exactly zero response, action scaling was exactly linear, and measured gains matched softplus predictions within 8.0e-8. The adapter improved effect MAE at 1% intervention data and guaranteed zero wrong-sign predictions, but was slightly worse at 5% and 20%, so a broad accuracy win was not established.
- Agent confidence
- 8/10
- Baseline
- Effect MAE / wrong-sign fraction / passive MAE: 1%=0.1889/0.1555/0.0222, 5%=0.1097/0.0035/0.0222, 20%=0.1079/0/0.0222
- Idea
- Effect MAE / wrong-sign fraction / passive MAE: 1%=0.1589/0/0.0222, 5%=0.1176/0/0.0222, 20%=0.1114/0/0.0222; Jacobian minimum=0.3873, zero-action maximum=0, gain sweep maximum error=8.0e-8
Limitations: The synthetic backbone and adapter are very small; the adapter uses horizon-independent summed action effects rather than a full causal impulse kernel, and the unconstrained comparison head is only approximately parameter-matched. No real HVAC data, multi-action outputs, MPC reward, or backbone fine-tuning was tested.
How to run: python3 experiment.py
Stage 2 — Benchmark vs. tuned baseline (arXiv:2607.03942)
No significant difference vs. the tuned baseline (+93.6%, p=0.0639, wins 0 / 0 paired seeds).
- Benchmark
- Dynamics forecasting
- Model
- rnn_small
- Paired seeds
- 8
- Baseline mean
- 0.0004
- Idea mean
- 0
- Effect (Δ)
- 0.0003 (+93.6%; negative = idea better)
- Wins
- 0 / 0 paired seeds
- p-value
- 0.0639 (permutation test, 20 000 shuffles)
- Smallest detectable effect
- n/a
- Mechanism
- Confirmed ✓
- Practical effect
- Inconclusive
- Baseline tuning
- swept over 0 configs
The built-in dynamics task predicts one next value from an action-containing history rather than a full planned action-horizon rollout. No custom track, MPC reward, multi-action output, backbone fine-tuning, or larger intervention datasets were tested. Baseline and idea sweeps used four seeds, with selected configurations evaluated on eight paired seeds.
How to run: python3 bench_experiment.py
Verdict computed by deterministic test code from paired-seed statistics — not by the language model.
Stage 2 — Benchmark latest Failed ✗
Agent confidence: 9/10
Built and evaluated a matched monotone forced-response GRU adapter on the structurally appropriate actuated-pendulum dynamics track. The trained model confirmed the mechanism: minimum finite-difference action slope was 0.01946, wrong-sign fraction was 0, and zero-action forced response was exactly 0. However, test MSE was worse than the unconstrained baseline (0.0006947 vs 0.0003589; paired delta +0.0003358, permutation p=0.06385), so the idea did not produce a significant benchmark win.
- Baseline
- test MSE mean 0.0003588799555, std 0.0001166449543, 8 paired seeds
- Idea
- test MSE mean 0.0006947237143, std 0.0005850544338, 8 paired seeds; mechanism confirmed: minimum slope 0.01945794, wrong-sign fraction 0, zero-action forced response 0
Benchmark result
No significant difference vs. the tuned baseline (+93.6%, p=0.0639, wins 0 / 0 paired seeds).
- Benchmark
- Dynamics forecasting
- Model
- rnn_small
- Paired seeds
- 8
- Baseline mean
- 0.0004
- Idea mean
- 0
- Effect (Δ)
- 0.0003 (+93.6%; negative = idea better)
- Wins
- 0 / 0 paired seeds
- p-value
- 0.0639 (permutation test, 20 000 shuffles)
- Smallest detectable effect
- n/a
- Mechanism
- Confirmed ✓
- Practical effect
- Inconclusive
- Baseline tuning
- swept over 0 configs
The built-in dynamics task predicts one next value from an action-containing history rather than a full planned action-horizon rollout. No custom track, MPC reward, multi-action output, backbone fine-tuning, or larger intervention datasets were tested. Baseline and idea sweeps used four seeds, with selected configurations evaluated on eight paired seeds.
How to run: python3 bench_experiment.py
Artifacts
- bench_experiment.py 6.6 KB View Raw
- bench_report.json 4.6 KB View Raw
- experiment.py 6.5 KB View Raw
- report.md 1.4 KB View
- report_bench_2026-08-30T213706.md 3.1 KB View
- results.json 1.7 KB View Raw