Skip to content

Conversation

@FBumann
Copy link
Contributor

@FBumann FBumann commented Jan 25, 2026

Add Piecewise Linear Constraint API

Summary

Add add_piecewise_constraints method to Model class for creating piecewise linear constraints using SOS2 formulation.

Features

  • Single Variable or LinearExpression support
  • Dict of Variables/Expressions for linking multiple quantities (e.g., power-efficiency curves)
  • Auto-detection of link_dim from breakpoints coordinates
  • NaN-based masking with skip_nan_check option for performance
  • Counter-based name generation for efficiency

Design decision

Is this something the linopy package wants to add? And if, do you want to see this as a helper method, that adds variables and constraints itself, or store sth like a PWL-Constraint object?
This implementation adds variables and (sos-)constraints, which i prefer over adding other classes of constraints.
This kind of relies on #549 to be widely uses, as it uses sos2 internally

As a convention, we could establish that such internally added variables/constraints get a prefix starting with an double underscore. This would simplify filtering.

Usage

# Single variable
m.add_piecewise_constraints(x, breakpoints, dim='bp')

# Expression
m.add_piecewise_constraints(x + y, breakpoints, dim='bp')

# Multiple linked variables (e.g., power-efficiency curve)
m.add_piecewise_constraints(
    {'power': power, 'efficiency': efficiency},
    breakpoints,
    link_dim='var',
    dim='bp'
)

SOS2 Formulation

The method creates:

  1. Lambda (λ) variables with bounds [0, 1] for each breakpoint
  2. SOS2 constraint ensuring at most two adjacent λ values are non-zero
  3. Convexity constraint: Σλ = 1
  4. Linking constraints: expr = Σ(λ × breakpoint) for each expression

Known Limitations

Supported (continuous):     NOT supported (discontinuous):
      /\                          /\
     /  \                        /  \
    /    \____                  /    \       ____
                                           gap
  • Returns only convexity constraint; access lambda via model.variables[f"{name}_lambda"]
  • No removal/modification support after creation
  • Single breakpoint dimension for all linked expressions

Future Work

Checklist

  • Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in doc.
  • Unit tests for new features were added (if applicable).
  • A note for the release notes doc/release_notes.rst of the upcoming release is included.
  • I consent to the release of this PR's code under the MIT license.

Add `add_piecewise_constraint` method to Model class that creates
piecewise linear constraints using SOS2 formulation.

Features:
- Single Variable or LinearExpression support
- Dict of Variables/Expressions for linking multiple quantities
- Auto-detection of link_dim from breakpoints coordinates
- NaN-based masking with skip_nan_check option for performance
- Counter-based name generation for efficiency

The SOS2 formulation creates:
1. Lambda variables with bounds [0, 1] for each breakpoint
2. SOS2 constraint ensuring at most two adjacent lambdas are non-zero
3. Convexity constraint: sum(lambda) = 1
4. Linking constraints: expr = sum(lambda * breakpoints)
@FBumann FBumann marked this pull request as ready for review January 26, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant