Skip to content

fix(constraints): freeze empty constraint groups without reshape error#783

Open
Ketchp wants to merge 1 commit into
PyPSA:masterfrom
Ketchp:fix/csr-constraint-empty-rows
Open

fix(constraints): freeze empty constraint groups without reshape error#783
Ketchp wants to merge 1 commit into
PyPSA:masterfrom
Ketchp:fix/csr-constraint-empty-rows

Conversation

@Ketchp

@Ketchp Ketchp commented Jun 21, 2026

Copy link
Copy Markdown

Note

Code and test in this PR was AI aided.

Problem description:

CSRConstraint.from_mutable reshaped con.vars with an inferred -1 dimension. For an empty constraint group (zero rows and zero terms) the vars array has size 0, and NumPy refuses to infer a (0, -1) reshape, raising "cannot reshape array of size 0 into shape (0,newaxis)".

This is a degenerate edge-case, but can be encountered when slicing or masking is used.

Changes proposed in this Pull Request

Pass the explicit _term count instead of -1; NumPy accepts a (0, 0) reshape and the rest of the method already handles zero-row input.

Minimal reproducible example:

import linopy

m = linopy.Model(freeze_constraints=True) # does not work
# m = linopy.Model(freeze_constraints=False)  # works
x = m.add_variables(coords=[range(3)], dims=["t"], name="x")
m.add_constraints(x.isel(t=range(0)) == 0)  # raises: "ValueError: cannot reshape array of size 0 into shape (0,newaxis)"

Checklist

  • AI-generated content is marked (see AGENTS.md).
  • 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.

CSRConstraint.from_mutable reshaped con.vars with an inferred -1
dimension. For an empty constraint group (zero rows and zero terms) the
vars array has size 0, and NumPy refuses to infer a (0, -1) reshape,
raising "cannot reshape array of size 0 into shape (0,newaxis)". This
broke the documented lossless freeze round-trip for legitimately empty
groups (e.g. shifted-time difference constraints at n_time == 1).

Pass the explicit _term count instead of -1; NumPy accepts a (0, 0)
reshape and the rest of the method already handles zero-row input.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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