Commit 982b573
Piecewise linear constraints: follow-up improvements (#602)
* Refactor piecewise constraints: add piecewise/segments/slopes_to_points API, LP formulation for convex/concave cases, and simplify tests
* piecewise: replace bp_dim/seg_dim params with constants, remove dead code, improve errors
* Fix piecewise linear constraints: add binary indicators to incremental formulation, add domain bounds to LP formulation
- Incremental method now uses binary indicator variables with link/order constraints to enforce proper segment filling order (Markowitz & Manne)
- LP method now adds x ∈ [min(xᵢ), max(xᵢ)] domain bound constraints to prevent extrapolation beyond breakpoints
* update signatures of breakpoints and segments, apply convexity check only where needed
* update doc
* Reject interior NaN and skip_nan_check+NaN in piecewise formulations
Validate trailing-NaN-only for SOS2 and disjunctive methods to prevent
corrupted adjacency. Fail fast when skip_nan_check=True but breakpoints
actually contain NaN.
* Allow piecewise() on either side of comparison operators
Support reversed syntax (y == piecewise(...)) via __le__/__ge__/__eq__
dispatch in BaseExpression and ScalarLinearExpression. Fix LP example
to use power == demand for more illustrative results.
* Fix mypy type errors for piecewise constraint types
- Add @overload to comparison operators (__le__, __ge__, __eq__) in
BaseExpression and Variable to distinguish PiecewiseExpression from
SideLike return types
- Update ConstraintLike type alias to include PiecewiseConstraintDescriptor
- Fix PiecewiseConstraintDescriptor.lhs type from object to LinExprLike
- Fix dict/sequence type mismatches in _dict_to_array, _dict_segments_to_array,
_segments_list_to_array
- Remove unused type: ignore comments
- Narrow ScalarLinearExpression/ScalarVariable return types to not include
PiecewiseConstraintDescriptor (impossible at runtime)
* rename header of jupyter notebook
* doc: rename notebook again
* feat: add active parameter to piecewise linear constraints (#604)
* feat: add `active` parameter to piecewise linear constraints
Add an `active` parameter to the `piecewise()` function that accepts a
binary variable to gate piecewise linear functions on/off. This enables
unit commitment formulations where a commitment binary controls the
operating range.
The parameter modifies each formulation method as follows:
- Incremental: δ_i ≤ active (tightened bounds) + base terms × active
- SOS2: Σλ_i = active (instead of 1)
- Disjunctive: Σz_k = active (instead of 1)
When active=0, all auxiliary variables are forced to zero, collapsing
x and y to zero. When active=1, the normal PWL domain is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: tighten active parameter docstrings
Clarify that zero-forcing is the only linear formulation possible —
relaxing the constraint would require big-M or indicator constraints.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add active parameter to release notes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve mypy type errors for x_base/y_base assignment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add unit commitment example to piecewise notebook
Example 6 demonstrates the active parameter with a gas unit that
stays off at t=1 (low demand) and commits at t=2,3 (high demand),
showing power=0 and fuel=0 when the commitment binary is off.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update notebook
* test: comprehensive active parameter test coverage
Add tests for gaps identified in review:
- Inequality + active (incremental and SOS2, on and off)
- auto method selection + active (equality and auto-LP rejection)
- active with LinearExpression (not just Variable)
- active with NaN-masked breakpoints
- LP file output comparison (active vs plain)
- Multi-dimensional solver test (per-entity on/off)
- SOS2 non-zero base + active off
- SOS2 inequality + active off
- Disjunctive active on (solver)
- Fix: reject active when auto resolves to LP
159 tests pass (was 122).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: extract PWL_ACTIVE_BOUND_SUFFIX constant
Move the active bound constraint name suffix to constants.py,
consistent with all other PWL suffix constants.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: remove redundant active parameter tests
Keep only tests that exercise unique code paths or verify distinct
mathematical properties.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: FBumann <117816358+FBumann@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent ae7cef0 commit 982b573
12 files changed
Lines changed: 3129 additions & 2807 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
| 22 | + | |
23 | 23 | | |
| 24 | + | |
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
| |||
0 commit comments