Skip to content

One construct per model#

For each built-in operator, the smallest model that declares it, beside the equation it prints. The reference page shows the same equations as one table. This page shows the file that produced each one.

sum(array)#

examples/operators/sum_all.yaml

description: Every dimension at once — `sum(array)` names none of them and takes them all.

dimensions:
  snapshot: { dtype: int }
  generator: { dtype: str }

parameters:
  budget: { dims: [] }

variables:
  p:
    dims: [snapshot, generator]
    bounds: { lower: 0 }

constraints:
  fleet_budget:
    dims: []
    expression: sum(p) <= budget

objective: { sense: minimize, expression: sum(p) }

\(\sum_{t \in \mathcal{T},\ g \in \mathcal{G}} p_{t,g} \le \mathrm{budget}\)

sum(array, over=dim)#

examples/operators/sum.yaml

description: The plain reduction — `sum(array, over=dim)` collapses one dimension.

dimensions:
  snapshot: { dtype: int }
  generator: { dtype: str }

parameters:
  limit: { dims: [snapshot] }

variables:
  p:
    dims: [snapshot, generator]
    bounds: { lower: 0 }

constraints:
  fleet_total:
    dims: [snapshot]
    expression: sum(p, over=generator) <= limit

objective: { sense: minimize, expression: sum(p) }

\(\sum_{g \in \mathcal{G}} p_{t,g} \le \mathrm{limit}_{t} \qquad \forall\, t \in \mathcal{T}\)

sum(array, by=relation, over=a, into=b)#

examples/operators/sum_by.yaml

description: >-
  The membership reduction — `sum(array, by=relation, over=a, into=b)` lands the result on the
  column the relation is read to, which is what makes topology data rather than
  structure.

dimensions:
  snapshot: { dtype: int }
  generator: { dtype: str }
  bus: { dtype: str }

relations:
  gen_bus: { key: generator, values: bus }

parameters:
  limit: { dims: [snapshot, bus] }

variables:
  p:
    dims: [snapshot, generator]
    bounds: { lower: 0 }

constraints:
  bus_total:
    dims: [snapshot, bus]
    expression: sum(p, by=gen_bus, over=generator, into=bus) <= limit

objective: { sense: minimize, expression: sum(p) }

\(\sum_{g \in \mathcal{G} \,:\, \mathrm{gen\_bus}(g) = b} p_{t,g} \le \mathrm{limit}_{t,b} \qquad \forall\, t \in \mathcal{T},\ b \in \mathcal{B}\)

sum(array, by=relation, over=a, into=b), joining on the rest of the key#

examples/operators/sum_by_columns.yaml

description: >-
  A call that names its ends — `sum(array, by=relation, over=a, into=b)`
  consumes column `a` and lands on column `b`, and the other key column is
  joined on, so each zone's total is taken per period.

dimensions:
  generator: { dtype: str }
  period: { dtype: int }
  zone: { dtype: str }

relations:
  zone_of: { key: [generator, period], values: zone }

parameters:
  demand: { dims: [zone, period] }

variables:
  p:
    dims: [generator, period]
    bounds: { lower: 0 }

constraints:
  zone_balance:
    dims: [zone, period]
    expression: sum(p, by=zone_of, over=generator, into=zone) >= demand

objective: { sense: minimize, expression: sum(p) }

\(\sum_{g \in \mathcal{G} \,:\, \mathrm{zone\_of}(g,\ e) = z} p_{g,e} \ge \mathrm{demand}_{z,e} \qquad \forall\, z \in \mathcal{Z},\ e \in \mathcal{E}\)

sum(array, by=relation, over=[a, …], into=[b, …])#

examples/operators/sum_by_column_lists.yaml

description: >-
  A call with several columns at each end — `sum(array, by=relation, over=[a, …], into=[b, …])`
  consumes both key columns at once and lands on the product of both value
  columns in one join.

dimensions:
  generator: { dtype: str }
  period: { dtype: int }
  bus: { dtype: str }
  technology: { dtype: str }

relations:
  slot_of: { key: [generator, period], values: [bus, technology] }

parameters:
  cap: { dims: [bus, technology] }

variables:
  p:
    dims: [generator, period]
    bounds: { lower: 0 }

constraints:
  slot_cap:
    dims: [bus, technology]
    expression: sum(p, by=slot_of, over=[generator, period], into=[bus, technology]) <= cap

objective: { sense: minimize, expression: sum(p) }

\(\sum_{g \in \mathcal{G},\ e \in \mathcal{E} \,:\, \mathrm{slot\_of.bus}(g,\ e) = b \wedge \mathrm{slot\_of.technology}(g,\ e) = t} p_{g,e} \le \mathrm{cap}_{b,t} \qquad \forall\, b \in \mathcal{B},\ t \in \mathcal{T}\)

at(array, by=relation, over=a, into=b)#

examples/operators/at.yaml

description: >-
  The adjoint of the membership reduction — `at(array, by=relation, over=a, into=b)` reads one
  coarse value once per fine label pointing at it.

dimensions:
  snapshot: { dtype: int }
  period: { dtype: int }

relations:
  period_of: { key: snapshot, values: period }

parameters:
  cap: { dims: [period] }

variables:
  p:
    dims: [snapshot]
    bounds: { lower: 0 }

constraints:
  within_cap:
    dims: [snapshot]
    expression: p <= at(cap, by=period_of, over=period, into=snapshot)

objective: { sense: minimize, expression: sum(p) }

\(p_{t} \le \mathrm{cap}_{\mathrm{period\_of}(t)} \qquad \forall\, t \in \mathcal{T}\)

at(array, by=relation, over=a, into=b), two columns over one dimension#

examples/operators/at_columns.yaml

description: >-
  A read that names its ends — `at(array, by=relation, over=a, into=b)`
  reads column `a` where a table has two columns over one dimension, here the
  sending end of a line.

dimensions:
  line: { dtype: str }
  bus: { dtype: str }

relations:
  ends: { key: line, values: { bus0: bus, bus1: bus } }

parameters:
  cap: { dims: [bus] }

variables:
  f:
    dims: [line]
    bounds: { lower: 0 }

constraints:
  sending_cap:
    dims: [line]
    expression: f <= at(cap, by=ends, over=bus0, into=line)

objective: { sense: minimize, expression: sum(f) }

\(f_{l} \le \mathrm{cap}_{\mathrm{ends.bus0}(l)} \qquad \forall\, l \in \mathcal{L}\)

shift(array, along=dim, offset=n)#

examples/operators/shift.yaml

description: >-
  Translation with no edge policy — the vacated position is absent, so the row
  it would have fed is not built.

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) }

\(p_{t} \le p_{t - 1} \qquad \forall\, t \in \mathcal{T}\)

shift(array, along=dim, offset=n, edge='wrap')#

examples/operators/shift_wrap.yaml

description: >-
  Cyclic translation — the horizon closed on itself, so the first position
  reads the last and nothing is vacated.

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, edge='wrap')

objective: { sense: minimize, expression: sum(p) }

\(p_{t} \le p_{t \ominus 1} \qquad \forall\, t \in \mathcal{T}\)

shift(array, along=dim, offset=n, edge=v)#

examples/operators/shift_edge.yaml

description: >-
  Translation with a value at the edge — the vacated position contributes the
  number instead of being absent, so the row survives.

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, edge=0)

objective: { sense: minimize, expression: sum(p) }

\(p_{t} \le p_{t \boxminus_{0} 1} \qquad \forall\, t \in \mathcal{T}\)

shift(array, along=dim, offset=p, edge=…)#

examples/operators/shift_by_parameter.yaml

description: >-
  Translation by an offset that differs per entity — `by:` names an integer
  parameter, so each technology is reached by its own lead time rather than by
  one the file had to fix.

dimensions:
  technology: { dtype: str }
  month: { dtype: int }

parameters:
  lead: { dims: [technology], dtype: int }
  demand: { dims: [technology, month] }

variables:
  order:
    dims: [technology, month]
    bounds: { lower: 0 }

constraints:
  arrives_after_its_lead:
    dims: [technology, month]
    expression: shift(order, along=month, offset=lead, edge=0) >= demand

objective: { sense: minimize, expression: sum(order) }

\(\mathit{order}_{t,m \boxminus_{0} \mathrm{lead}} \ge \mathrm{demand}_{t,m} \qquad \forall\, t \in \mathcal{T},\ m \in \mathcal{M}\)

shift(array, along=dim, offset=n, by=relation, within=c)#

examples/operators/shift_partitioned.yaml

description: >-
  Translation inside a group — each season closed on itself, so a season's first
  snapshot reads that season's last and no level crosses the boundary.

dimensions:
  snapshot: { dtype: int }
  season: { dtype: str }

relations:
  season_of: { key: snapshot, values: season }

variables:
  p:
    dims: [snapshot]
    bounds: { lower: 0 }

constraints:
  no_faster_than_before_in_season:
    dims: [snapshot]
    expression: p <= shift(p, along=snapshot, offset=1, edge='wrap', by=season_of, within=season)

objective: { sense: minimize, expression: sum(p) }

\(p_{t} \le p_{t \ominus^{\mathrm{season\_of}(t)} 1} \qquad \forall\, t \in \mathcal{T}\)

sum_back(array, along=dim, window=n)#

examples/operators/sum_back.yaml

description: >-
  A trailing window of a fixed width: a unit that started in the last three
  hours is still on.

dimensions:
  unit: { dtype: str }
  hour: { dtype: int }

parameters:
  min_up: { dims: [unit], dtype: int }

variables:
  started:
    dims: [unit, hour]
    domain: binary
  on:
    dims: [unit, hour]
    domain: binary

constraints:
  stays_up_its_own_time:
    dims: [unit, hour]
    expression: sum_back(started, along=hour, window=3) <= on

objective: { sense: minimize, expression: sum(on) }

\(\sum_{h' \in \mathcal{H} \,:\, 0 \le h - h' < 3} \mathit{started}_{u,h'} \le \mathit{on}_{u,h} \qquad \forall\, u \in \mathcal{U},\ h \in \mathcal{H}\)

sum_back(array, along=dim, window=p)#

examples/operators/sum_back_by_parameter.yaml

description: >-
  A trailing window whose width is data — `within:` names an integer parameter,
  so a unit stays up for its *own* minimum time rather than one the file fixed.

dimensions:
  unit: { dtype: str }
  hour: { dtype: int }

parameters:
  min_up: { dims: [unit], dtype: int }

variables:
  started:
    dims: [unit, hour]
    domain: binary
  on:
    dims: [unit, hour]
    domain: binary

constraints:
  stays_up_its_own_time:
    dims: [unit, hour]
    expression: sum_back(started, along=hour, window=min_up) <= on

objective: { sense: minimize, expression: sum(on) }

\(\sum_{h' \in \mathcal{H} \,:\, 0 \le h - h' < \mathrm{min\_up}} \mathit{started}_{u,h'} \le \mathit{on}_{u,h} \qquad \forall\, u \in \mathcal{U},\ h \in \mathcal{H}\)

sum_back(array, along=dim, window=p, edge='wrap')#

examples/operators/sum_back_wrap.yaml

description: >-
  A trailing window on a representative period that repeats, so the window at
  the first hour reaches back into the last.

dimensions:
  unit: { dtype: str }
  hour: { dtype: int }

parameters:
  min_up: { dims: [unit], dtype: int }

variables:
  started:
    dims: [unit, hour]
    domain: binary
  on:
    dims: [unit, hour]
    domain: binary

constraints:
  stays_up_its_own_time:
    dims: [unit, hour]
    expression: sum_back(started, along=hour, window=min_up, edge='wrap') <= on

objective: { sense: minimize, expression: sum(on) }

\(\sum_{h' \in \mathcal{H} \,:\, 0 \le h \ominus h' < \mathrm{min\_up}} \mathit{started}_{u,h'} \le \mathit{on}_{u,h} \qquad \forall\, u \in \mathcal{U},\ h \in \mathcal{H}\)

sum_back(array, along=dim, window=n, by=relation, within=c)#

examples/operators/sum_back_partitioned.yaml

description: >-
  A window that stops at each group's edge: representative days are separate
  samples rather than consecutive hours, so a window must not reach across the
  boundary between two of them.

dimensions:
  unit: { dtype: str }
  hour: { dtype: int }
  day: { dtype: str }

relations:
  day_of: { key: hour, values: day }

variables:
  started:
    dims: [unit, hour]
    domain: binary
  on:
    dims: [unit, hour]
    domain: binary

constraints:
  stays_up_inside_its_day:
    dims: [unit, hour]
    expression: sum_back(started, along=hour, window=3, by=day_of, within=day) <= on

objective: { sense: minimize, expression: sum(on) }

\(\sum_{h' \in \mathcal{H} \,:\, 0 \le h -^{\mathrm{day\_of}(h)} h' < 3} \mathit{started}_{u,h'} \le \mathit{on}_{u,h} \qquad \forall\, u \in \mathcal{U},\ h \in \mathcal{H}\)

dual(constraint)#

examples/operators/dual.yaml

description: The row dual — `dual(constraint)` reads a solved constraint's shadow price over its own frame.

dimensions:
  snapshot: { dtype: int }

parameters:
  load: { dims: [snapshot] }

variables:
  p:
    dims: [snapshot]
    bounds: { lower: 0 }

constraints:
  balance:
    dims: [snapshot]
    expression: p >= load

expressions:
  price: dual(balance)

objective: { sense: minimize, expression: sum(p) }

\(\mathit{price}_{t} = \lambda_{\mathrm{balance},t} \qquad \forall\, t \in \mathcal{T}\)

Regenerate with pixi run python -m tools.gallery.