Skip to main content

mathspec

CI conda-forge pypi-version python-version Documentation build status

Write the specification (spec) of an optimisation model as a YAML file. Check it and print it as math, with no data and no solver.

A spec declares four things: the dimensions it 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 spec.

  • Check specs 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 spec, many tools. Engines, renderers and analysers read the spec through one public API, so no two of them can read the file differently. Program API →
  • Write full-size specs. The spec of 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.

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

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

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$

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

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 spec as math does the same from a shell.

Engines and other tools

mathspec builds nothing and solves nothing itself. Instead, specsolve and linopy build a model from a spec and its data, and solve it. Support in both is work in progress. Any other tool can read the same spec through the Program API. The solid boxes are mathspec; the dashed boxes are outside it.

flowchart LR
    accTitle: What mathspec does, and what other tools do with a spec
    accDescr: A YAML file loads into a Spec and the Program it lowers to. mathspec checks the spec and prints it as math, with no data. Outside mathspec, drawn dashed, an engine such as specsolve or linopy reads the same spec, takes your data and returns your answers, and any other tool, such as a renderer or an analyser, reads the same spec through the Program API.
    Y(["your spec<br/>one YAML file"]) --> SPEC["<b>Spec</b> and the <b>Program</b> it lowers to<br/><i>checked before any data exists</i>"]
    SPEC --> CHECK["<b>check it</b><br/>python -m mathspec check"]
    SPEC --> SHOW["<b>print it as math</b><br/>LaTeX · Typst · Markdown"]
    SPEC -.-> OTHER["<b>your own tool</b><br/>a renderer · an analyser · …<br/>reads the Program API"]
    SPEC -.-> ENGINE["<b>an engine</b><br/>specsolve · linopy<br/>builds and solves the model"]
    DATA[("your data")] -.-> ENGINE
    ENGINE -.-> ANS(["your answers"])
    classDef outside stroke-dasharray:5 4
    class ENGINE,DATA,ANS,OTHER outside

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 come from Calliope: math in YAML, one block per component, dims: and a where: string. sum(over=) and the dimension rules take their names from linopy.

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. The test suite passes every construct through the schema, the parsers and all three typeset formats, and compiles the LaTeX. The YAML that mathspec accepts can still change.

Licence

The code is MIT, and the prose is CC-BY-4.0.

Metadata

Release files for mathspec 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mathspec 0.3.0
File Size Uploaded
mathspec-0.3.0.tar.gz 177.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mathspec 0.3.0
File Interpreter ABI Platform
mathspec-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 363.0 kB

Release files / mathspec-0.3.0.tar.gz

Download URL mathspec-0.3.0.tar.gz
Size 177.7 kB
Tags Source
SHA-256 checksum
How to use checksums
16b875b6b70af859e8fffae34fbf8d3a252f7b5009c61558696411e274e8e845
BLAKE2b-256 checksum
How to use checksums
22ec0dee85ffed9e7e9af0c16e32a92d877f6767a337ec83c833bc48ea036039
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 Oct 15, 2026.

Transparency log

Release files / mathspec-0.3.0-py3-none-any.whl

Download URL mathspec-0.3.0-py3-none-any.whl
Size 185.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
613f3fa1bb36bcffe490290fed42d7966529593054a4fe560392d7442b83f4f0
BLAKE2b-256 checksum
How to use checksums
3f7e5c6f0e3c89881a247f159987d8ee12d3c985fa5b10bd572fe12eeac3766e
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 Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page