Changelog#
Each pull request adds its line under ## Upcoming version. A release pull
request renames that heading to the version and the day, such as
## 0.1.0 (2026-10-01), and edits the section into the release notes. Merging
it releases that version (RELEASING.md).
Upcoming version#
- feat(language)!: a call names the columns of a relation as relation[column], and a sum through a relation is a sum over the axes its join opens (#664)
- docs(pypsa): the pypsa page lists six more refusals and eight data-prep steps, and a capital cost says where fom_cost and overnight_cost enter (#816)
- docs(pypsa): a committable unit built in a later period starts from off, and the big M follows pypsa for an infinite build cap (#817)
- docs(pypsa): a line, a transformer, a storage unit and a store may be built in whole modules, and a unit that is not active counts no modules (#815)
- docs(pypsa): the cycle rows read each investment period's own cycle basis (#814)
- docs(pypsa): a start-up or shut-down cost may change from snapshot to snapshot, as in pypsa master (#807)
- docs(pypsa): a line or transformer limits its voltage angle difference, as in pypsa master (#808)
- docs(pypsa): the pypsa line references point at pypsa master (#806)
- docs(pypsa): a fixed modular committable unit gets only its per-module commitment rows, as in pypsa master (#787)
- docs(pypsa): the pypsa references are recorded against pypsa master (#786)
0.2.1 (2026-10-01)#
A spec can now be written as several files. merge
composes fragments, each a spec that owns part of the math and reads what
another file declares under given:. override
lays patches over a base, each changing part of it. A named expression adds
itself as a term to a sum with adds_to:, and one fragment sets the objective.
Every fragment typesets on its own, in LaTeX, Typst and Markdown, and gets
advice before any merge: what it reads from another file prints in its legend,
so one component's math can be reviewed without the rest of the model.
PyPSA in 24 files
is the PyPSA spec composed this way, and merges back to the one file.
Nothing a 0.2.0 file or call does stops working. Two rules of the language
are now stated exactly. A consumer that attaches data refuses a null or NaN
parameter value: a coordinate with no value has no row, and inf and -inf
are values (#788). And
dual(c) is the rate at which the optimal objective rises with the right side
of c, for every comparator and under either sense, which is what engines
return (#751).
The pull requests in this release:
Composition#
- feat(language): a spec is composed from files that each state part of it, and patched with files that each change part of it (#732)
- feat(language): a term names the sum it adds to with
adds_to:, agiven: expressions:entry of its own file, and a sum another file defines takes terms too (#763) - feat(language): merge refuses a second objective, and a composed objective reads a sum that each file adds its part to (#763)
- fix(language): merge and override take a list of files, and its order is the order of the terms and of the patches (#761)
- fix(language): a merged spec's descriptions do not depend on the order the fragments are passed in, and a reader's fills one its owner left out (#739)
- fix(language): a given declaration that leaves out its domain or dtype folds into an introducer that sets one (#768)
- fix(language): a file whose terms read each other's sums is refused at load (#780)
- fix(language): a where that reads a given expression names it as a given expression, not as a variable (#809)
- refactor(language): a term prints as the definition it is, and one rule folds every reading (#738)
- fix(typeset): a term a file adds to a sum keeps its definition line when the expressions are inlined (#766)
Language#
- feat(language): two files that state the same spec write one text, and
canonical --checkfails a file that is not in it (#731) - feat(language): a named expression may declare the frame it is read over (#741)
- feat(language): a sum names several dimensions in one over= list (#778)
- feat(language): a divisor or a power over parameters may add, so a discount factor is written where it is used (#757)
- feat(language): a parameter value that is null or NaN is refused when the data is attached (#788)
- fix(language): dual(c) is the rate at which the optimal objective rises with the right side of c, so an equality has a sign too (#751)
- fix(language): a cases block with one case may compare expressions in its when: (#795)
- fix(language): a where string names several columns in at's over= and into=, as an expression does (#782)
- fix(language): a macro formal written inside a list takes the name the call binds to it (#779)
Typesetting and advice#
- fix(typeset): a substituted term that opens with a minus prints as a subtraction (#759)
- fix(advice): an objective that reads a given expression or an empty sum gets advice rather than a KeyError (#767)
Documentation#
- docs(pypsa): a single spec covers every pypsa model class and component (#620)
- docs(pypsa): the pypsa spec is also 24 topic files that merge back to it, each component adding its share of a sum by name (#736)
- docs(pypsa): an efficiency, a rate or a phase shift may change from snapshot to snapshot (#717)
- docs: the composition how-to builds a component library from terms each file adds to a sum (#762)
- docs: the composition how-to shows a sum that one file defines and other files add terms to (#800)
- docs: a file restates a shared dimension as its dtype alone, and
mergecarries the one description written for it (#743) - docs(language): a reported quotient is absent where its divisor is zero, whether a solve or the data gave that zero (#765)
- docs(notation): the notation page shows a named expression whose declared frame is wider than its body (#756)
- docs: code examples on the site are readable in light and dark mode, and a diagram shows what mathspec leaves to engines and other tools (#730)
- docs: the site follows the reader's light or dark setting, and a page shows where it sits in the navigation (#727)
0.2.0 (2026-09-25)#
A file now states a specification, or spec. A model is a spec with data attached, which an engine builds and a solver takes. mathspec holds specs only. The API, the messages and the docs use the two words in these senses (glossary).
This release breaks three things:
- The first parameter of
to_spec,advice,typeset,typeset_declaration,to_latex,to_typstandto_markdownisspec, notmodel. A call that passesmodel=by keyword fails. A positional call works as before. - The module
mathspec.modelis nowmathspec.spec.from mathspec import Specworks as before. - Error and advice messages say "spec" where they said "model". A test that matches the old text fails.
The pull requests in this release:
- feat!: what a file states is called a spec, the functions that read one take it as spec, and model means a spec with data (#721)
- docs: the README and the docs home page say that spec is short for specification (#724)
- fix(docs): the Python API pages link every name a docstring cites, and show advice as the function it is (#720)
0.1.0 (2026-09-25)#
🎉 mathspec is officially on PyPI!
0.1.0rc1 (2026-09-25)#
The release candidate for 0.1.0, the first release on PyPI:
pip install mathspec==0.1.0rc1. The package installs, imports and runs as
mathspec since 0.0.0-alpha.127
(#702). The
0.0.0-alpha.N releases below were tags and GitHub releases only.
- docs: a page says how the package version and the language version of a model file relate (#711)
- docs: the installation page and the PyPI project page say
pip install mathspec, and the README's links resolve on PyPI (#707) - docs: every link to the documentation points at mathspec.readthedocs.io (#706)
0.0.0-alpha.127 (2026-09-25)#
Refactoring#
- the package installs, imports and runs as mathspec, rather than math-spec and math_spec (#702) (f9151af)
0.0.0-alpha.126 (2026-09-25)#
Documentation#
- the site is built by zensical, and its API reference is the public surface rather than every module (#568) (64eb268)
0.0.0-alpha.125 (2026-09-25)#
Bug Fixes#
- language: an unknown operator's refusal points at the limits page instead of an escape key that does not exist (#676) (5e4ef2b)
- language: messages and docs say data is attached rather than bound, so a bound is only a variable's limit (#694) (cc8ba08)
Documentation#
- a development section holds the PyPSA parity pages and the contributing guide (#678) (a399bdd)
- a first tutorial writes the dispatch model one block at a time, checks it and prints it (#680) (48b60e8)
- a glossary defines each word the docs use in a fixed sense (#675) (2561ad8)
- each page keeps only what its reader needs, and a fact stated twice keeps one home (#686) (ef8dcb9)
- engine authors get a program api page rendered from math_spec.program, and the per-module pages and the file-and-program page are gone (#697) (784867a)
- one Python API page documents every public name, including the typesetting functions (#679) (ee5ffdf)
- the nav keeps tutorials, how-to guides, reference and about for model writers, and puts the rest under development (#683) (341ad2a)
- the notation page heads each section with the construct it shows (#682) (66faa7b)
- the readme and home page lead with what a user gets, and name specsolve and linopy as engines (#698) (9fda1bc)
- the readme drops the internals diagram and the repeated formats, and is a third shorter (#699) (234245b)
- what spec.expand() returns is documented on the model writer's python api page, and reading.md keeps only which program an engine reads (#696) (a9caeae)
- what spec.expand() returns is stated once, as a different model that binds the same data (#677) (413550e)
0.0.0-alpha.124 (2026-09-24)#
Features#
- language: a bound is null where it is open, never infinite, in the file and in the program (#689) (8df92d0)
0.0.0-alpha.123 (2026-09-24)#
Documentation#
0.0.0-alpha.122 (2026-09-24)#
Refactoring#
- program: the program no longer exports fan_in, FanIn, quotients or divisor_parameters (#633) (352431b)
0.0.0-alpha.121 (2026-09-24)#
Features#
- language: a model's program is an attribute of the model, and the one door to both states is to_spec (#656) (91f0640)
- language: nothing writes a formulation out unasked (#661) (b5241fd)
Bug Fixes#
- language: a name a curve writes is refused at load whatever declares it, and advice reads a named coefficient's sign (#666) (c1574ab)
Refactoring#
- language: a model loads without writing its curves out, and the program owns the vocabulary the file declares in (#653) (7e93ecb)
- language: every rule that reads across declarations runs in lowering, before any expression is read (#651) (6c1fb6b)
- language: the top-level surface is the two states, the door, the errors, the advice and the typesetter (#660) (5c4f8be)
- program: a program carries the trees the typesetter prints, and every curve is written out before a model becomes one (#649) (762394d)
- program: a program mirrors the file, descriptions and curves included, and the typesetter reads it alone (#650) (bfd628e)
Documentation#
- a page explains why a loaded model is a spec and a program, and which tool reads which (#668) (dc0d731)
0.0.0-alpha.120 (2026-09-23)#
Features#
0.0.0-alpha.119 (2026-09-23)#
Bug Fixes#
- language: a long chain of named expressions loads, a typo beside a formal is refused, and a fault in an entry hides no other (#643) (1e010ca)
- language: a macro template nothing calls is held to every rule a call site is (#628) (ffab0ff)
Refactoring#
- language: an expression resolves straight into the program's own nodes (#638) (b3cee88)
- language: each named expression is resolved once, and every use reads that node (#632) (ceecf69)
- program: a comparison of expressions is one node before and after lowering (#631) (f723602)
0.0.0-alpha.118 (2026-09-23)#
Features#
0.0.0-alpha.117 (2026-09-22)#
Documentation#
- limits: a where cannot test a relation against its target dimension, and composition is a limit on the file (#624) (216208b)
0.0.0-alpha.116 (2026-09-22)#
Features#
- lowering: a program is lowered from the model as it arrived, and a curve left as written is refused (#618) (b15c78a)
0.0.0-alpha.115 (2026-09-22)#
Bug Fixes#
0.0.0-alpha.114 (2026-09-22)#
Documentation#
0.0.0-alpha.113 (2026-09-22)#
Bug Fixes#
0.0.0-alpha.112 (2026-09-22)#
Bug Fixes#
0.0.0-alpha.111 (2026-09-22)#
Features#
- language: a model declares what it assumes of its data (#589) (e1454cf)
- language: a model writes its formulations out on request, and states what each assumes of its data (#602) (1e00c23)
- language: a where counts the coordinates a predicate admits (#592) (5cc55d3)
- language: a where may compare arithmetic over parameters (#566) (e9793bd)
0.0.0-alpha.110 (2026-09-21)#
Documentation#
0.0.0-alpha.109 (2026-09-21)#
Bug Fixes#
0.0.0-alpha.108 (2026-09-20)#
Refactoring#
- program: a program names its nodes by the naming rule and its groups as the file does (#585) (3848821)
0.0.0-alpha.107 (2026-09-20)#
Bug Fixes#
- language: at refuses a read that consumes a column over the dimension it joins on, as sum does (#562) (c10c181)
Refactoring#
- language: a partition is its own class rather than a direction with nothing consumed or produced (#559) (6af0075)
- language: a relation is read in a direction rather than walked (#494) (bbc4344)
0.0.0-alpha.106 (2026-09-19)#
Refactoring#
0.0.0-alpha.105 (2026-09-18)#
Documentation#
0.0.0-alpha.104 (2026-09-18)#
Bug Fixes#
0.0.0-alpha.103 (2026-09-18)#
Documentation#
- the contributing page points at the generated-pages table rather than a stale count (#555) (796ca8a)
0.0.0-alpha.102 (2026-09-18)#
Documentation#
- a rule states what is accepted and stops, rather than naming what it is not (#552) (1019b57)
- every page says what a model author needs and drops rationale, history and internals (#551) (ba6ad9a)
0.0.0-alpha.101 (2026-09-18)#
Documentation#
- language: deciding what a column of data is declared as is a how-to, and the dimensions page keeps the axis (#544) (3540c5c)
- language: named expressions, cases and macros get a page, and the reported page folds into it (#545) (4e49fc7)
- language: relations get a page of their own, and the operators page stops restating how a call reads one (#543) (7e9a572)
- language: the reference pages state their rules and stop arguing for them (#546) (efc9404)
- language: the relations page says what a relation is, how it is spelled, what its data owes, and how it is read, in that order (#549) (6f9e1a4)
- language: the six rules every walk through a relation keeps (#539) (6e93995)
- pinning a variable and writing a curve out by hand are how-tos (#547) (0bf0924)
- reading a loaded model sits beside the Python API rather than among the language pages (#548) (17d1e96)
0.0.0-alpha.100 (2026-09-18)#
Features#
- language: a partition names the value columns it groups by, so a relation may gain one without changing the call (#540) (0da7f50), closes #538
0.0.0-alpha.99 (2026-09-18)#
Features#
- language: a call walks one relation, so by= names one rather than a list (#533) (b78135d)
- language: a relation names the columns its key determines under values: (#504) (d9b0371)
- language: a walk through a relation names both of its ends, and lands only on dimensions it brings (#532) (26f29b0)
0.0.0-alpha.98 (2026-09-18)#
Documentation#
0.0.0-alpha.97 (2026-09-18)#
Features#
- program: a walk that says which regions each node stands under (#482) (3f37cbe), closes #473
- program: every axis names its linking rows and linking columns (#525) (588142f)
Bug Fixes#
0.0.0-alpha.96 (2026-09-17)#
Bug Fixes#
- language: an unknown keyword in an uncalled macro is refused by its signature (#462) (a1659da)
- language: an unknown keyword on an operator is refused once, by its signature (#458) (aa3e052)
0.0.0-alpha.95 (2026-09-16)#
Features#
0.0.0-alpha.94 (2026-09-16)#
Documentation#
- operators: every relational call form prints beside its YAML, the ones that name their columns included (#496) (602c29e)
0.0.0-alpha.93 (2026-09-16)#
Documentation#
- language: a walk through a relation is stated once, in the three verbs the loader uses (#490) (ebc9b16)
0.0.0-alpha.92 (2026-09-16)#
Features#
0.0.0-alpha.91 (2026-09-15)#
Corrected: this release carries no change. #474
was merged and then reverted by #481, both
before the tag was cut, and revert had no section in changelog-sections, so release-please kept
the feature and dropped the revert. The line it published was:
0.0.0-alpha.90 (2026-09-15)#
Documentation#
0.0.0-alpha.89 (2026-09-15)#
Features#
0.0.0-alpha.88 (2026-09-15)#
Documentation#
0.0.0-alpha.87 (2026-09-14)#
Features#
- language: a variable, a constraint and a cased expression declare their shape as dims, as a parameter does (#429) (d8dfdb0)
0.0.0-alpha.86 (2026-09-11)#
Bug Fixes#
0.0.0-alpha.85 (2026-09-10)#
Documentation#
0.0.0-alpha.84 (2026-09-10)#
Bug Fixes#
0.0.0-alpha.83 (2026-09-09)#
Features#
Refactoring#
0.0.0-alpha.82 (2026-09-09)#
Features#
- program: a where predicate's operands are walked with where_children, as an expression's are with children (#416) (b653537)
- typesetting: a backticked name in a description sets in monospace in every format (#421) (a2dcee7)
Bug Fixes#
Performance#
- validation: a model's expressions and where strings are resolved once per load rather than once per reader (#415) (bd86867)
0.0.0-alpha.81 (2026-09-09)#
Documentation#
0.0.0-alpha.80 (2026-09-09)#
Documentation#
0.0.0-alpha.79 (2026-09-09)#
Bug Fixes#
0.0.0-alpha.78 (2026-09-09)#
Bug Fixes#
0.0.0-alpha.77 (2026-09-09)#
Features#
0.0.0-alpha.76 (2026-09-08)#
Bug Fixes#
- program: a parameter under a power is seen by every walk, so a divisor written as a power is named (#404) (1689a7a), closes #403
0.0.0-alpha.75 (2026-09-08)#
Features#
0.0.0-alpha.74 (2026-09-08)#
Features#
- typeset: a named expression prints as a definition, and one declaration prints on its own by name (#385) (f66925e)
0.0.0-alpha.73 (2026-09-02)#
Documentation#
0.0.0-alpha.72 (2026-09-02)#
Features#
- program: a model says whether an axis may be built a window at a time, and what each coordinate needs from its neighbours (#374) (1e029b4)
0.0.0-alpha.71 (2026-09-02)#
Bug Fixes#
0.0.0-alpha.70 (2026-09-02)#
Documentation#
0.0.0-alpha.69 (2026-09-02)#
Bug Fixes#
Refactoring#
- the expression parser is package-private, and the parsed tree is named apart from the program's (#342) (55ff525)
0.0.0-alpha.68 (2026-09-02)#
Documentation#
- language: the rules binding obeys belong to the language, not to whichever engine reads the data (#242) (c05da6a)
0.0.0-alpha.67 (2026-09-02)#
Refactoring#
- a built-in's one positional argument is stated once, and a degree question names the tree it walks (#364) (556af30)
- every rule two passes shared has one home, and a docstring says what a caller needs rather than why (#363) (f24ddd3)
- model: each cross-declaration rule is one method, so a refusal names the rule that raised it (#369) (b25a602)
- piecewise: one block expands itself, holding its names, frame and mask once (#367) (537eadf)
- resolution is one method per node kind, and each operator's dim rule is one function (#368) (c7c2833)
- typesetting: the legend reads what the equations returned rather than state left on the walk (#366) (db96a54)
0.0.0-alpha.66 (2026-09-01)#
Performance#
0.0.0-alpha.65 (2026-09-01)#
Refactoring#
- language: a translation policy and a bound's side name the values they can be, rather than being a string (#354) (d212157)
- typesetting: a format spells the operators the language names, rather than any string a walk happens to ask for (#352) (12b4041)
0.0.0-alpha.64 (2026-09-01)#
Features#
- parser: a refused where string names the rewrite for pandas and C connective habits (#346) (3dbd9b2)
0.0.0-alpha.63 (2026-09-01)#
Refactoring#
- language: an operator, a declaration kind and a notation name the values they can be, rather than being a string (#345) (3f3f858)
0.0.0-alpha.62 (2026-09-01)#
Bug Fixes#
- language: a declaration named what no expression could write is refused, rather than loading unreferenceable (#340) (b865bc1)
0.0.0-alpha.61 (2026-09-01)#
Performance#
0.0.0-alpha.60 (2026-09-01)#
Bug Fixes#
- language: the language reference states which case arms are refused, and the refusal says what actually breaks (#336) (01920d1)
0.0.0-alpha.59 (2026-09-01)#
Bug Fixes#
0.0.0-alpha.58 (2026-09-01)#
Features#
- program: a resolved where is a first-class Mask whose leaves carry their dims, and the where grammar is package-private (#327) (53cc352)
0.0.0-alpha.57 (2026-09-01)#
Bug Fixes#
- program: a program describes a mathematical program rather than being one, and claims neither linearity nor a storage format (#315) (5dfa6be)
0.0.0-alpha.56 (2026-09-01)#
Features#
- program: the conjuncts of a where mask are the program's to give, not each consumer's to re-derive (#313) (db63d3c)
0.0.0-alpha.55 (2026-08-31)#
Documentation#
- ceiling: load-time unit checking has its own refusal, where the data-prep row used to answer for it (#272) (8dfd17d)
0.0.0-alpha.54 (2026-08-31)#
Documentation#
- drop the effects row from the PyPSA-1.3.0 parity table, a feature that release does not have (#305) (92e5ed8)
0.0.0-alpha.53 (2026-08-31)#
Documentation#
- a link's delivery lags its flow, wrapping or losing what is in transit at the horizon's edge (#300) (1d4f10f)
0.0.0-alpha.52 (2026-08-31)#
Documentation#
- examples: the PyPSA file states a constraint once where PyPSA builds one row set, rather than a block per regime (#257) (#292) (c35e637)
0.0.0-alpha.51 (2026-08-31)#
Features#
- a named expression may give a value per region, and no two regions may claim one coordinate (#168) (e12e7da)
0.0.0-alpha.50 (2026-08-31)#
Documentation#
0.0.0-alpha.49 (2026-08-31)#
Features#
Bug Fixes#
- examples: a committable modular unit that is not extendable gets the rows PyPSA builds for it (#271) (5af0ac8)
0.0.0-alpha.48 (2026-08-31)#
Features#
- language: which dims a mask reads is the language's answer, so two consumers cannot restrict one model differently (#269) (350b1ed)
0.0.0-alpha.47 (2026-08-28)#
Documentation#
0.0.0-alpha.46 (2026-08-28)#
Features#
- program: a piecewise assumption names the data it is about, and a derived parameter says how it is filled (#237) (48431b1)
0.0.0-alpha.45 (2026-08-28)#
Bug Fixes#
- language: a negative edge fill prints, the sign of a literal amount being folded once at resolution (#234) (d9303db)
0.0.0-alpha.44 (2026-08-28)#
Bug Fixes#
- language: a where mask is folded at resolution, so a typeset page and a program agree about it (#232) (553bda0)
0.0.0-alpha.43 (2026-08-28)#
Features#
- program: a parameter says which piecewise block derived it, and a label space keeps its dtype (#227) (515dbd5)
- program: a piecewise block is kept as facts — its breakpoints, its mask, and what it assumes of the data (#228) (2fdbd6f)
0.0.0-alpha.42 (2026-08-28)#
Bug Fixes#
- language: a negative sum_back width is refused at load rather than asserting in lowering (#223) (62e52eb), closes #222
0.0.0-alpha.41 (2026-08-28)#
Bug Fixes#
- language: a boolean literal in a where is decided at load wherever it stands (#216) (fab308f), closes #214
0.0.0-alpha.40 (2026-08-28)#
Refactoring#
- program: the declaration vocabularies have one home, so a program cannot spell one differently from the file (#219) (f7596d7), closes #209
0.0.0-alpha.39 (2026-08-28)#
Bug Fixes#
- advice: a model handed over as a program is advised of everything a file is (#217) (4fc50e6), closes #210
0.0.0-alpha.38 (2026-08-28)#
Features#
Bug Fixes#
- a file the language accepts is one every consumer can build, the edge rules being decided at load (#211) (a362ff0)
- program: a where mask cannot be rewritten under another consumer (#197) (ce406b0)
- program: an unknown dimension is refused rather than answered empty (#199) (96fdccf)
- program: every expression node answers fan_in (#202) (f5cc67d)
Refactoring#
- program: a program is built by keyword, so a new field cannot reorder an old call (#203) (214394a)
- program: a program's declarations are keyed by the name the file wrote (#205) (579264a)
- program: drop the two pieces of the program API nothing reaches (#204) (ca25fa5)
- program: expressions are the ones a row is built from, and the declared ones say so (#206) (81aaddd)
- program: the program module says what it promises, rather than offering its whole namespace (#208) (08d2f64)
0.0.0-alpha.37 (2026-08-28)#
Features#
- a model is checked from the shell, advice included, with no consumer installed (#192) (941126c)
- advice carries which pass said it and which declaration it is about, so a consumer can filter rather than parse (#195) (89408f6)
Refactoring#
0.0.0-alpha.36 (2026-08-28)#
Refactoring#
- a program is trusted by construction, so the language's rules are checked once, on the spec (#189) (45931b1)
0.0.0-alpha.35 (2026-08-28)#
Documentation#
0.0.0-alpha.34 (2026-08-28)#
Refactoring#
- two public states and a conversion to each, where the surface was seventy-seven names (#180) (718e2de)
0.0.0-alpha.33 (2026-08-28)#
Features#
- the notes a check prints are reachable, so a consumer surfaces them rather than re-deriving them (#184) (19ef814)
0.0.0-alpha.32 (2026-08-28)#
Features#
0.0.0-alpha.31 (2026-08-28)#
Documentation#
0.0.0-alpha.30 (2026-08-28)#
Documentation#
0.0.0-alpha.29 (2026-08-27)#
Features#
- language: dimension members and lookup maps come from the data, rather than from the file (#169) (f3c4e5f)
0.0.0-alpha.28 (2026-08-27)#
Bug Fixes#
0.0.0-alpha.27 (2026-08-27)#
Bug Fixes#
- the linearized rung states its three caps as rows and starts one unit cold, so every block it declares is built (#162) (cb4863f)
0.0.0-alpha.26 (2026-08-27)#
Features#
0.0.0-alpha.25 (2026-08-27)#
Features#
- rung 11 — PyPSA's ac-dc-meshed example, whole (#151) (a133044)
- rung 12 — linearized unit commitment, a file of its own (#152) (69b926e)
- rung 13 — transmission losses in tangent form, a file of its own (#153) (379ce23)
- rung 14 — two-stage stochastic with CVaR, a file of its own (#154) (41b427d)
- rung 15 — investment periods with a growth limit, a file of its own (#155) (285aac3)
0.0.0-alpha.24 (2026-08-26)#
Features#
- PyPSA in one file — every rung stated, shown beside its data, and solved to the same objective on both lanes (#122) (46544e3)
0.0.0-alpha.23 (2026-08-26)#
Bug Fixes#
- docs: the homepage feature cards render as cards rather than as loose rules and paragraphs (#145) (b88e5dc)
0.0.0-alpha.22 (2026-08-26)#
Features#
0.0.0-alpha.21 (2026-08-26)#
Documentation#
0.0.0-alpha.20 (2026-08-26)#
Documentation#
0.0.0-alpha.19 (2026-08-26)#
Bug Fixes#
0.0.0-alpha.18 (2026-08-26)#
Refactoring#
- parser: one number rule, one amount table, and a namespace nothing builds by hand (#106) (f775a07)
- schema: one wording for an undeclared dimension, and the front door validates once (#105) (69e42db)
- the stack's own additions say less and repeat nothing (#102) (119e588)
- typeset: Markdown is LaTeX's math with its own document layer, and a step merges itself (#107) (1ca9178)
0.0.0-alpha.17 (2026-08-25)#
Bug Fixes#
- language: a link takes any affine expression, an uncalled template hides no typo, and degree is decided at load (#91) (a653056)
- parser: a negation is over a power, a keyword is given once, and an amount is a number or a name (#88) (4bf994c)
- schema: every refusal of a malformed file is a SchemaError, and an empty declared map survives a round trip (#89) (ee07736)
- schema: two literal bounds that cross are refused at load (#97) (30589ba)
- typeset: a sum under its own dimension takes a fresh index, and prose escapes its markup (#92) (20c7076)
Refactoring#
0.0.0-alpha.16 (2026-08-25)#
Refactoring#
0.0.0-alpha.15 (2026-08-25)#
Documentation#
0.0.0-alpha.14 (2026-08-25)#
Documentation#
0.0.0-alpha.13 (2026-08-25)#
Bug Fixes#
0.0.0-alpha.12 (2026-08-25)#
Documentation#
0.0.0-alpha.11 (2026-08-25)#
Bug Fixes#
- enforce the two rules a named offset or width was always said to obey (#61) (5bd92dc), closes #58
- let sum_back stop at each group's edge, as its checks already assumed (#65) (cb58e88)
- refuse a negated named amount, and one read where there is no coordinate (#63) (15d9c25), closes #62
0.0.0-alpha.10 (2026-08-24)#
Features#
Refactoring#
- name the groups a pass asks about, and spell each operator once (#52) (e35c46c)
- the package is
typesetting, the function staystypeset(#54) (a1d9599)