Skip to content

v1: summing scalar selections (x[i] + x[j]) raises on auxiliary-coordinate conflict #791

Description

@FBumann

Under the v1 convention, summing scalar selections of a variable raises. This breaks the very common sum(c[j] * x[j] for j in ...) idiom for building a constraint from a numpy matrix. Filing so we can decide whether to soften this before v1 ships.

Note

Reproduction and analysis below were produced with Claude Code (AI-generated).

Minimal reproduction

import linopy
from linopy import Model

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

m = Model()
x = m.add_variables(coords=[range(3)], name="x")
x[0] + x[1]   # ValueError

Actual

ValueError: Auxiliary coordinate 'dim_0' has conflicting values across operands:
left=0, right=1. xarray would silently drop the conflict; linopy raises so the
caller resolves it. ...

x[0] and x[1] each carry a scalar dim_0 coordinate (0 and 1). Adding
them is an aux-coordinate conflict, which v1 raises on (§11) instead of silently
dropping as legacy did.

Why it matters

The classic "build an LP from a numpy matrix" pattern now raises:

for i in range(4):
    lhs = sum(float(A[i, j]) * x[j] for j in range(n))
    m.add_constraints(lhs <= float(b[i]), name=f"c{i}")

Workarounds exist — vectorize with a labelled coefficient matrix
((A_da * x).sum(dim)), or drop the scalar coord per term
(x.isel(dim_0=j, drop=True)) — but the bare idiom failing with an
alignment error is a sharp ergonomic edge for a first-class operation.

Question for v1

Should scalar selections drop their leftover scalar dimension-coordinate (so
x[i] + x[j] just works), or is raising the intended, documented behaviour with
the workarounds as the answer? Related: #714 (meta), #295 (aux coords leaking
into expressions and breaking alignment).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions