math_spec.piecewise
Expand piecewise: blocks into plain variables and constraints.
A block becomes ordinary affine declarations before anything reads the model,
under names prefixed with the block's own; what each method emits is tabled in
docs/reference/language/piecewise.md. Everything the language decides
about a block against its model is decided once, in :func:check, and the
emitters write rows from the facts it settled. A refusal names the link or key
the file wrote rather than an emitted declaration.
ASSUMED = ('complete', 'increasing', 'curvature', 'breakpoints', 'contiguous')
module-attribute
#
GateRow = tuple[str, str | None, str]
module-attribute
#
Curve(name, block, frame, rows, mask, gates, names)
dataclass
#
One piecewise: block held to its model: every fact the rows it writes read.
:func:check is the only thing that builds one, so holding one is the
proof that the block is inside the language, and nothing after it decides
anything.
| ATTRIBUTE | DESCRIPTION |
|---|---|
name |
The block's key.
TYPE:
|
block |
The block as written.
TYPE:
|
frame |
The dims the block builds one curve per coordinate of. |
rows |
Each link's row frame — the frame, or its refinement through the link's relation. |
mask |
The block's
TYPE:
|
gates |
The rows the weights sum under, one or two. |
names |
Every name the expansion writes.
TYPE:
|
CurveMask(block, resolved)
#
A block's where:, as each shape of row the expansion writes reads it.
Built from the block and its resolved mask, to answer the one question the expansion asks of it: whether it reads the breakpoint dim. Such a where is ragged — it says how far each curve runs, not only which curves exist — so a row over the frame and the breakpoint dim takes it as written, the rows on a curve's edges shift it, and a row over the frame alone, which cannot read that dim, takes the count of breakpoints it admits. A where over the frame alone reaches every row as written.
Source code in src/math_spec/piecewise.py
along = block.along
instance-attribute
#
dims = resolved.dims if resolved is not None else frozenset()
instance-attribute
#
exists
property
#
What a row over the frame alone takes: the where, or the count of breakpoints a ragged one admits.
frame
property
#
The where as a row over the frame and the breakpoint dim conjoins it onto a position test — none where ragged.
ragged
property
#
Whether the where reads the breakpoint dim, and so says how far each curve runs.
text = block.where
instance-attribute
#
edge(end)
#
The first or last breakpoint of each curve: where the mask holds and does not one step outward.
The vacated edge of a shift in a where is false, which is what
makes the head and the tail of the axis their own edge.
Source code in src/math_spec/piecewise.py
interior()
#
Where a breakpoint has one on either side: the rows a claim about a bend is true of.
Source code in src/math_spec/piecewise.py
neighbours()
#
Where a breakpoint and the one before it are both there: the rows a claim about a segment is true of.
Names(name, weights, convexity, chord, domain_lo, domain_hi, links, sos)
dataclass
#
Every name one block's expansion writes, spelled once for the emitters and the collision check.
Every name is reserved whichever method the block declares: which method
writes which is the method's business, and a collision is the file's
either way. sos holds the names a method that states a set writes
through :func:math_spec.sos.emit.
by_kind
property
#
Each name by the kind of declaration it would collide with.
chord
instance-attribute
#
convexity
instance-attribute
#
domain_hi
instance-attribute
#
domain_lo
instance-attribute
#
links
instance-attribute
#
name
instance-attribute
#
sos
instance-attribute
#
ungated
property
#
The second gate row, where the gate variable does not exist.
weights
instance-attribute
#
of(name, links)
classmethod
#
The names block name with links links writes.
Source code in src/math_spec/piecewise.py
assumptions_of(name, block, where)
#
What block assumes of its numbers, by the name the document prints and a refusal quotes.
Every curve assumes its breakpoints are there: a missing parameter row is
not absence, it is a zero, so an undeclared breakpoint sits the curve on
the origin rather than shortening it. A curve has an x-axis only where two
links tie it, so the increasing condition — and the shape it is checked
with — exist only there; lp alone needs a segment to state a line for;
a ragged where: must mark one run.
Read off the block rather than off an expansion, so a model states what it
assumes whether or not its curves have been written out. Each condition is
a where string over the parameters the file declared: the expansion writes
them into assumptions:, and a model that still declares the block
derives the same text at load. A where: over the frame alone is not
written into them: a program carries it on the declaration, and asks each
condition only where it holds.
Source code in src/math_spec/piecewise.py
check(schema, name, block)
#
block held to everything the language decides about it against its model, as the facts its rows read.
What the block names by key — dimensions, parameters, relations, the gate
— and the names it writes are checked as the file loads, with every other
cross-declaration rule (:class:~math_spec.model.Spec); the link
expressions and the where are typed with the rest of the model
(:attr:~math_spec.model.Spec.resolved), so a fault in one is named
against the link there. What is left is what needs those typed forms: the
frame, declared by dims: or read off the links; each link's row; that
each link's expression and values fit its row; and that the where:
fits the frame.
| RAISES | DESCRIPTION |
|---|---|
PiecewiseExpansionError
|
A link that does not fit its row, a frame that reaches the breakpoint dim, or a where outside the frame. |
Source code in src/math_spec/piecewise.py
declaration_of(block, where=None)
#
The curve of one expanded block, as a program carries it.
| PARAMETER | DESCRIPTION |
|---|---|
block
|
The block as written.
TYPE:
|
where
|
Which coordinates of the frame have a curve, lowered — and so which ones what the block assumes is asked at.
TYPE:
|
Source code in src/math_spec/piecewise.py
expand_piecewise(schema)
#
schema with every piecewise: block written out — schema itself where it declares none.
A method: adjacency block states its restriction as the set
method: sos2 states, and then that set is written out here too: the
binaries are what the method is, so the model that comes back carries no
set of its own (:func:math_spec.sos.emit is where they are spelled).
| RAISES | DESCRIPTION |
|---|---|
PiecewiseExpansionError
|
A block :func: |