Add a `mask` parameter to `add_piecewise_formulation`
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 257
- Forks
- 87
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 29
Description
This is not needed explicitly by anyone yet, but should be added for consistency with add_variables etc
[!NOTE]
The following content was generated by AI.
Summary
Add a mask parameter to add_piecewise_formulation, matching the add_variables(mask=…) / add_constraints(mask=…) convention: where mask=False, no piecewise formulation is built for that entry (no auxiliary variables, no link/convexity constraints). It answers a structural question — does this entity have a piecewise relationship at all? — and takes priority over active.
Motivation
Heterogeneous sets where only some entities have a piecewise curve. Today you either split into several add_piecewise_formulation calls or rely on NaN-breakpoint tricks. A mask is the declarative, convention-aligned way to say "this entity has no curve here."
Relationship to active / active_fill (#796, #797, #798)
mask is orthogonal to gating and does not overlap with the #796 work:
| state | how to express |
|---|---|
| entity has no curve | mask=False |
| curve, gated on/off (unit commitment) | active=status |
| curve, always on (ungated) | active_fill=1 (or full active=1) |
mask: structural / compile-time — does the constraint exist here?active: solve-time decision — is it engaged?
They compose: mask filters which entries get a formulation, active gates the survivors. A masked entry has no constraint, so active/active_fill for it is moot — hence mask priority. mask does not solve #796: masking the non-committable units would delete their curve, but those units still dispatch on it.
Relationship to .sel()
For a clean label-subset along one dimension, .sel() on the operands already achieves "no constraint elsewhere", so no parameter is needed there. mask earns its place for:
- Ragged / multi-dim holes that no rectangular
.sel()can express (scattered(gen, time)pairs, not whole labels along an axis). - Full-index output —
.sel()returns reduced-index objects that must be realigned to the full coordinate afterwards;maskkeeps everything on the full index with holes. - One declarative argument instead of slicing every operand (and keeping breakpoint arrays consistent).
Notes
- Not urgent and not a blocker for the #796 gating fix; filed separately so the two designs don't get tangled.
- Originally raised by @fneum in review of #797.
🤖 Generated with Claude Code
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the add_piecewise_formulation entry point and compare its parameter handling with add_variables(mask=…) and add_constraints(mask=…). Check the existing tests around piecewise formulations, then verify that masked entries create no auxiliary variables or constraints while unmasked entries still honor active and active_fill.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100