Skip to content

Commit be93663

Browse files
committed
Update Changelog and add some tests to ensure behaviour
1 parent 65bcfb2 commit be93663

2 files changed

Lines changed: 81 additions & 1 deletion

File tree

doc/release_notes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Upcoming Version
1010
- Comparison operators (``==``, ``<=``, ``>=``) fill missing RHS coords with NaN (no constraint created)
1111
- Fixes crash on ``subset + var`` / ``subset + expr`` reverse addition
1212
- Fixes superset DataArrays expanding result coords beyond the variable's coordinate space
13+
* When passing DataArray bounds to ``add_variables`` with explicit ``coords``, the ``coords`` parameter now defines the variable's coordinates. DataArray bounds are validated against these coords (raises ``ValueError`` on mismatch) and broadcast to missing dimensions. Previously, the ``coords`` parameter was silently ignored for DataArray inputs.
1314
* Add ``add_piecewise_constraints()`` with SOS2, incremental, LP, and disjunctive formulations (``linopy.piecewise(x, x_pts, y_pts) == y``).
1415
* Add ``linopy.piecewise()`` to create piecewise linear function descriptors (`PiecewiseExpression`) from separate x/y breakpoint arrays.
1516
* Add ``linopy.breakpoints()`` factory for convenient breakpoint construction from lists, Series, DataFrames, DataArrays, or dicts. Supports slopes mode.
@@ -25,7 +26,6 @@ Version 0.6.5
2526

2627
* Expose the knitro context to allow for more flexible use of the knitro python API.
2728

28-
2929
Version 0.6.4
3030
--------------
3131

test/test_common.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,86 @@ def test_as_dataarray_with_dataarray_default_dims_coords() -> None:
409409
assert list(da_out.coords["dim2"].values) == list(da_in.coords["dim2"].values)
410410

411411

412+
def test_as_dataarray_with_dataarray_coord_mismatch() -> None:
413+
da_in = DataArray([1, 2, 3], dims=["x"], coords={"x": [10, 20, 30]})
414+
with pytest.raises(ValueError, match="do not match"):
415+
as_dataarray(da_in, coords={"x": [10, 20, 40]})
416+
417+
418+
def test_as_dataarray_with_dataarray_extra_dims() -> None:
419+
da_in = DataArray([[1, 2], [3, 4]], dims=["x", "y"])
420+
with pytest.raises(ValueError, match="extra dimensions"):
421+
as_dataarray(da_in, coords={"x": [0, 1]})
422+
423+
424+
def test_as_dataarray_with_dataarray_extra_dims_allowed() -> None:
425+
da_in = DataArray(
426+
[[1, 2], [3, 4]],
427+
dims=["x", "y"],
428+
coords={"x": [0, 1], "y": [0, 1]},
429+
)
430+
da_out = as_dataarray(da_in, coords={"x": [0, 1]}, allow_extra_dims=True)
431+
assert da_out.dims == da_in.dims
432+
assert da_out.shape == da_in.shape
433+
434+
435+
def test_as_dataarray_with_dataarray_broadcast() -> None:
436+
da_in = DataArray([1, 2], dims=["x"], coords={"x": ["a", "b"]})
437+
da_out = as_dataarray(
438+
da_in, coords={"x": ["a", "b"], "y": [1, 2, 3]}, dims=["x", "y"]
439+
)
440+
assert set(da_out.dims) == {"x", "y"}
441+
assert da_out.sizes["y"] == 3
442+
443+
444+
def test_as_dataarray_with_dataarray_no_coords() -> None:
445+
da_in = DataArray([1, 2, 3], dims=["x"], coords={"x": [10, 20, 30]})
446+
da_out = as_dataarray(da_in)
447+
assert_equal(da_out, da_in)
448+
449+
450+
def test_as_dataarray_with_dataarray_sequence_coords() -> None:
451+
da_in = DataArray([1, 2], dims=["x"], coords={"x": [0, 1]})
452+
idx = pd.RangeIndex(2, name="x")
453+
da_out = as_dataarray(da_in, coords=[idx], dims=["x"])
454+
assert list(da_out.coords["x"].values) == [0, 1]
455+
456+
457+
def test_as_dataarray_with_dataarray_sequence_coords_mismatch() -> None:
458+
da_in = DataArray([1, 2], dims=["x"], coords={"x": [0, 1]})
459+
idx = pd.RangeIndex(3, name="x")
460+
with pytest.raises(ValueError, match="do not match"):
461+
as_dataarray(da_in, coords=[idx], dims=["x"])
462+
463+
464+
def test_add_variables_with_dataarray_bounds_and_coords() -> None:
465+
model = Model()
466+
time = pd.RangeIndex(5, name="time")
467+
lower = DataArray([0, 0, 0, 0, 0], dims=["time"], coords={"time": range(5)})
468+
var = model.add_variables(lower=lower, coords=[time], name="x")
469+
assert var.shape == (5,)
470+
assert list(var.data.coords["time"].values) == list(range(5))
471+
472+
473+
def test_add_variables_with_dataarray_bounds_coord_mismatch() -> None:
474+
model = Model()
475+
time = pd.RangeIndex(5, name="time")
476+
lower = DataArray([0, 0, 0], dims=["time"], coords={"time": [0, 1, 2]})
477+
with pytest.raises(ValueError, match="do not match"):
478+
model.add_variables(lower=lower, coords=[time], name="x")
479+
480+
481+
def test_add_variables_with_dataarray_bounds_broadcast() -> None:
482+
model = Model()
483+
time = pd.RangeIndex(3, name="time")
484+
space = pd.Index(["a", "b"], name="space")
485+
lower = DataArray([0, 0, 0], dims=["time"], coords={"time": range(3)})
486+
var = model.add_variables(lower=lower, coords=[time, space], name="x")
487+
assert set(var.data.dims) == {"time", "space"}
488+
assert var.data.sizes["time"] == 3
489+
assert var.data.sizes["space"] == 2
490+
491+
412492
def test_as_dataarray_with_unsupported_type() -> None:
413493
with pytest.raises(TypeError):
414494
as_dataarray(lambda x: 1, dims=["dim1"], coords=[["a"]])

0 commit comments

Comments
 (0)