Skip to content

CSRConstraint drops auxiliary coordinates when a sparse expression becomes a constraint #941

Description

@FabianHofmann

Note

This issue was written by AI (Claude), based on a limitation found while working on #940.

Version Checks (indicate both or one)

Issue Description

Under v1 semantics, a CSR-backed LinearExpression (the result of groupby(...).sum(sparse=True)) carries one-dimensional auxiliary coordinates, e.g. the period/region labels of a multi-key observed=True grouping on the flat group dim, or aux coords on surviving dims. When such an expression is turned into a constraint via Model.add_constraints, the resulting CSRConstraint drops every auxiliary coordinate and keeps only the per-dimension index.

The dense path keeps them, so the sparse and dense results differ in their coordinates. This matters for later sel/where on the constraint by aux label and for the v1 aux-conflict rule, which cannot fire on the constraint side anymore.

Cause: CSRConstraint.from_payload builds the constraint from payload.indexes[d] for d in payload.grid_dims only and never looks at payload.coords (linopy/constraints.py, from_payload). CSRConstraint itself stores only a list of per-dim pd.Index, so there is currently no slot for aux coords to live in.

Reproducible Example

import linopy
import pandas as pd
from linopy import Model

linopy.options["semantics"] = "v1"

m = Model()
x = m.add_variables(coords=[pd.RangeIndex(4, name="s")], name="x")
expr = x.to_linexpr().assign_coords(
    period=("s", [1, 1, 2, 2]), region=("s", ["n", "s", "n", "s"])
)

dense = expr.groupby(["period", "region"]).sum(observed=True)
sparse = expr.groupby(["period", "region"]).sum(observed=True, sparse=True)

print(list(dense.coords))   # ['period', 'region', 'group']
print(list(sparse.coords))  # ['group', 'period', 'region']

c_dense = m.add_constraints(dense <= 1, name="dense")
c_sparse = m.add_constraints(sparse <= 1, name="sparse")

print(list(c_dense.coords))   # ['period', 'region', 'group']
print(list(c_sparse.coords))  # ['group']   <- period and region are gone

Expected Behavior

c_sparse.coords contains period and region on the group dim, matching the dense constraint and the sparse expression it was built from.

Installed Versions

Details

linopy 0.9.1.post1.dev20+g73e65c22d plus PR #940, Python 3.13, xarray/pandas from uv sync --extra dev.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions