linopy.model.Model.add_variables#
- Model.add_variables(lower=-inf, upper=inf, coords=None, name=None, mask=None, binary=False, integer=False, semi_continuous=False, **kwargs)#
Assign a new, possibly multi-dimensional array of variables to the model.
Variables may be added with lower and/or upper bounds. Unless a coords argument is provided, the shape of the lower and upper bounds define the number of variables which will be added to the model under the name name.
- Parameters:
lower (
float/array_like, optional) – Lower bound of the variable(s). Ignored if binary is True. The default is -inf.upper (
TYPE, optional) – Upper bound of the variable(s). Ignored if binary is True. The default is inf.coords (
list/dict/xarray.Coordinates, optional) – The coords of the variable array. When provided with named dimensions (aMapping,xarray.Coordinates, a sequence of namedpd.Indexobjects, or an unnamed sequence paired withdims=in**kwargs),coordsis the source of truth for the variable’s dimensions, order, and values.lower,upperandmaskare aligned to this contract:dims of every bound must be a subset of
coords.dims; extra dims raiseValueError;dim order in the variable always follows
coords;shared-dim coordinate values must equal
coords; same values in a different order are auto-reindexed, different value sets raiseValueError;dims listed in
coordsbut missing from a bound are broadcast tocoordsshape.
One optimization variable is added per combination of coordinates. The default is
None, in which case the shape is inferred from the bounds.name (
str, optional) – Reference name of the added variables. The default None results in a name like “var1”, “var2” etc.mask (
array_like, optional) – Boolean mask with False values for variables which are skipped. The shape of the mask has to match the shape the added variables. Default is None.binary (
bool) – Whether the new variable is a binary variable which are used for Mixed-Integer problems.integer (
bool) – Whether the new variable is a integer variable which are used for Mixed-Integer problems.semi_continuous (
bool) – Whether the new variable is a semi-continuous variable. A semi-continuous variable can take the value 0 or any value between its lower and upper bounds. Requires a positive lower bound.**kwargs – Additional keyword arguments are passed to the DataArray creation.
- Raises:
ValueError – If neither lower bound and upper bound have coordinates, nor coords are directly given.
- Returns:
linopy.Variable– Variable which was added to the model.
Examples
>>> from linopy import Model >>> import pandas as pd >>> m = Model() >>> time = pd.RangeIndex(10, name="Time") >>> m.add_variables(lower=0, coords=[time], name="x") Variable (Time: 10) ------------------- [0]: x[0] ∈ [0, inf] [1]: x[1] ∈ [0, inf] [2]: x[2] ∈ [0, inf] [3]: x[3] ∈ [0, inf] [4]: x[4] ∈ [0, inf] [5]: x[5] ∈ [0, inf] [6]: x[6] ∈ [0, inf] [7]: x[7] ∈ [0, inf] [8]: x[8] ∈ [0, inf] [9]: x[9] ∈ [0, inf]
Strict coords-as-truth: a bound with an extra dim raises.
>>> import xarray as xr >>> m = Model() >>> bad = xr.DataArray( ... [[1.0, 2.0, 3.0]] * 2, ... dims=["extra", "x"], ... coords={"x": [0, 1, 2]}, ... ) >>> m.add_variables(lower=bad, coords=[pd.Index([0, 1, 2], name="x")], name="v") Traceback (most recent call last): ... ValueError: lower bound has dimension(s) ['extra'] not declared in coords ...
Strict coords-as-truth: a bound whose shared-dim values don’t match raises.
>>> m = Model() >>> wrong = xr.DataArray( ... [1.0, 2.0, 3.0], dims=["x"], coords={"x": [10, 20, 30]} ... ) >>> m.add_variables( ... lower=wrong, coords=[pd.Index([0, 1, 2], name="x")], name="v" ... ) Traceback (most recent call last): ... ValueError: lower bound: coordinate values for dimension 'x' do not match coords ...
Strict coords-as-truth, helpful side: a bound whose coord values match
coordsonly in a different order is auto-reindexed.>>> m = Model() >>> reordered = xr.DataArray( ... [3.0, 1.0, 2.0], dims=["x"], coords={"x": ["c", "a", "b"]} ... ) >>> v = m.add_variables( ... lower=reordered, ... coords=[pd.Index(["a", "b", "c"], name="x")], ... name="r", ... ) >>> v.lower.values.tolist() [1.0, 2.0, 3.0]
Unnamed-coords sequence +
dims=opts into the same strict enforcement as a named index — extra dims still raise.>>> m = Model() >>> m.add_variables(lower=bad, coords=[[0, 1, 2]], dims=["x"], name="w") Traceback (most recent call last): ... ValueError: lower bound has dimension(s) ['extra'] not declared in coords ...
The same strict contract applies to
mask(including withcoords=[[...]], dims=[...]).>>> m = Model() >>> m.add_variables(mask=bad, coords=[[0, 1, 2]], dims=["x"], name="wm") Traceback (most recent call last): ... ValueError: mask has dimension(s) ['extra'] not declared in coords ...