Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions test/test_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ def test_constraint_to_polars_mixed_signs(m: Model, x: linopy.Variable) -> None:
# Use Constraint so sign data can be patched
con = m.add_constraints(x >= 0, name="mixed", freeze=False)
# Replace sign data with mixed signs across the first dimension
n = con.data.sizes["first"]
n = con.sizes["first"]
signs = np.array(["<=" if i % 2 == 0 else ">=" for i in range(n)])
con.data["sign"] = xr.DataArray(signs, dims=con.data["sign"].dims)
df = con.to_polars()
Expand Down Expand Up @@ -667,7 +667,7 @@ def test_constraint_with_helper_dims_as_coords(m: Model) -> None:
con = Constraint(data, m, "c")

expr = m.add_constraints(con)
assert not set(HELPER_DIMS).intersection(set(expr.data.coords))
assert not set(HELPER_DIMS).intersection(set(expr.coords))


def test_constraint_matrix(m: Model) -> None:
Expand Down
54 changes: 27 additions & 27 deletions test/test_linear_expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_linexpr_with_helper_dims_as_coords(m: Model) -> None:
assert set(HELPER_DIMS).intersection(set(data.coords))

expr = LinearExpression(data, m)
assert not set(HELPER_DIMS).intersection(set(expr.data.coords))
assert not set(HELPER_DIMS).intersection(set(expr.coords))


def test_linexpr_with_data_without_coords(m: Model) -> None:
Expand Down Expand Up @@ -558,7 +558,7 @@ def test_matmul_contracts_only_shared_dims(z: Variable) -> None:
expr = 1 * z
b = xr.DataArray(
np.ones((3, 2)),
coords={"dim_1": expr.data.indexes["dim_1"], "location": ["L1", "L2"]},
coords={"dim_1": expr.indexes["dim_1"], "location": ["L1", "L2"]},
dims=["dim_1", "location"],
)

