Skip to content

test: make assert_linequal ignore dimension order#801

Open
FBumann wants to merge 1 commit into
PyPSA:masterfrom
fluxopt:fix/assert-linequal-dim-order
Open

test: make assert_linequal ignore dimension order#801
FBumann wants to merge 1 commit into
PyPSA:masterfrom
fluxopt:fix/assert-linequal-dim-order

Conversation

@FBumann

@FBumann FBumann commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

I hit some false positives while working on sth else. This fixes them. Making the testing more robust.

Note

The following content was generated by AI.

What this does

linopy expressions are dimension-labelled xarray structures, so they inherit
xarray's broadcast order-sensitivity: x + y produces dims (x_dim, y_dim)
while y + x produces (y_dim, x_dim). That difference is not mathematically
meaningful, but xarray's assert_equal is order-sensitive, so
assert_linequal(x + y, y + x) failed.

assert_linequal already normalizes term order before comparing (its
docstring promises "semantically equal"). This aligns dimension order the
same way: a new _align_dim_order helper transposes the second operand to the
first's dimension order when they share a dimension set. If the dimension sets
differ, the expressions are genuinely unequal and the comparison is left
untouched so assert_equal reports the real difference.

Notes

  • Touches only linopy/testing.py; adds test/test_testing.py (dim-order
    insensitivity, plus genuinely-different expressions still fail).
  • Full test_linear_expression.py + test_quadratic_expression.py pass
    unchanged (333), i.e. nothing was relying on the order-sensitive behavior.
Reproducer
import pandas as pd
from linopy import Model
from linopy.testing import assert_linequal

m = Model()
a = m.add_variables(coords=[pd.Index([0, 1], name="i")], name="a")
b = m.add_variables(coords=[pd.Index([0, 1, 2], name="j")], name="b")

(a + b).data.coeffs.dims   # ('i', 'j', '_term')
(b + a).data.coeffs.dims   # ('j', 'i', '_term')
assert_linequal(a + b, b + a)   # before: AssertionError; after: passes

linopy expressions inherit xarray's broadcasting, whose dimension order
follows operand order: ``x + y`` yields ``(x_dim, y_dim)`` while ``y + x``
yields ``(y_dim, x_dim)``. That difference carries no mathematical meaning,
yet xarray's order-sensitive ``assert_equal`` made the two compare unequal.

``assert_linequal`` already normalizes term order; align dimension order the
same way before comparing, matching its "semantically equal" contract.
Expressions with genuinely different dimension sets or values still fail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codspeed-hq

codspeed-hq Bot commented Jun 30, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 138 untouched benchmarks
⏩ 138 skipped benchmarks1


Comparing fluxopt:fix/assert-linequal-dim-order (3d33893) with master (fe798b1)

Open in CodSpeed

Footnotes

  1. 138 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@FBumann FBumann requested a review from FabianHofmann June 30, 2026 20:42
@FBumann

FBumann commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

canceled pypsa-tests

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