You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the long term I would like to have things strict, but for now this is fine. Tracking this so we can readdress it later.
Note
The following content was generated by AI.
Describe the feature you'd like to see
With the move to mathspec 0.2.0 in #958, linopy/spec/builder.py::_check_live no longer refuses a constraint row that absence empties. It drops the row silently. This follows mathspec's documented semantics: absence spread through arithmetic "takes the row with it", and the first row of a bare shift "is not built".
Before (0a725f4), such a row raised SpecDataError ("N row(s) hold no variable term"), because a row that silently disappears no longer binds.
absent (null) row, e.g. x - shift(x) at the first snapshot
dropped silently
bare masked Variable as a term
not checked
present row with no variable, e.g. absence: zero against a binding side
refused
Strict is the long-term goal. Open questions:
Opt-in strictness, e.g. add_spec(..., strict=True), or strict by default with an explicit edge policy in the spec (shift(..., edge=...))?
Warn at least with the count of rows dropped per constraint?
Does mathspec need a language-level way to state "this row may be dropped", so strict engines can tell intended from accidental absence?
Reasons it is relaxed for now: pypsa.yaml, its netcdf round trip and the spec_pypsa benchmark rely on a bare shift dropping the first snapshot.
Minimal example
importpandasaspdimportxarrayasxrimportlinopylinopy.options["semantics"] ="v1"spec="""dimensions: snapshot: { dtype: int }variables: p: dims: [snapshot] bounds: { lower: 0 }constraints: no_faster_than_before: dims: [snapshot] expression: p <= shift(p, along=snapshot, offset=1)objective: { sense: minimize, expression: sum(p) }"""sources=xr.Dataset(coords={"snapshot": pd.Index([0, 1, 2], name="snapshot")})
m=linopy.Model.from_spec(spec, sources)
print(m.constraints["no_faster_than_before"].labels.values)
# [-1 1 2] -> row at snapshot 0 is dropped without error or warning
Tests pinning the current behaviour: test/test_spec_builder.py::test_absence_takes_the_row_with_it and ::test_a_row_the_data_emptied_of_variables_is_refused.
In the long term I would like to have things strict, but for now this is fine. Tracking this so we can readdress it later.
Note
The following content was generated by AI.
Describe the feature you'd like to see
With the move to mathspec 0.2.0 in #958,
linopy/spec/builder.py::_check_liveno longer refuses a constraint row that absence empties. It drops the row silently. This follows mathspec's documented semantics: absence spread through arithmetic "takes the row with it", and the first row of a bareshift"is not built".Before (0a725f4), such a row raised
SpecDataError("N row(s) hold no variable term"), because a row that silently disappears no longer binds.The current state after #958:
x - shift(x)at the first snapshotVariableas a termabsence: zeroagainst a binding sideStrict is the long-term goal. Open questions:
add_spec(..., strict=True), or strict by default with an explicit edge policy in the spec (shift(..., edge=...))?Reasons it is relaxed for now:
pypsa.yaml, its netcdf round trip and thespec_pypsabenchmark rely on a bareshiftdropping the first snapshot.Minimal example
Tests pinning the current behaviour:
test/test_spec_builder.py::test_absence_takes_the_row_with_itand::test_a_row_the_data_emptied_of_variables_is_refused.