Cover the committed quantity in Mc, and tighten it - #2411
Conversation
The big-M bounding commitment deviations summed the absolute device flow limits over all devices, time steps and flow columns, which is orders of magnitude above the largest possible flow deviation, weakening the LP relaxation whenever a non-convex cost curve adds the commitment-sign constraints. It also ignored the committed quantities altogether: a committed quantity far beyond the devices' flow limits needs a deviation larger than Mc, which made the problem infeasible. The bound now adds the largest absolute committed quantity to the devices' flow limits, summed per time step for flow commitments and over the horizon where stock commitments are present (their deviations accumulate flows since the start). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: F.N. Claessen <claessen@seita.nl>
Signed-off-by: F.N. Claessen <claessen@seita.nl>
Documentation build overview
21 files changed ·
|
…ce split The tightened Mc changes the model coefficients, which lands the solver on another vertex of the same optimum: total costs, the energy commitment's cost and the sample supply commitment's reward are unchanged, but the EV/battery split (both devices face the same prices) moves. The split was standing in for the aggregate commitment semantics of issue #2379, which the sample commitment's own reported cost captures directly: per-device binding would reward the battery's supply also while the site is net-consuming. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: F.N. Claessen <claessen@seita.nl>
…t-bigm # Conflicts: # documentation/changelog.rst
There was a problem hiding this comment.
Pull request overview
This PR fixes and tightens the scheduler’s commitment-deviation Big-M (Mc) by incorporating committed quantities (preventing infeasibility when commitments exceed device limits) while avoiding an overly-loose bound that weakens LP relaxations under non-convex commitment sign constraints.
Changes:
- Recompute
Mcbased on per-step aggregated device flow limits, plus the largest finite absolute committed quantity; for stock commitments, cover the whole horizon. - Add a new planning test module (
test_big_m.py) to validateMccomposition and a previously-infeasible non-convex case. - Adjust an existing scheduling test to assert aggregate commitment reward behavior without relying on a degenerate EV/battery cost split; add a changelog entry.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| flexmeasures/data/tests/test_scheduling_simultaneous.py | Makes the test assert aggregate commitment reward semantics without relying on solver-dependent device split |
| flexmeasures/data/models/planning/tests/test_big_m.py | Adds targeted regression and composition tests for Mc under both solver backends |
| flexmeasures/data/models/planning/scheduling_problem.py | Updates Mc calculation to include committed quantities and tighten bounds |
| documentation/changelog.rst | Adds a user-facing bugfix note describing the corrected/tightened Mc behavior |
…iencies A stock change is not a raw flow: it passes through the derivative efficiencies and includes the explicit stock delta, so with a conversion gain above one (or a nonzero stock delta) the horizon-summed flow limits under-bounded a stock commitment's deviation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: F.N. Claessen <claessen@seita.nl>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (4)
flexmeasures/data/models/planning/tests/test_big_m.py:108
- These two comment lines break a sentence across lines in a way that doesn't end each physical line with punctuation. Per .github/instructions/docstrings.instructions.md, avoid mid-phrase wraps by combining into one punctuated line.
# 4 time steps of 0.5 flow scaled by the worst-case conversion gain max(2, 1/0.5) plus a 0.25 stock delta,
# plus the committed quantity
flexmeasures/data/models/planning/tests/test_big_m.py:143
- These inline comments should end with punctuation to follow the repo's docstring/comment formatting rule (.github/instructions/docstrings.instructions.md).
# The upwards deviation earns 1 per unit, so the device consumes at full power
np.testing.assert_allclose(schedule[0].values, 0.5, atol=1e-6)
# Each of the 4 steps deviates upwards by 100.5 at price -1
assert costs == -4 * 100.5
flexmeasures/data/models/planning/tests/test_big_m.py:83
- Inline comments should end with punctuation; this comment currently ends mid-sentence, which violates the docstring/comment line-break rule in .github/instructions/docstrings.instructions.md.
This issue also appears in the following locations of the same file:
- line 107
- line 140
# 4 time steps of 0.5 + 2 flow limits each, plus the committed quantity
flexmeasures/data/tests/test_scheduling_simultaneous.py:146
- Inline comments should only break lines after punctuation (see .github/instructions/docstrings.instructions.md). Here the line break happens after "commitment" with no punctuation, leaving a mid-phrase wrap.
# Aggregate (unscoped) commitment semantics (issue #2379): the sample commitment
# rewarding supply binds the site's *aggregate* flow,
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: F.N. Claessen <claessen@seita.nl>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
flexmeasures/data/tests/test_scheduling_simultaneous.py:147
- The first line of this comment block breaks the repo’s “line breaks only after punctuation” convention for comments/docstrings (see .github/instructions/docstrings.instructions.md:38). Right now it wraps after “the sample commitment” (no punctuation), which makes later edits and searching harder.
# Aggregate (unscoped) commitment semantics (issue #2379): the sample commitment
# rewarding supply binds the site's *aggregate* flow,
# so it collects a reward only where the site as a whole net-produces.
flexmeasures/data/models/planning/tests/test_big_m.py:143
- This test asserts exact equality on a floating-point cost returned by the solver. Even when the solution is correct, solver/LP backend differences (or small numerical noise) can produce tiny rounding differences and make this assertion flaky, especially since this module runs under both backends.
assert costs == -4 * 100.5
…cost equality Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: F.N. Claessen <claessen@seita.nl>
…t-bigm # Conflicts: # documentation/changelog.rst
Requested in review: the split records which vertex of the degenerate optimum the solver lands on, so it stays asserted as a benchmark of how model changes impact fairness, with the expectation updated deliberately when a change moves it. The tightened Mc moves the EV costs from 2.2375 to 2.3125. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: F.N. Claessen <claessen@seita.nl>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (1)
flexmeasures/data/models/planning/scheduling_problem.py:523
per_device_step_limitscurrently usesabs().max(axis=1)acrossderivative max/min/equals. Whenderivative equalsis set, the actual feasible flow is pinned (and clipped to min/max by the selector logic), so taking the max can significantly overestimate the true per-step bound and undermines the goal of tighteningMc(e.g. a device withderivative min=-1,derivative max=0,derivative equals=-0.4contributes 1.0 here but can only ever contribute 0.4). Consider computing the effective per-step limit by usingabs(clip(derivative equals))when present, otherwisemax(abs(min), abs(max)).
per_device_step_limits = [
d[bigM_columns].astype(float).abs().max(axis=1).fillna(0).to_numpy()
for d in device_constraints
]
per_step_total = sum(per_device_step_limits)
…t-bigm # Conflicts: # documentation/changelog.rst
Why
Mc, the big-M bounding commitment deviations, summed the absolute device flow limits over all devices, all time steps and all three flow columns (derivative max,minandequals, double-counting the latter). That is orders of magnitude above the largest possible flow deviation, which weakens the LP relaxation whenever a non-convex cost curve adds the commitment-sign constraints — and sits badly with the 1e-9 feasibility tolerances we pin for HiGHS.At the same time it ignored the committed quantities: a committed quantity far beyond the devices' flow limits needs a deviation larger than
Mc, so the sign constraint cut it off and the problem went infeasible.What changed
Mcis now the largest absolute committed quantity plus the devices' summed flow limits — summed per time step for flow commitments, and over the whole horizon when stock commitments are present (their deviations accumulate flows since the start of the schedule).How to test
New
test_big_m.py(running under both backends) covers the bound's composition, the 1 MW floor, and a behavioral case — a committed quantity of 100 against a 0.5 MW device under a non-convex cost curve — that is infeasible on main and optimal with the fix. The full planning suite passes (349 passed).🤖 Generated with Claude Code