Expand All @@ -574,8 +574,8 @@ def test_matmul_contracts_all_dims_when_const_covers_them(z: Variable) -> None:
b = xr.DataArray(
np.ones((2, 3, 2)),
coords={
"dim_0": expr.data.indexes["dim_0"],
"dim_1": expr.data.indexes["dim_1"],
"dim_0": expr.indexes["dim_0"],
"dim_1": expr.indexes["dim_1"],
"location": ["L1", "L2"],
},
dims=["dim_0", "dim_1", "location"],
Expand Down Expand Up @@ -2061,35 +2061,35 @@ def test_add_join_none_preserves_default(

def test_add_expr_join_inner(self, a: Variable, b: Variable) -> None:
result = a.to_linexpr().add(b.to_linexpr(), join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_add_expr_join_outer(self, a: Variable, b: Variable) -> None:
result = a.to_linexpr().add(b.to_linexpr(), join="outer")
assert list(result.data.indexes["i"]) == [0, 1, 2, 3]
assert list(result.indexes["i"]) == [0, 1, 2, 3]

def test_add_expr_join_left(self, a: Variable, b: Variable) -> None:
result = a.to_linexpr().add(b.to_linexpr(), join="left")
assert list(result.data.indexes["i"]) == [0, 1, 2]
assert list(result.indexes["i"]) == [0, 1, 2]

def test_add_expr_join_right(self, a: Variable, b: Variable) -> None:
result = a.to_linexpr().add(b.to_linexpr(), join="right")
assert list(result.data.indexes["i"]) == [1, 2, 3]
assert list(result.indexes["i"]) == [1, 2, 3]

def test_add_constant_join_inner(self, a: Variable) -> None:
const = xr.DataArray([10, 20, 30], dims=["i"], coords={"i": [1, 2, 3]})
result = a.to_linexpr().add(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_add_constant_join_outer(self, a: Variable) -> None:
const = xr.DataArray([10, 20, 30], dims=["i"], coords={"i": [1, 2, 3]})
result = a.to_linexpr().add(const, join="outer")
assert list(result.data.indexes["i"]) == [0, 1, 2, 3]
assert list(result.indexes["i"]) == [0, 1, 2, 3]

def test_add_constant_join_override(self, a: Variable, c: Variable) -> None:
expr = a.to_linexpr()
const = xr.DataArray([10, 20, 30], dims=["i"], coords={"i": [0, 1, 2]})
result = expr.add(const, join="override")
assert list(result.data.indexes["i"]) == [0, 1, 2]
assert list(result.indexes["i"]) == [0, 1, 2]
assert (result.const.values == const.values).all()

def test_add_same_coords_all_joins(self, a: Variable, c: Variable) -> None:
Expand All @@ -2110,7 +2110,7 @@ def test_add_scalar_with_explicit_join(self, a: Variable) -> None:
class TestSubtraction:
def test_sub_expr_join_inner(self, a: Variable, b: Variable) -> None:
result = a.to_linexpr().sub(b.to_linexpr(), join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_sub_constant_override(self, a: Variable) -> None:
expr = 1 * a + 5
Expand All @@ -2123,12 +2123,12 @@ class TestMultiplication:
def test_mul_constant_join_inner(self, a: Variable) -> None:
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = a.to_linexpr().mul(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_mul_constant_join_outer(self, a: Variable) -> None:
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = a.to_linexpr().mul(const, join="outer")
assert list(result.data.indexes["i"]) == [0, 1, 2, 3]
assert list(result.indexes["i"]) == [0, 1, 2, 3]
assert result.coeffs.sel(i=0).item() == 0
assert result.coeffs.sel(i=1).item() == 2
assert result.coeffs.sel(i=2).item() == 3
Expand All @@ -2141,12 +2141,12 @@ class TestDivision:
def test_div_constant_join_inner(self, a: Variable) -> None:
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = a.to_linexpr().div(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_div_constant_join_outer(self, a: Variable) -> None:
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = a.to_linexpr().div(const, join="outer")
assert list(result.data.indexes["i"]) == [0, 1, 2, 3]
assert list(result.indexes["i"]) == [0, 1, 2, 3]

def test_div_expr_with_join_raises(self, a: Variable, b: Variable) -> None:
with pytest.raises(TypeError):
Expand All @@ -2155,21 +2155,21 @@ def test_div_expr_with_join_raises(self, a: Variable, b: Variable) -> None:
class TestVariableOperations:
def test_variable_add_join(self, a: Variable, b: Variable) -> None:
result = a.add(b, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_variable_sub_join(self, a: Variable, b: Variable) -> None:
result = a.sub(b, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_variable_mul_join(self, a: Variable) -> None:
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = a.mul(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_variable_div_join(self, a: Variable) -> None:
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = a.div(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_variable_add_outer_values(self, a: Variable, b: Variable) -> None:
result = a.add(b, join="outer")
Expand All @@ -2195,14 +2195,14 @@ def test_variable_div_override(self, a: Variable) -> None:

def test_same_shape_add_join_override(self, a: Variable, c: Variable) -> None:
result = a.to_linexpr().add(c.to_linexpr(), join="override")
assert list(result.data.indexes["i"]) == [0, 1, 2]
assert list(result.indexes["i"]) == [0, 1, 2]

class TestMerge:
def test_merge_join_parameter(self, a: Variable, b: Variable) -> None:
result = merge(
[a.to_linexpr(), b.to_linexpr()], cls=LinearExpression, join="inner"
)
assert list(result.data.indexes["i"]) == [1, 2]
assert list(result.indexes["i"]) == [1, 2]

def test_merge_outer_join(self, a: Variable, b: Variable) -> None:
result = merge(
Expand All @@ -2214,13 +2214,13 @@ def test_merge_join_left(self, a: Variable, b: Variable) -> None:
result = merge(
[a.to_linexpr(), b.to_linexpr()], cls=LinearExpression, join="left"
)
assert list(result.data.indexes["i"]) == [0, 1, 2]
assert list(result.indexes["i"]) == [0, 1, 2]

def test_merge_join_right(self, a: Variable, b: Variable) -> None:
result = merge(
[a.to_linexpr(), b.to_linexpr()], cls=LinearExpression, join="right"
)
assert list(result.data.indexes["i"]) == [1, 2, 3]
assert list(result.indexes["i"]) == [1, 2, 3]

class TestValueVerification:
def test_add_expr_outer_const_values(self, a: Variable, b: Variable) -> None:
Expand Down Expand Up @@ -2319,18 +2319,18 @@ def test_quadratic_add_constant_join_inner(
quad = a.to_linexpr() * b.to_linexpr()
const = xr.DataArray([10, 20, 30], dims=["i"], coords={"i": [1, 2, 3]})
result = quad.add(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2, 3]
assert list(result.indexes["i"]) == [1, 2, 3]

def test_quadratic_add_expr_join_inner(self, a: Variable) -> None:
quad = a.to_linexpr() * a.to_linexpr()
const = xr.DataArray([10, 20], dims=["i"], coords={"i": [0, 1]})
result = quad.add(const, join="inner")
assert list(result.data.indexes["i"]) == [0, 1]
assert list(result.indexes["i"]) == [0, 1]

def test_quadratic_mul_constant_join_inner(
self, a: Variable, b: Variable
) -> None:
quad = a.to_linexpr() * b.to_linexpr()
const = xr.DataArray([2, 3, 4], dims=["i"], coords={"i": [1, 2, 3]})
result = quad.mul(const, join="inner")
assert list(result.data.indexes["i"]) == [1, 2, 3]
assert list(result.indexes["i"]) == [1, 2, 3]
14 changes: 7 additions & 7 deletions test/test_quadratic_expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_quadratic_expression_from_variables_multiplication(
) -> None:
quad_expr = x * y
assert isinstance(quad_expr, QuadraticExpression)
assert quad_expr.data.sizes[FACTOR_DIM] == 2
assert quad_expr.vars.sizes[FACTOR_DIM] == 2


def test_adding_quadratic_expressions(x: Variable) -> None:
Expand All @@ -52,7 +52,7 @@ def test_quadratic_expression_from_variables_power(x: Variable) -> None:
power_expr = x**2
target: QuadraticExpression = x * x # type: ignore
assert isinstance(power_expr, QuadraticExpression)
assert power_expr.data.sizes[FACTOR_DIM] == 2
assert power_expr.vars.sizes[FACTOR_DIM] == 2
assert_quadequal(power_expr, target)
assert_quadequal(x.pow(2), target)

Expand All @@ -63,23 +63,23 @@ def test_quadratic_expression_from_linexpr_multiplication(
mult_expr = (10 * x + y) * y
target: QuadraticExpression = 10 * x * y + y * y # type: ignore
assert isinstance(mult_expr, QuadraticExpression)
assert mult_expr.data.sizes[FACTOR_DIM] == 2
assert mult_expr.vars.sizes[FACTOR_DIM] == 2
assert mult_expr.nterm == 2
assert_quadequal(mult_expr, target)


def test_quadratic_expression_from_linexpr_power(x: Variable) -> None:
expr = (10 * x) ** 2
assert isinstance(expr, QuadraticExpression)
assert expr.data.sizes[FACTOR_DIM] == 2
assert expr.vars.sizes[FACTOR_DIM] == 2
assert expr.nterm == 1


def test_quadratic_expression_from_linexpr_with_constant_power(x: Variable) -> None:
expr = (10 * x + 5) ** 2
target: QuadraticExpression = 100 * x * x + 50 * x + 50 * x + 25 # type: ignore
assert isinstance(expr, QuadraticExpression)
assert expr.data.sizes[FACTOR_DIM] == 2
assert expr.vars.sizes[FACTOR_DIM] == 2
assert expr.nterm == 3
assert_quadequal(expr, target)

Expand All @@ -90,7 +90,7 @@ def test_quadratic_expression_from_linexpr_with_constant_multiplation(
expr: QuadraticExpression = (10 * x + 5) * (y + 5) # type: ignore
target: QuadraticExpression = 10 * x * y + 5 * y + 50 * x + 25 # type: ignore
assert isinstance(expr, QuadraticExpression)
assert expr.data.sizes[FACTOR_DIM] == 2
assert expr.vars.sizes[FACTOR_DIM] == 2
assert expr.nterm == 3
assert_quadequal(expr, target)

Expand Down Expand Up @@ -133,7 +133,7 @@ def test_matmul_with_const(x: Variable) -> None:
expr2 = expr @ const
assert isinstance(expr2, QuadraticExpression)
assert expr2.nterm == 2
assert expr2.data.sizes[FACTOR_DIM] == 2
assert expr2.vars.sizes[FACTOR_DIM] == 2


def test_quadratic_expression_dot_and_matmul(x: Variable, y: Variable) -> None:
Expand Down
22 changes: 11 additions & 11 deletions test/test_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def test_bound_types_with_coords(
var = model.add_variables(lower=lower, coords=coords, name="x")
assert var.shape == (3,)
assert var.dims == ("x",)
assert list(var.data.coords["x"].values) == [0, 1, 2]
assert list(var.coords["x"].values) == [0, 1, 2]

# -- DataArray validation: mismatch and extra dims ---------------------

Expand Down Expand Up @@ -569,7 +569,7 @@ def test_bound_broadcast_missing_dim(
assert var.dims == ("time", "space", "colour")
assert var.data.lower.dims == ("time", "space", "colour")
assert var.data.upper.dims == ("time", "space", "colour")
assert var.data.sizes == {"time": 3, "space": 2, "colour": 1}
assert var.sizes == {"time": 3, "space": 2, "colour": 1}
assert not var.data.lower.isnull().any()
assert (var.data.lower.sel(space="a", colour="red") == [-1, -2, -3]).all()
assert (var.data.lower.sel(space="b", colour="red") == [-1, -2, -3]).all()
Expand Down Expand Up @@ -607,7 +607,7 @@ def test_xarray_coordinates_object(self, model: "Model") -> None:
time = pd.RangeIndex(3, name="time")
base = model.add_variables(lower=0, coords=[time], name="base")
lower = DataArray([1, 1, 1], dims=["time"], coords={"time": range(3)})
var = model.add_variables(lower=lower, coords=base.data.coords, name="x2")
var = model.add_variables(lower=lower, coords=base.coords, name="x2")
assert var.shape == (3,)

# -- Mixed bound type combinations ------------------------------------
Expand Down Expand Up @@ -665,7 +665,7 @@ def test_both_dataarray_different_dim_subsets(self, model: "Model") -> None:
var = model.add_variables(
lower=lower, upper=upper, coords=[time, space], name="x"
)
assert var.data.sizes == {"time": 3, "space": 2}
assert var.sizes == {"time": 3, "space": 2}
assert not var.data.lower.isnull().any()
assert not var.data.upper.isnull().any()
assert (var.data.upper.sel(time=0) == [10, 20]).all()
Expand Down Expand Up @@ -698,7 +698,7 @@ def test_coords_inferred_from_bounds(self, model: "Model", lower: Any) -> None:
"""When coords is None, dims/coords are inferred from the bounds."""
var = model.add_variables(lower=lower, name="x")
assert var.dims == ("x",)
assert list(var.data.coords["x"].values) == [10, 20, 30]
assert list(var.coords["x"].values) == [10, 20, 30]

def test_coords_inferred_multidim(self, model: "Model") -> None:
lower = DataArray(
Expand All @@ -708,7 +708,7 @@ def test_coords_inferred_multidim(self, model: "Model") -> None:
)
var = model.add_variables(lower=lower, name="x")
assert set(var.dims) == {"time", "space"}
assert var.data.sizes == {"time": 3, "space": 2}
assert var.sizes == {"time": 3, "space": 2}

# -- Multi-dimensional coords -----------------------------------------

Expand All @@ -728,7 +728,7 @@ def test_coords_inferred_multidim(self, model: "Model") -> None:
def test_multidim_coords_with_scalar(self, model: "Model", coords: Any) -> None:
var = model.add_variables(lower=0, upper=1, coords=coords, name="x")
assert set(var.dims) == {"time", "space"}
assert var.data.sizes == {"time": 3, "space": 2}
assert var.sizes == {"time": 3, "space": 2}

def test_multidim_dataarray_with_coords(self, model: "Model") -> None:
lower = DataArray(
Expand All @@ -739,7 +739,7 @@ def test_multidim_dataarray_with_coords(self, model: "Model") -> None:
coords = [pd.RangeIndex(3, name="time"), pd.Index(["a", "b"], name="space")]
var = model.add_variables(lower=lower, coords=coords, name="x")
assert set(var.dims) == {"time", "space"}
assert var.data.sizes == {"time": 3, "space": 2}
assert var.sizes == {"time": 3, "space": 2}
assert not var.data.lower.isnull().any()

def test_bounds_with_different_dim_order(self, model: "Model") -> None:
Expand All @@ -759,7 +759,7 @@ def test_bounds_with_different_dim_order(self, model: "Model") -> None:
var = model.add_variables(
lower=lower, upper=upper, coords=[time, space], name="x"
)
assert var.data.sizes == {"time": 3, "space": 2}
assert var.sizes == {"time": 3, "space": 2}
assert (var.data.lower.values == 0).all()
assert (var.data.upper.values == 1).all()

Expand All @@ -769,7 +769,7 @@ def test_reordered_coords_reindexed(self, model: "Model") -> None:
"""Same coord values in different order should reindex, not raise."""
lower = DataArray([10, 20, 30], dims=["x"], coords={"x": ["c", "a", "b"]})
var = model.add_variables(lower=lower, coords={"x": ["a", "b", "c"]}, name="x")
assert list(var.data.coords["x"].values) == ["a", "b", "c"]
assert list(var.coords["x"].values) == ["a", "b", "c"]
# Values must follow the reindexed order, not the original
assert list(var.data.lower.values) == [20, 30, 10]

Expand All @@ -790,7 +790,7 @@ def test_string_coordinates(self, model: "Model") -> None:
)
var = model.add_variables(lower=lower, coords=coords, name="x")
assert var.dims == ("region",)
assert list(var.data.coords["region"].values) == ["north", "south", "east"]
assert list(var.coords["region"].values) == ["north", "south", "east"]

def test_datetime_coordinates(self, model: "Model") -> None:
dates = pd.date_range("2025-01-01", periods=3)
Expand Down
Loading