Skip to content

read_netcdf sorts containers alphabetically, permuting matrices.A after a round trip #934

Description

@FabianHofmann

Note

The following content was generated by AI (Claude Code) while reviewing #929, verified by @FabianHofmann.

read_netcdf rebuilds the variable, expression and constraint containers with sorted(...) over the names (linopy/io.py, read_netcdf), so a model comes back in alphabetical instead of insertion order. Labels are preserved, but matrices.A orders its columns by container iteration, so the matrix of a round-tripped model is a column permutation of the original. Same for the constraint rows. Independent of the semantics option and of frozen constraints.

Repro

import linopy
import numpy as np

m = linopy.Model()
z = m.add_variables(lower=0, name="z")
a = m.add_variables(lower=0, name="a")
m.add_constraints(z + a >= 10, name="con1")
m.add_constraints(z - a <= 5, name="con2")
m.add_objective(z + 2 * a)

m.to_netcdf("model.nc")
m2 = linopy.io.read_netcdf("model.nc")

print(list(m.variables), list(m2.variables))
print(np.array_equal(m.matrices.A.toarray(), m2.matrices.A.toarray()))
['z', 'a'] ['a', 'z']
False

Proposal

Store the container order in the file (e.g. an attribute listing the names) and rebuild in that order, falling back to the sorted order for files without it.

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

    sparseSparse / CSR-backed expressions and constraints

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions