mathspec
Write an optimisation model as a YAML file. Check it and print it as math, with no data and no solver.
A mathspec file declares four things: the axes the model runs over, such as
snapshot and generator; the data it expects, such as load and cost; the
decisions the solver makes, such as dispatch; and the rules those decisions
obey, such as sum(dispatch, over=generator) == load. The file
below is a complete model.
mathspec builds nothing and solves nothing itself. specsolve and linopy build and solve a mathspec model. Support in both is work in progress.
- Check models in CI, with no data. A wrong name or dimension fails when the file loads, and the error names the fix. Errors →
- Publish the math you solve. The equations in the paper print from the file the solver reads. Typeset →
- One model, many tools. Engines, renderers and analysers read the model through one public API, so no two of them can read the file differently. Program API →
- Write full-size models. PyPSA's
n.optimize()model is one file, with stochastic, multi-period and quadratic variants. PyPSA in one file →
Example
description: Least-cost dispatch of a generator fleet against an hourly load.
dimensions:
snapshot: { dtype: int, description: dispatch periods }
generator: { description: generating units }
parameters:
capacity: { dims: [generator], description: installed capacity }
load: { dims: [snapshot], description: demand to be met }
cost: { dims: [generator], description: marginal cost }
variables:
dispatch:
description: output of a generator in a snapshot
dims: [snapshot, generator]
where: "capacity > 0"
bounds: { lower: 0, upper: capacity }
constraints:
power_balance:
dims: [snapshot]
expression: sum(dispatch, over=generator) == load
objective:
sense: minimize
expression: sum(dispatch * cost)
The math it prints
The typesetter prints the file above as math, with no data and no solver. Markdown is one of three formats, and GitHub renders it here.
Least-cost dispatch of a generator fleet against an hourly load.
Objective
\min \sum_{t \in \mathcal{T},\ g \in \mathcal{G}} \mathit{dispatch}_{t,g} \cdot \mathrm{cost}_{g}
Subject to
power_balance
\sum_{g \in \mathcal{G}} \mathit{dispatch}_{t,g} = \mathrm{load}_{t} \qquad \forall\, t \in \mathcal{T}
Variable domains
dispatch
0 \le \mathit{dispatch}_{t,g} \le \mathrm{capacity}_{g} \qquad \forall\, t \in \mathcal{T},\ g \in \mathcal{G} \,:\, \mathrm{capacity}_{g} > 0
The whole document: a symbol table, and the legend it prints
Least-cost dispatch of a generator fleet against an hourly load.
Sets
| Symbol | Meaning |
|---|---|
$\mathcal{S}$ |
index $s$ — snapshot — dispatch periods |
$\mathcal{G}$ |
index $g$ — generator — generating units |
Parameters
| Symbol | Meaning |
|---|---|
$\bar p$ |
capacity over $\mathcal{G}$ — installed capacity |
$\ell$ |
load over $\mathcal{S}$ — demand to be met |
$c$ |
cost over $\mathcal{G}$ — marginal cost |
Variables
| Symbol | Meaning |
|---|---|
$\mathit{dispatch}$ |
dispatch over $\mathcal{S} \times \mathcal{G}$ — output of a generator in a snapshot |
Objective
$\min \sum_{s \in \mathcal{S},\ g \in \mathcal{G}} \mathit{dispatch}_{s,g} \cdot c_{g}$
Subject to
power_balance
$\sum_{g \in \mathcal{G}} \mathit{dispatch}_{s,g} = \ell_{s} \qquad \forall\, s \in \mathcal{S}$
Variable domains
dispatch
$0 \le \mathit{dispatch}_{s,g} \le \bar p_{g} \qquad \forall\, s \in \mathcal{S},\ g \in \mathcal{G} \,:\, \bar p_{g} > 0$
Each format is one call:
import mathspec as ms
spec = ms.to_spec('dispatch.yaml')
ms.to_markdown(spec)
ms.to_latex(spec)
ms.to_typst(spec)
A symbol table gives the names their conventional spelling, as in the folded block. Print a model as math does the same from a shell.
Documentation
The documentation is at https://mathspec.readthedocs.io.
Installation
See installation. To work on mathspec, see contributing.
Prior art
Every file under src/ was written in specsolve
and extracted here. The keys themselves,
which are YAML math, a block per component, dims: and a where: string,
come from Calliope.
linopy supplies the vocabulary that
sum(over=) and the dimension rules are named against.
Status
Alpha, pre-1.0.
Breaking changes land without a deprecation cycle. Pin an exact version if you depend on this, and read the changelog before upgrading. Every construct round-trips through the schema, the parsers and all three typeset formats, and the LaTeX is compiled. The accepted YAML is not yet frozen.
Licence
Release files for mathspec 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mathspec-0.1.0.tar.gz | 151.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mathspec-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 308.9 kB
Release files / mathspec-0.1.0.tar.gz
| Download URL | mathspec-0.1.0.tar.gz |
|---|---|
| Size | 151.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
368725fbb337e7c682af7352b3ec38828027730fc36f145ff36aeb6bb808aa65
|
|
BLAKE2b-256 checksum How to use checksums |
342085803dceab6dc37ae08067d2388106427c942e60891462c9526e24023b64
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / mathspec-0.1.0-py3-none-any.whl
| Download URL | mathspec-0.1.0-py3-none-any.whl |
|---|---|
| Size | 157.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
babf3d173806ff7462590af9c9691ad62b4560fec2e5ee8b23a021cdf69a89c1
|
|
BLAKE2b-256 checksum How to use checksums |
e4f22359d581003d138cc1fcb7646569fa0936c4f875e7ba119f4d2bd3fe0f94
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log