Skip to content

Cover the committed quantity in Mc, and tighten it - #2411

Open
Flix6x wants to merge 12 commits into
mainfrom
fix/tighten-commitment-bigm
Open

Cover the committed quantity in Mc, and tighten it#2411
Flix6x wants to merge 12 commits into
mainfrom
fix/tighten-commitment-bigm

Conversation

@Flix6x

@Flix6x Flix6x commented Aug 7, 2026

Copy link
Copy Markdown
Member

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, min and equals, 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

Mc is 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

Flix6x and others added 2 commits August 7, 2026 15:56
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>
@read-the-docs-community

read-the-docs-community Bot commented Aug 7, 2026

Copy link
Copy Markdown

Flix6x and others added 2 commits August 7, 2026 16:24
…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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Mc based 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 validate Mc composition 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

Comment thread flexmeasures/data/models/planning/scheduling_problem.py
@Flix6x
Flix6x requested a lite review from Copilot August 7, 2026 14:37
…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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

…t-bigm

# Conflicts:
#	documentation/changelog.rst
Comment thread flexmeasures/data/tests/test_scheduling_simultaneous.py
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_limits currently uses abs().max(axis=1) across derivative max/min/equals. When derivative equals is 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 tightening Mc (e.g. a device with derivative min=-1, derivative max=0, derivative equals=-0.4 contributes 1.0 here but can only ever contribute 0.4). Consider computing the effective per-step limit by using abs(clip(derivative equals)) when present, otherwise max(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
@Flix6x Flix6x added this to the 1.1.0 milestone Aug 8, 2026
@Flix6x Flix6x self-assigned this Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants