Skip to content

x - a <= 0 and x <= a build different constraints #707

Description

@FBumann

Issue Description

x - a <= 0 and x <= a are the same constraint, but linopy builds them differently in some cases. Subtraction aligns its operands by position when they share a same-size dimension — discarding coordinate labels — whereas the <= constraint operator aligns by label. The two forms disagree whenever the operands' labels are not already in the same order.

Reproducible Example

import pandas as pd
import linopy

m = linopy.Model()
x = m.add_variables(coords=[["A1", "A5", "A11", "A100"]], name="x")
coef = pd.Series([100, 1, 5, 11], index=["A100", "A1", "A5", "A11"])

print(x - coef <= 0)   # [A1]: x[A1] <= 100   <- positional, wrong
print(x <= coef)       # [A1]: x[A1] <= 1     <- by label, correct

coef["A1"] is 1, so the correct constraint is x[A1] <= 1. x <= coef produces that; x - coef <= 0 produces x[A1] <= 100 — it paired x[A1] with coef's first entry (A100), ignoring labels. Confirmed on linopy 0.7.0.

Expected Behavior

x - a <= 0 and x <= a are algebraically identical and must build the same constraint — either both align by label, or a label mismatch raises.

Context

Same positional / override-join behaviour as #586 and #670. #586's own snippet (add_constraints(x >= series)) takes the label-aligned path and no longer reproduces, but the bug is alive in arithmetic. The strict-alignment convention in #591 would fix it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions