-
Notifications
You must be signed in to change notification settings - Fork 78
Description
Based on the discussion in #256, I started using <variable>.loc[indices] in arithmetic expressions and observed some inconsistencies (or I still do not understand the behaviour to 100% ^^)
Following setup:
import xarray as xr
import linopy
m = linopy.Model()
# 2 days, hourly (48 hours)
t = [0, 1, 2, 3]
n = ["a", "b"]
level = m.add_variables(coords=[t, n], name="level", dims=["time", "node"])
alpha = xr.DataArray([[1, 2], [3, 4], [5, 6], [7, 8]], coords=level.coords)
other_times = [2, 0, 3, 1]
other_time_level = level.loc[dict(time=other_times)]
Some arithmetic expressions
level + other_time_level works as expected, coordinates are overridden based on level
LinearExpression (time: 4, node: 2):
------------------------------------
[0, a]: +1 level[0, a] + 1 level[2, a]
[0, b]: +1 level[0, b] + 1 level[2, b]
[1, a]: +1 level[1, a] + 1 level[0, a]
[1, b]: +1 level[1, b] + 1 level[0, b]
[2, a]: +1 level[2, a] + 1 level[3, a]
[2, b]: +1 level[2, b] + 1 level[3, b]
[3, a]: +1 level[3, a] + 1 level[1, a]
[3, b]: +1 level[3, b] + 1 level[1, b]
When using level + alpha * other_time_level, I would have expected to get
LinearExpression (time: 4, node: 2):
------------------------------------
[0, a]: +1 level[0, a] + 1 level[2, a]
[0, b]: +1 level[0, b] + 2 level[2, b]
[1, a]: +1 level[1, a] + 3 level[0, a]
[1, b]: +1 level[1, b] + 4 level[0, b]
[2, a]: +1 level[2, a] + 5 level[3, a]
[2, b]: +1 level[2, b] + 6 level[3, b]
[3, a]: +1 level[3, a] + 7 level[1, a]
[3, b]: +1 level[3, b] + 8 level[1, b]
since I though that alpha would be term to define the coordinates in alpha * other_time_level
However, what I actually get is the following (coordinates of other_time_level are sorted according to the original time index again)
LinearExpression (time: 4, node: 2):
------------------------------------
[0, a]: +1 level[0, a] + 1 level[0, a]
[0, b]: +1 level[0, b] + 2 level[0, b]
[1, a]: +1 level[1, a] + 3 level[1, a]
[1, b]: +1 level[1, b] + 4 level[1, b]
[2, a]: +1 level[2, a] + 5 level[2, a]
[2, b]: +1 level[2, b] + 6 level[2, b]
[3, a]: +1 level[3, a] + 7 level[3, a]
[3, b]: +1 level[3, b] + 8 level[3, b]
Interestingly, the result changes when transforming other_time_level into a LinearExpression first, i.e., call level + alpha * other_time_level.to_linexpr()
LinearExpression (time: 4, node: 2):
------------------------------------
[0, a]: +1 level[0, a] + 5 level[2, a]
[0, b]: +1 level[0, b] + 6 level[2, b]
[1, a]: +1 level[1, a] + 1 level[0, a]
[1, b]: +1 level[1, b] + 2 level[0, b]
[2, a]: +1 level[2, a] + 7 level[3, a]
[2, b]: +1 level[2, b] + 8 level[3, b]
[3, a]: +1 level[3, a] + 3 level[1, a]
[3, b]: +1 level[3, b] + 4 level[1, b]
Finally, I tried to simply add alpha instead of multiplying it, i.e., level + alpha + other_time_level and this gives the expected result in terms of sorting the single terms into the expected rows:
LinearExpression (time: 4, node: 2):
------------------------------------
[0, a]: +1 level[0, a] + 1 level[2, a] + 1
[0, b]: +1 level[0, b] + 1 level[2, b] + 2
[1, a]: +1 level[1, a] + 1 level[0, a] + 3
[1, b]: +1 level[1, b] + 1 level[0, b] + 4
[2, a]: +1 level[2, a] + 1 level[3, a] + 5
[2, b]: +1 level[2, b] + 1 level[3, b] + 6
[3, a]: +1 level[3, a] + 1 level[1, a] + 7
[3, b]: +1 level[3, b] + 1 level[1, b] + 8
So my question would be: How to achieve the intended result and is all of the behaviour as it should be?