cottax.assemblies.jax module

The shipped assembly: pytree places, the relational and ode languages, the jax solvers and the drawings; its surface, its defaults and the joins between consumers.

class Description[source]

Bases: Frozen

A function described rather than given: what a wrapper needs of it, its parameters in order. Its node is implemented by the description (a RepoRef to code elsewhere, say), which no backend runs until one resolves it.

parameters: AbstractVar[tuple[str, ...]]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class Unimplemented(parameters: tuple[str, ...])[source]

Bases: Description

A function yet to be written: its parameters, and nothing else. Its node has no implementation.

parameters: tuple[str, ...]
class Explicit[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], *, output_tags: Tags[V] = {})[source]

Bases: Wrapper[N, V], Generic[N, V]

A function computing its outputs, returned in that order.

terms: AbstractVar[tuple[Optional[PlaceWithValue[V]], ...]] = ()

What else it writes where a place is due, each a place (with the value where one was written) or None for zero: a constraint’s bounds or targets; none for most.

property function_outputs: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

nodes(at: N)[source]

What this declares, bound at at and at names derived from it.

Return type:

tuple[tuple[N, NodeDefinition[V]], ...]

class Implicit[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], *, output_tags: Tags[V] = {})[source]

Bases: Paired[N, V], Generic[N, V]

An implicit model: a function writing ^cond.u per unknown (its outputs), in that order, and at ^solve.at the problem determining the unknowns.

terms: AbstractVar[tuple[Optional[PlaceWithValue[V]], ...]] = ()

What else it writes where a place is due, each a place (with the value where one was written) or None for zero: a constraint’s bounds or targets; none for most.

condition_mint

alias of Solve

property function_outputs: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

condition_node(at: N)[source]

The condition node as bound at at, its own name: condition, or one whose places derive from its name.

Return type:

ConditionalNode[V]

property problem: N

Where its problem binds, the model handed to declare loose: ^solve.<fn>.

class Residual[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], *, output_tags: Tags[V] = {})[source]

Bases: Implicit[N, V], Generic[N, V]

The function returns a residual per unknown, each held at zero: ^cond.u = 0.

property condition: RelationalCondition[V]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class FixedPoint[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], *, output_tags: Tags[V] = {})[source]

Bases: Implicit[N, V], Generic[N, V]

The function returns the next value of each unknown, each held equal to it: a fixed point, u = ^cond.u.

property condition: RelationalCondition[V]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class PlaceWithValue[V: Place](place: V, value: Any | None = None, tags: tuple[Tagged, ...] = ())[source]

Bases: Frozen, Generic[V]

A place, the value written for it (None where none was), and the tags written on the place.

place: V
value: Any | None = None
tags: tuple[Tagged, ...] = ()
class InequalityConstraint[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], bounds: Bounds[V], *, output_tags: Tags[V] = {})[source]

Bases: Constraint[N, V], Generic[N, V]

Each output within its bounds: g <= g_max, q >= q_min, lo <= t <= hi, zero where a side is None.

bounds: Bounds[V]
property held_against: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property terms: tuple[Optional[PlaceWithValue[V]], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property condition: RelationalCondition[V]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class EqualityConstraint[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], targets: OrderedMap[V, Optional[PlaceWithValue[V]]], *, output_tags: Tags[V] = {})[source]

Bases: Constraint[N, V], Generic[N, V]

Each output equal to its target: h = h_target, or h = 0 where it is None.

targets: OrderedMap[V, Optional[PlaceWithValue[V]]]

Each output’s target (with its value where a number was written), or None for zero.

property held_against: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property terms: tuple[Optional[PlaceWithValue[V]], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property condition: RelationalCondition[V]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class Problem[N: Label, V: Place](unknowns: tuple[V, ...], bounds: Bounds[V], objectives: tuple[Objective[V], ...], subject_to: tuple[Union[Constraint[N, V], RelationalCondition[V]], ...])[source]

Bases: Declaration[N, V], Generic[N, V]

A relational condition node declared alone, with no body: the unknowns it determines, their bounds, its objectives, and the constraints and requirements it is subject to.

unknowns: tuple[V, ...]
bounds: Bounds[V]

(lo, hi) as written.

Type:

On the unknowns

objectives: tuple[Objective[V], ...]

One for optimise, none for satisfy.

subject_to: tuple[Union[Constraint[N, V], RelationalCondition[V]], ...]

Constraints and requirements held in this problem’s one condition node.

checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_subject_to>, <function check_bounds_on_unknowns>, <function check_condition>)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

property holds: tuple[Union[Constraint[N, V], RelationalCondition[V]], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property outputs: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

nodes_when_held(at: N)[source]

Nothing: what holds it takes its condition.

Return type:

tuple[tuple[N, NodeDefinition[V]], ...]

property held: tuple[RelationalCondition[V], ...]

The requirement of each constraint it is subject to.

property condition: RelationalCondition[V]
property given: OrderedMap[V, Any]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property tags: Tags[V]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

nodes(at: N)[source]

What this declares, bound at at and at names derived from it.

Return type:

tuple[tuple[N, NodeDefinition[V]], ...]

loose_at(names: DerivedNames[N, V])[source]

^solve.<objective>; none with no objective.

Return type:

Optional[N]

class Tagged(value: Any)[source]

Bases: Frozen

What is written (a name, a path, a value or a model in a slot) with a tag the declarations carry but never read: the feature that gives the tag its meaning reads it (Static: part of the compile key). Around a name or a path the place carries it, around a value the place minted for it, around a model the node name its slot gives.

value: Any
class Surface[N: Label, V: Place](locator: Locator[V, N])[source]

Bases: Frozen, Generic[N, V]

What a model is written through: locator says what a bare string means, and what else is written means what its Written answer says. A part is a level under it adding methods; a surface a study uses joins parts, a class. A method’s parameter annotated Place, Label or a tuple of either (alone, | None, varargs, or in a Mapping) is read through the surface before the method runs: a caller writes it any way the surface reads, and the method is handed it exact.

locator: Locator[V, N]
located(locator: Locator[V, N])[source]

The same surface, strings meaning what locator says.

Return type:

Self

place(written: Any, *, role: str = 'what is written')[source]

A place: a string, as the locator says, an exact place, or what it stands for (Written), if one place: a V path, a wrapper’s one output.

Return type:

V

places(written: Any, *, role: str = 'what is written')[source]

Places: one written alone, or several; what stands for places, all of them.

Return type:

tuple[V, ...]

node(written: Any, *, role: str = 'what is written')[source]

A node name: a string, as the locator says, an exact name, or the name it takes (Written): an N path, a wrapper’s function’s name.

Return type:

N

nodes(written: Any, *, role: str = 'what is written')[source]

Node names: one written alone, or several.

Return type:

tuple[N, ...]

property derived: DerivedNames[N, V]

The names derived from the class of place the locator locates.

class Part(locator: Locator[V, N])[source]

Bases: Surface, Choice

A level of a surface adding methods: each takes exact names, its parameters annotated Place or Label read by the surface before it runs, and returns a declaration, an op or a run. What it defaults to is an AbstractVar a final binds. Two parts defining one name are refused where they are joined.

Handed in as:

class Mine(ShippedSurface, MyPart), the shipped parts and one of a study’s own, then Mine(locator, conventions) – or a surface joining only the parts it names.

class Declaring(locator: Locator[V, N], conventions: ~cottax.consumers.declaration.conventions.Conventions = Conventions(reads=ParameterReads(by_name=True), term=<function term_of>, per_place=<function per_place_of>))[source]

Bases: Part

Part declaring multiple nodes (residuals / implicit models / rates)

Includes conventions on what means what here (i.e. does it read all function parameter strictly?)

class Mine(ShippedSurface, MyDeclaring), a declaring part of a study’s own beside the shipped ones; surface.reading(conventions) reads its arguments otherwise.

conventions: Conventions = Conventions(reads=ParameterReads(by_name=True), term=<function term_of>, per_place=<function per_place_of>)

cottax’s unless a study says otherwise.

Type:

What each argument that may be a value means

function

function(fn, *outputs) where it is used, @function(*outputs) where it is written. Each parameter is read where reads says, else by name under the surface read_in names it in, else by name in this one.

Type:

A function computing its outputs, returned in that order

declare(*models: Any)[source]

Walk a model tree yielding a Declared: the graph plus already given values and tags.

Return type:

Declared

reading(conventions: Conventions)[source]

The same surface, arguments read as conventions says.

Return type:

Self

parameter_reads(fn: Body, reads: Any, read_in: Mapping[Callable[[str], Any], Any], *, given: Callable[[str], Any])[source]

The place each parameter of fn reads, as conventions.reads says.

Return type:

tuple[PlaceWithValue, ...]

term(x: Any, written: Any, value_at: PlaceToPlace)[source]

What is written where a place about x is due, as conventions.term says: None for zero, a value at value_at(x), or a place.

Return type:

PlaceWithValue | None

per_place(among: tuple[Any, ...], written: Any)[source]

What is written for each of among, as conventions.per_place says.

Return type:

dict[Place, Any]

class Editing(locator: Locator[V, N])[source]

Bases: Part

Core’s own edits, written by name: the ops a study writes by hand, each named after the op it builds; a copy goes where copies says.

copies: AbstractVar[PlaceToPlace]

^copy.var.

Type:

Where a cut’s copy of a place goes

copy(var: Place)[source]

Where a cut of var puts its copy, as this surface’s cuts and closings mint it.

Return type:

Place

cut(var: Place, readers: tuple[Label, ...], *, copy_of: PlaceToPlace | None = None)[source]

readers (one, or several) read a copy of var; its producer stays.

Return type:

Cut

rename(node: Label, onto: Mapping[Place, Place])[source]

The node reads and owns each place of onto at the place it maps to.

Return type:

Rename

determine(requirement: Label, *unknowns: Place)[source]

The requirement determines unknowns: a problem.

Return type:

Determine

nest(inner: Label, outer: Label)[source]

The problem inner is answered inside every iteration of outer.

Return type:

Nest

unnest(inner: Label)[source]

The problem inner answered at its own level again.

Return type:

Unnest

combine(at: Label, nodes: tuple[Label, ...], kind: type)[source]

nodes folded into one at at, by kind’s +.

Return type:

Combine

delete(nodes: tuple[Label, ...])[source]

nodes (one, or several) unbound.

Return type:

Delete

implement(implementations: Mapping[Label, object])[source]

Each node run by what it maps to.

Return type:

Implement

class RelationalDeclaring(locator: Locator[V, N], conventions: ~cottax.consumers.declaration.conventions.Conventions = Conventions(reads=ParameterReads(by_name=True), term=<function term_of>, per_place=<function per_place_of>))[source]

Bases: Declaring

The relational declarations: implicit models and constraints as functions, and the relational conditions over them.

residual

A function returning a residual per unknown, and the problem where each vanishes: residual(fn, *unknowns), or @residual(*unknowns).

fixed_point

A function returning each unknown’s next value, and the problem holding each equal to it: fixed_point(fn, *unknowns), or @fixed_point(*unknowns).

inequality_constraint

A function computing its outputs, each within its (lo, hi) – one pair for the one output there is, or a mapping of pairs – and with none given at most zero: inequality_constraint(fn, *outputs, within=(None, ‘g_max’)), or the decorator.

equality_constraint

A function computing its outputs, each equal to its target – one for the one output there is, or a mapping – and with none given zero: equality_constraint(fn, *outputs, against=’h_target’), or the decorator.

requirement(condition: Place, op: type[Rel] = Eq)[source]

c op 0, determining nothing: held by a problem subject to it, or where an architecture puts it.

Return type:

RelationalCondition

satisfy(*, design: Design, subject_to: SubjectTo = ())[source]

Any point of design (names, or a mapping to (lo, hi)) meeting the constraints it is subject to (one, or a collection), nothing minimised: a root find where those are equalities.

Return type:

Problem

optimise(*, design: Design, minimise: Place | None = None, maximise: Place | None = None, subject_to: SubjectTo = ())[source]

Minimise or maximise one objective over design (names, or a mapping to (lo, hi)), subject to constraints – one, or a collection: constraint wrappers in the model, or bare requirements, held by the problem.

Return type:

Problem

class RelationalEditing(locator: Locator[V, N])[source]

Bases: Editing

The relational edit a study writes by hand: cuts closed by a fixed point.

fixed_point_cut(cuts: Place | Mapping[Place, tuple[Label, ...]], readers: tuple[Label, ...] | None = None, *, at: Label | None = None, copy_of: PlaceToPlace | None = None)[source]

Cuts closed by one problem holding each copy equal to what it copies (^copy.y = y): one variable and its readers, fixed_point_cut(‘y_1’, D2), or several closed together, fixed_point_cut({‘y_1’: D2, ‘y_2’: (D1,)}, at=’mda’). The problem binds at ^closure.<the first variable> unless at names it; each copy where copies says unless copy_of does.

Return type:

FixedPointCut

class Architecting(locator: Locator[V, N])[source]

Bases: Part

The architectures a study applies, each named after the op it builds, every group of cuts closed by closing; which variables to cut is the rule, per call.

closing: AbstractVar[Closing]

another closing is another surface, or the op written in full.

Type:

How a group of cuts is closed

mdf(top: Label, rule: CutRule = GaussSeidel())[source]

Multidisciplinary feasible under top: one MDA per cycle, nested in it.

Return type:

MDF

idf(top: Label, rule: CutRule = GaussSeidel())[source]

Individual discipline feasible under top: the closures combined into it.

Return type:

IDF

sand(top: Label, rule: CutRule = GaussSeidel())[source]

Simultaneous analysis and design under top: the bodies’ states are its own.

Return type:

SAND

mda(rule: CutRule = GaussSeidel())[source]

A multidisciplinary analysis: one closure per cycle, and no design.

Return type:

MDA

class Driving(locator: Locator[V, N])[source]

Bases: Part

Driving problems: one by its contract (assign), or every undriven one by the first of the implementations accepting it (drive), tried under contracts; each role where role_places puts it.

contracts: AbstractVar[tuple[DriverContract, ...]]

The contracts a problem is driven under, the first an implementation implements.

role_places: AbstractVar[RolePlaces]

Where a driver’s data and reports go, a rule per role.

assign(problem: Label, contract: DriverContract)[source]

The problem driven by contract, each of its roles where role_places puts it, read off the problem when the op is applied.

Return type:

AssignByRule

drive(*implementations: Any)[source]

Every undriven problem driven by the first of implementations accepting it, under the first of the contracts it implements; a problem driven already implemented by the first covering its contract.

Return type:

Drive

class ShippedSurface(locator: ~cottax.consumers.surface.interface.Locator[~cottax.pytree.consumers.surface.builders.Keys, ~cottax.pytree.consumers.surface.builders.Keys], conventions: ~cottax.consumers.declaration.conventions.Conventions = Conventions(reads=ParameterReads(by_name=True), term=<function term_of>, per_place=<function per_place_of>), copies: ~cottax.core.maths.places.PlaceToPlace = ^copy, contracts: tuple = (RootFinding(), FixedPointIteration(), Minimisation(), ConstrainedMinimisation(), Integration()), role_places: ~cottax.consumers.surface.interface_types.RolePlaces = RolePlaces(entries={<class 'cottax.core.driven.roles.Start'>: ^start, <class 'cottax.core.driven.roles.Steps'>: ^steps, <class 'cottax.ode.contracts.Times'>: ^times, <class 'cottax.ode.contracts.Trajectory'>: ^trajectory}))[source]

Bases: RelationalDeclaring, OdeDeclaring, RelationalEditing, Architecting, Driving, Running

The surface a study writes through: every shipped part, at the pair’s defaults.

copies: PlaceToPlace = ^copy

^copy.var.

Type:

Where a cut’s copy of a place goes

contracts: tuple = (RootFinding(), FixedPointIteration(), Minimisation(), ConstrainedMinimisation(), Integration())

The contracts a problem is driven under, the first an implementation implements.

role_places: RolePlaces = RolePlaces(entries={<class 'cottax.core.driven.roles.Start'>: ^start, <class 'cottax.core.driven.roles.Steps'>: ^steps, <class 'cottax.ode.contracts.Times'>: ^times, <class 'cottax.ode.contracts.Trajectory'>: ^trajectory})

Where a driver’s data and reports go, a rule per role.

property closing: Closing

Each group closed by copy = var, the copy where copies says and the closure at ^closure.<the cycle’s first member>: one mint for a cut and a closing.

class Drive(implementations: tuple[DriverImplementation, ...], contracts: tuple[DriverContract, ...], places: Callable[[object, tuple, DriverContract], tuple[tuple, tuple]])[source]

Bases: ComposedOp

Every problem no driver answers yet, driven by the first implementation whose contract accepts its shape, under the first of contracts it implements, at the places places(at, unknowns, contract) gives (its data and its reports, as Assign takes them), and implemented by it. A problem already driven and not implemented is implemented by the first implementation whose implements covers its contract; one already implemented is left alone.

implementations: tuple[DriverImplementation, ...]
contracts: tuple[DriverContract, ...]
places: Callable[[object, tuple, DriverContract], tuple[tuple, tuple]]
composed(graph: NestingGraph)[source]

The ops this one is. Takes a graph, so an expansion may depend on what it meets.

Return type:

tuple[GraphOp, ...]

chosen(name, problem)[source]
Return type:

DriverImplementation

covering(name, contract: DriverContract)[source]

The first implementation of contract, a problem’s already.

Return type:

DriverImplementation

contract_for(implementation: DriverImplementation)[source]

The default contract an implementation answers: the first it implements.

Return type:

DriverContract

class RolePlaces(entries: OrderedMap[type[Role], PlaceToPlace])[source]

Bases: Frozen

Where a driver’s data and reports go, a rule per role (entries), found along the role’s ancestry, the most specific first: a PerUnknown role’s applied to each unknown, a PerProblem one’s to the problem’s name read as a place. A role with no entry is refused: nothing is named after a role unless a rule says so. a | b joins two, b’s winning.

entries: OrderedMap[type[Role], PlaceToPlace]
rule(role: type[Role])[source]

The rule for role: its own entry, else its nearest ancestor’s.

Return type:

PlaceToPlace

class Mint(*_: Any, **__: Any)[source]

Bases: Frozen

A purpose, by its class: what a name is derived for. Its spelling (^copy) labels a derived name; nothing finds a purpose by it.

class Copy[source]

Bases: Mint

A cut’s copy of a variable: ^copy.y.

class Closure[source]

Bases: Mint

Where a closure of cuts binds: ^closure.<the cycle’s first member>.

class Purpose(mint: Mint)[source]

Bases: Frozen

A purpose as a study writes it: called on a name as written, the Derived name.

mint: Mint
beside(written: Any, *names: str)[source]

The place for this purpose names deeper than the place written.

Return type:

Derived

rate = ^rate

Each shipped purpose, called on a name as written for the name derived from it: cx.copy(‘y_2’) is ^copy[‘y_2’], cx.solve(‘f’) the problem named after f, cx.given.beside(‘y’, ‘k’) a read written as a value.

initial = ^initial

Each shipped purpose, called on a name as written for the name derived from it: cx.copy(‘y_2’) is ^copy[‘y_2’], cx.solve(‘f’) the problem named after f, cx.given.beside(‘y’, ‘k’) a read written as a value.

span = ^span

Each shipped purpose, called on a name as written for the name derived from it: cx.copy(‘y_2’) is ^copy[‘y_2’], cx.solve(‘f’) the problem named after f, cx.given.beside(‘y’, ‘k’) a read written as a value.

times = ^times

Each shipped purpose, called on a name as written for the name derived from it: cx.copy(‘y_2’) is ^copy[‘y_2’], cx.solve(‘f’) the problem named after f, cx.given.beside(‘y’, ‘k’) a read written as a value.

trajectory = ^trajectory

Each shipped purpose, called on a name as written for the name derived from it: cx.copy(‘y_2’) is ^copy[‘y_2’], cx.solve(‘f’) the problem named after f, cx.given.beside(‘y’, ‘k’) a read written as a value.

class Locator[V: Place, N: Label][source]

Bases: Frozen, Choice, Generic[V, N]

How a bare string is converted to a cottax native Place or Label.

Handed in as:

surface.located(Under(V.plasma, GetAttrKey)), a surface whose strings are attributes under .plasma; cx.Scope(V.plasma, GetAttrKey) is the same.

places: AbstractClassVar[type[Place]]

what the names derived from one are found by.

Type:

The class of place it locates

nodes: AbstractClassVar[type[Label]]

The class of node name it locates.

abstractmethod place(s: str)[source]

A string written where a place is due.

Return type:

V

abstractmethod node(s: str)[source]

A string written where a node is due.

Return type:

N

class Conventions(reads: , tuple[~cottax.consumers.declaration.interface_types.PlaceWithValue, ...]]=ParameterReads(by_name=True), term: , ~cottax.consumers.declaration.interface_types.PlaceWithValue | None]=<function term_of>, per_place: , dict]=<function per_place_of>)[source]

Bases: Frozen

What a declaring part’s arguments mean, in three shapes, each a callable and cottax’s by default, so a study changes one: Conventions(term=my_term), my_term calling term_of for what it does not read itself. Held as a declaring part’s conventions, and asked through its methods of the same names (parameter_reads, term, per_place).

reads: Callable[..., tuple[PlaceWithValue, ...]] = ParameterReads(by_name=True)

the reads of the function of, one per parameter in order: reads as written (a mapping by parameter, or a tuple of every one), read_in a rule per name, a value minted at given(parameter).

Type:

reads(parameters, reads, read_in, *, place, given, of)

term[V: Place](written: Any, *, place: Callable[[Any], V], value_at: PlaceToPlace[V])

term(x, written, *, place, value_at): what is written where a place about x is due: None for zero, a value at value_at(x), or a place.

Return type:

Optional[PlaceWithValue[V]]

per_place[V: Place](written: Any, *, place: Callable[[Any], V])

per_place(among, written, *, place): what is written for each of among: a mapping by name, or one thing for the one place there is.

Return type:

dict[V, Any]

Shipped(by_name: bool = True)[source]

cottax’s conventions, a parameter read at its own name unless by_name is off.

Return type:

Conventions

class PytreeLocator[source]

Bases: Locator[VarPath, NodePath]

What every pytree locator decides alike: a string where a node is due is a key at the root, as a slot in a mapping names one. What a string means where a place is due is each final’s.

places

alias of VarPath

nodes

alias of NodePath

node(s: str)[source]

A string written where a node is due.

Return type:

NodePath

class Under(root: Var, key: type[GetAttrKey] | type[DictKey])[source]

Bases: PytreeLocator

A place string one key under a root, the key a GetAttrKey or a DictKey.

root: Var
key: type[GetAttrKey] | type[DictKey]
checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_name_key>,)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

place(s: str)[source]

A string written where a place is due.

Return type:

VarPath

property V: Keys

any path relative to it, in V’s syntax, where a string can say only one name: tfcoil.locator.V.coils[0].j.

Type:

A builder at the root

class InFull[source]

Bases: PytreeLocator

No place strings: every place written in full, a V path or a VarPath.

place(s: str)[source]

A string written where a place is due.

Return type:

VarPath

property V: Keys

the root is the root.

Type:

V itself

Scope(root: Var, key: type[GetAttrKey] | type[DictKey], by_name: bool = True)[source]

The shipped surface, a place string one key under root, and a parameter reads omits read at its own name unless by_name is off.

Return type:

ShippedSurface

flat = ShippedSurface(locator=Under())

flat.function(f, ‘y2’) writes [‘y2’] and reads each parameter by name.

Type:

A plain dict

absolute = ShippedSurface(locator=InFull())

every place a V path or a VarPath.

Type:

No place strings

class Declared[N: Label, V: Place](plan: Plan, given: OrderedMap[V, Any], place_tags: Tags[V] = {}, node_tags: Tags[N] = {})[source]

Bases: Frozen, Generic[N, V]

A plan, the values given at its boundary inputs, and the tags written on its places and on its node names. An op edits the plan alone: a value or a tag at a place the plan renames away is left where it was written, and a run takes no value nothing reads.

plan: Plan
given: OrderedMap[V, Any]
place_tags: Tags[V] = {}
node_tags: Tags[N] = {}
property graph: NestingGraph[N, V]
using(values: Mapping[V, Any])[source]

The same, with a value given at each of values, replaced or added: each a boundary input of the graph.

Return type:

Declared[N, V]

tags_of[T: Tagged](declared: Declared, name: Any, kind: type[T])[source]

The tags of kind written on name, a place or a node name.

Return type:

tuple[T, ...]

class Static(value: Any)[source]

Bases: Tagged

A given value that sizes or selects rather than computes (a count, a switch): kept as written and part of the compiled program’s key, so a new one compiles anew. Every other value given is an array, traced.

class FixedPointClosing[N: Label, V: Place](copies: PlaceToPlace[V], at: At[N, V])[source]

Bases: Closing[N, V], Generic[N, V]

One group closed as one problem: a copy per variable, named by copies, and the closure bound where at says.

copies: PlaceToPlace[V]
at: At[N, V]
bound_at(cycle: tuple[N, ...], group: ToCut[N, V])[source]

Where that op binds the problem closing group.

Return type:

N

class FixedPointCut[N: Label, V: Place](cuts: tuple[Cut[N, V], ...], at: N)[source]

Bases: ComposedOp[N, V], Generic[N, V]

Several cuts and the problem that determines every copy they mint: ^copy.x = x per cut, so the condition is the next iterate and the loop is re-closed through it.

cuts: tuple[Cut[N, V], ...]
at: N

Where the problem closing the cuts is bound – a binding of its own.

checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_cuts>,)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

property vars: tuple[V, ...]

What was cut, in the order the cuts were given.

property copies: tuple[V, ...]

The copies the readers end up reading, one per cut.

property definition: RelationalCondition[V]

One relation per cut, paired by the order the cuts were given.

composed(graph: NestingGraph[N, V])[source]

The ops this one is. Takes a graph, so an expansion may depend on what it meets.

Return type:

Sequence[GraphOp[N, V]]

class AtFirstMember[N: Label, V: Place](closure_of: LabelToLabel[N])[source]

Bases: At[N, V], Generic[N, V]

At the cycle’s first member in binding order, whatever the rule cut: one closure per cycle, so two groups on one cycle collide, which closed refuses by name.

closure_of: LabelToLabel[N]
class GaussSeidel[N: Label, V: Place][source]

Bases: Sweep[N, V], Generic[N, V]

In binding order.

order_of(graph: AbstractGraph[N, V])[source]

The order this graph is swept in, naming its nodes exactly once each.

Return type:

tuple[N, ...]

class GaussSeidelMinimal[N: Label, V: Place](limit: int)[source]

Bases: Sweep[N, V], Generic[N, V]

In the order minimal_feedback_order finds: the fewest variables opened.

limit: int

Above this many nodes on one cycle the exact search (2^n n) is refused.

order_of(graph: AbstractGraph[N, V])[source]

The order this graph is swept in, naming its nodes exactly once each.

Return type:

tuple[N, ...]

class GaussSeidelOrdered[N: Label, V: Place](order: tuple[N, ...])[source]

Bases: Sweep[N, V], Generic[N, V]

In the order written, which names the graph’s nodes exactly once each or is refused: an order meant for one cycle and got wrong is what leaves it unswept.

order: tuple[N, ...]
order_of(graph: AbstractGraph[N, V])[source]

The order this graph is swept in, naming its nodes exactly once each.

Return type:

tuple[N, ...]

class Jacobi[N: Label, V: Place][source]

Bases: CutRule[N, V], Generic[N, V]

Every coupling, for every reader, in one closure: each node runs from the previous iterate alone.

to_cuts(graph: AbstractGraph[N, V])[source]

One group per closure.

Return type:

tuple[ToCut[N, V], ...]

class NoCuts[N: Label, V: Place][source]

Bases: CutRule[N, V], Generic[N, V]

Nothing opened, said rather than fallen into.

to_cuts(graph: AbstractGraph[N, V])[source]

One group per closure.

Return type:

tuple[ToCut[N, V], ...]

class ByName[N: Label, V: Place](rules: tuple[tuple[N, CutRule[N, V]], ...])[source]

Bases: CutRule[N, V], Generic[N, V]

A rule per cycle, keyed by a node on it. Cycles are disjoint, so exactly one key lies on the graph handed; none or several is refused, never the first taken.

rules: tuple[tuple[N, CutRule[N, V]], ...]
checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_keys_distinct>,)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

to_cuts(graph: AbstractGraph[N, V])[source]

One group per closure.

Return type:

tuple[ToCut[N, V], ...]

class CloseFunctionalCycles[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: ComposedOp[N, V], Generic[N, V]

Every cycle of the function nodes closed by the rule, over the graph this op is applied to. Records the rule, where a closure records a decision.

rule: CutRule[N, V]
closing: Closing[N, V]
composed(graph: NestingGraph[N, V])[source]

The ops this one is. Takes a graph, so an expansion may depend on what it meets.

Return type:

Sequence[GraphOp[N, V]]

class Architecture[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: StagedOp[N, V], Generic[N, V]

An MDAO architecture, with a top (Monolithic) or without (Coupled).

A StagedOp, since each stage is decided off the graph the one before leaves; like any composition it proves nothing of its own, every op it applies being checked.

  1. what the level absorbs is combined (absorbing), and every cycle then off the level’s own is resolved (outside);

  2. the cycles of the level’s scope are cut over the boxes the final names, and each group is closed with one problem, the closure;

  3. every problem lying wholly inside another’s body is nested there, at every depth (unless the final combines declared problems, which then combines it as any); then every problem on each cycle of the scope is placed as the final’s combining says, the closures apart from the problems the model declared.

rule: CutRule[N, V]

the MDA method.

Type:

What is cut on each cycle

closing: Closing[N, V]

the op, and where its problem binds.

Type:

How a group is closed

boxes: AbstractVar[Boxes[N, V]]

Which solves in the scope the rule sees as one function each.

design: AbstractVar[tuple[N, ...]]

the top, or none.

Type:

The problems that are the level’s own and not models

combines_declared: ClassVar[bool] = True

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_nothing_nested>, <function check_implicit_models>)

(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.

Type:

What the op needs of the graph before it can compute anything

abstractmethod scope(graph: NestingGraph[N, V])[source]

The graph the cutting sees, and whose cycles are placed.

Return type:

NestingGraph[N, V]

abstractmethod outside(graph: NestingGraph[N, V])[source]

What resolves the cycles the scope leaves out, once absorbed.

Return type:

tuple[GraphOp[N, V], ...]

abstractmethod absorbing(graph: NestingGraph[N, V])[source]

What is combined before anything is cut.

Return type:

tuple[GraphOp[N, V], ...]

abstractmethod combining(opened: NestingGraph[N, V], closures: Sequence[N])[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

Return type:

Sequence[GraphOp[N, V]]

stages(graph: NestingGraph[N, V])[source]

Absorb; resolve what then lies outside; cut and close the scope of what is left; place every problem on its cycles, the closures being the problems the cutting bound.

Return type:

Generator[Sequence[GraphOp[N, V]], NestingGraph[N, V], None]

nesting_inside(scope: NestingGraph[N, V])[source]

Each problem of the scope lying wholly inside another’s body nested there, read before anything is cut; none where the final combines declared problems.

Return type:

tuple[GraphOp[N, V], ...]

resolution(graph: NestingGraph[N, V])[source]

The whole derivation: each stage’s ops and the graph it leaves. Refused as apply refuses.

Return type:

Resolution[N, V]

cycles_under(opened: NestingGraph[N, V], closures: Sequence[N])[source]

Per cycle of the scope in opened, the problems on it: the closures the cutting bound and the ones the model declared, but those already nested.

Return type:

tuple[OnCycle[N], ...]

class Monolithic[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Architecture[N, V], Generic[N, V]

Under a top: its interior is the scope, every requirement the design reaches is combined into it first, and every cycle then off the top’s is resolved by an analysis.

top: N

nothing searches for an optimiser.

Type:

The problem the design lives in. Required

analysis: Optional[Analysis[N, V]] = None

What resolves every cycle off the top’s; None is an MDA with this rule and closing.

checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_top_bound>, <function check_top_is_problem>, <function check_top_combinable>)

(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.

Type:

What the op needs of the graph before it can compute anything

property design: tuple[N, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

scope(graph: NestingGraph[N, V])[source]

The graph the cutting sees, and whose cycles are placed.

Return type:

NestingGraph[N, V]

outside(graph: NestingGraph[N, V])[source]

The analysis over the graph with the top’s cycle taken out, its ops applied to the whole: a cycle off the top’s is a component of its own.

Return type:

tuple[GraphOp[N, V], ...]

absorbing(graph: NestingGraph[N, V])[source]

Every requirement whose conditions the design of top reaches, combined into top: one Combine, or nothing.

Return type:

tuple[GraphOp[N, V], ...]

class Coupled[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: Architecture[N, V], Generic[N, V]

No top: the whole graph is the scope and nothing is absorbed. A requirement is left where it is, for the proof to refuse.

design: AbstractVar[tuple[N, ...]] = ()

the top, or none.

Type:

The problems that are the level’s own and not models

scope(graph: NestingGraph[N, V])[source]

The graph the cutting sees, and whose cycles are placed.

Return type:

NestingGraph[N, V]

outside(graph: NestingGraph[N, V])[source]

What resolves the cycles the scope leaves out, once absorbed.

Return type:

tuple[GraphOp[N, V], ...]

absorbing(graph: NestingGraph[N, V])[source]

What is combined before anything is cut.

Return type:

tuple[GraphOp[N, V], ...]

class MultidisciplinaryFeasible[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Monolithic[N, V], Generic[N, V]

Per cycle, the closures folded into one MDA nested in top, and each declared problem nested in that MDA – or in top, on a cycle nothing was bound on.

combines_declared: ClassVar[bool] = False

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class IndividualFeasible[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Monolithic[N, V], Generic[N, V]

top owns the coupling copies and drives the gaps to zero; each declared problem is a solve of its own inside its iteration.

combines_declared: ClassVar[bool] = False

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class Simultaneous[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Monolithic[N, V], Generic[N, V]

top absorbs every problem under it.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class Analysis[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: Coupled[N, V], Generic[N, V]

Per cycle, the closures folded into one, and each declared problem nested in it. A cycle nothing was bound on is left as it is: its one problem closes it.

combines_declared: ClassVar[bool] = False

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class MDF[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: MultidisciplinaryFeasible[N, V], Generic[N, V]

Multidisciplinary feasible over the disciplines.

boxes: AbstractVar[Boxes[N, V]] = disciplines

Which solves in the scope the rule sees as one function each.

class IDF[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: IndividualFeasible[N, V], Generic[N, V]

Individual discipline feasible over the disciplines.

boxes: AbstractVar[Boxes[N, V]] = disciplines

Which solves in the scope the rule sees as one function each.

class SAND[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Simultaneous[N, V], Generic[N, V]

Simultaneous analysis and design over the bodies: the states are the optimiser’s outright, so a solve’s own loop needs no cut.

boxes: AbstractVar[Boxes[N, V]] = bodies

Which solves in the scope the rule sees as one function each.

class MDA[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: Analysis[N, V], Generic[N, V]

A multidisciplinary analysis over the disciplines: each implicit model keeps its own solver, and one closure per cycle iterates the states between them.

boxes: AbstractVar[Boxes[N, V]] = disciplines

Which solves in the scope the rule sees as one function each.

class Boxes[N: Label, V: Place][source]

Bases: Frozen, Generic[N, V]

Which problems of the graph handed are seen as one function each.

abstractmethod folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Bodies[N: Label, V: Place][source]

Bases: Boxes[N, V], Generic[N, V]

None: the function nodes alone are seen.

folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Disciplines[N: Label, V: Place][source]

Bases: Boxes[N, V], Generic[N, V]

Every problem of the graph handed – a discipline under check_implicit_models, and under an architecture every implicit model in its scope.

folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Solves[N: Label, V: Place](names: tuple[N, ...])[source]

Bases: Boxes[N, V], Generic[N, V]

These, by name.

names: tuple[N, ...]
folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Resolution[N: Label, V: Place](absorbed: tuple[GraphOp[N, V], ...], outside: tuple[GraphOp[N, V], ...], closures: tuple[GraphOp[N, V], ...], opened: NestingGraph[N, V], combining: tuple[GraphOp[N, V], ...], graph: NestingGraph[N, V])[source]

Bases: Frozen, Generic[N, V]

Architecture applied to a graph in terms of GraphOps and the intermediate graphs. Useful for extracting which closures were inserted.

absorbed: tuple[GraphOp[N, V], ...]

one Combine, or none.

Type:

The requirements the design reaches, combined into the top

outside: tuple[GraphOp[N, V], ...]

the analysis’s closures and placing.

Type:

What resolved the cycles off the scope’s

closures: tuple[GraphOp[N, V], ...]

what the Closing returned.

Type:

What the cutting bound, one closure per group

opened: NestingGraph[N, V]

The graph after those two and before any problem is placed.

combining: tuple[GraphOp[N, V], ...]

each lying inside another’s body nested there, then the final’s own, placing the closures and the declared problems.

Type:

The ops placing the problems

graph: NestingGraph[N, V]

The result.

class Eq[source]

Bases: Rel

lhs = rhs.

symbol: str = '='

How a relation writes it.

class Le[source]

Bases: Rel

lhs <= rhs.

symbol: str = '<='

How a relation writes it.

class Min[source]

Bases: Sense

Driven down.

symbol: str = 'min'

How an objective writes it.

class Max[source]

Bases: Sense

Driven up.

symbol: str = 'max'

How an objective writes it.

class Objective[V: Place](place: V, sense: type[Sense])[source]

Bases: Frozen, Generic[V]

A place and the way it is driven: which way changes the answer, so it is the problem’s, stored with the place it drives.

place: V
sense: type[Sense]
checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_sense>,)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

relabel(renaming: Renaming[V])[source]
Return type:

Objective[V]

class Relation[V: Place](lhs: Optional[V], rhs: Optional[V], op: type[Rel])[source]

Bases: Frozen, Generic[V]

lhs op rhs between two places; a side of None is zero.

lhs: Optional[V]
rhs: Optional[V]
op: type[Rel]
checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_sides>, <function check_op>)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

property terms: tuple[V, ...]

The sides that are places, left then right.

relabel(renaming: Renaming[V])[source]
Return type:

Relation[V]

class RelationalCondition[V: Place](relations: tuple[Relation[V], ...], objectives: tuple[Objective[V], ...], unknowns: tuple[V, ...], parameters: tuple[V, ...])[source]

Bases: ConditionalNode[V], Generic[V]

A condition node: relations and objectives over places, the unknowns it determines and the parameters it holds fixed. Every other term is a condition. Supports addition.

relations: tuple[Relation[V], ...]
objectives: tuple[Objective[V], ...]
unknowns: tuple[V, ...]

What this node determines; () for a requirement.

parameters: tuple[V, ...]

a bound, a limit. Read, not a condition, so a proof asks them off the problem’s cycle.

Type:

Terms read and held fixed while the unknowns move

checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_relates_something>, <function check_parameters>)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

property conditions: tuple[V, ...]

The objectives, then every relation’s terms that are neither unknowns nor parameters, in order.

property reads: tuple[V, ...]

The conditions, then the parameters.

property owns: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

determined(unknowns: tuple[V, ...])[source]

Same ConditionalNode but determined by the unknowns.

Return type:

RelationalCondition[V]

relabel(renaming: Renaming[V])[source]

Relabels the relations, objectives, unknowns and parameters.

Return type:

RelationalCondition[V]

class RootFinder[V: Place][source]

Bases: DriverContract[V], Generic[V]

Answers equalities, a fixed point among them.

static accepts(node: object)

No objective, every relation an equality. is_fixed_point / is_root_find.

Return type:

bool

class FixedPointIterator[V: Place][source]

Bases: DriverContract[V], Generic[V]

Answers u = g(u) by updating each unknown to its g(u).

static accepts(node: object)

A fixed point with each unknown on the left of exactly one relation: one update u <- g(u) per unknown.

Return type:

bool

class Minimiser[V: Place][source]

Bases: DriverContract[V], Generic[V]

Answers one objective with no relation beside it.

static accepts(node: object)

An optimise with no relation beside the objective.

Return type:

bool

class ConstrainedMinimiser[V: Place][source]

Bases: DriverContract[V], Generic[V]

Answers one objective, with or without relations to respect.

static accepts(node: object)

Exactly one objective. is_unconstrained_optimise / is_constrained_optimise.

Return type:

bool

class RootFinding[V: Place](steps: bool)[source]

Bases: RootFinder[V], Generic[V]

From a Start; steps reports Steps.

steps: bool
property takes: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reports: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class FixedPointIteration[V: Place](steps: bool)[source]

Bases: FixedPointIterator[V], Generic[V]

From a Start; steps reports Steps.

steps: bool
property takes: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reports: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class Minimisation[V: Place](steps: bool)[source]

Bases: Minimiser[V], Generic[V]

From a Start; steps reports Steps.

steps: bool
property takes: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reports: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class ConstrainedMinimisation[V: Place](steps: bool)[source]

Bases: ConstrainedMinimiser[V], Generic[V]

From a Start; steps reports Steps. Its bounds are relations of the problem over parameters, not data of the driver: they change the answer.

steps: bool
property takes: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reports: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

CONTRACTS = (RootFinding(), FixedPointIteration(), Minimisation(), ConstrainedMinimisation(), Integration())

an implementation answers a problem by the first one it implements.

Type:

The default contracts, every shipped language’s

class OdeDeclaring(locator: Locator[V, N], conventions: ~cottax.consumers.declaration.conventions.Conventions = Conventions(reads=ParameterReads(by_name=True), term=<function term_of>, per_place=<function per_place_of>))[source]

Bases: Declaring

The ODE declarations: a rate per state, and the ODE integrating it.

rate

A function returning the rate of each state, and the ODE determining the states: rate(fn, *states), or @rate(*states). initial= (a mapping, or one for the one state) and span= say where those are read, a value written there given; two rates joined by combine read one span. record={‘x’: ‘x_history’} with times=’ts’ declares the ODE driven, writing each named state at every time.

class Rate[N: Label, V: Place](fn: Body, function_reads: tuple[PlaceWithValue[V], ...], outputs: tuple[V, ...], record: OrderedMap[V, V], times: Optional[PlaceWithValue[V]], initial: OrderedMap[V, PlaceWithValue[V]], span: Optional[PlaceWithValue[V]], *, output_tags: Tags[V] = {})[source]

Bases: Paired[N, V], Generic[N, V]

A function writing ^rate.x per state (its outputs), in that order, and at ^solve.at the ODE determining the states from their initial values (initial, else ^initial.x) over the span (span, else ^span of the first state). Where a study names a history (record, at times) the ODE is declared driven, by Integration(trajectory=True), so a model reading a history is coupled to it from the declaration on.

record: OrderedMap[V, V]

The place each recorded state’s history is written to.

times: Optional[PlaceWithValue[V]]

Where the times a history is saved at are read.

initial: OrderedMap[V, PlaceWithValue[V]]

Where each named state’s initial value is read.

span: Optional[PlaceWithValue[V]]

Where the span is read.

checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_named>,)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

condition_mint

alias of Solve

property function_outputs: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property terms: tuple[PlaceWithValue[V], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property condition: OdeCondition[V]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

condition_node(at: N)[source]

The ODE, driven where a history is recorded: the times where times says, each history where record names it, else at ^trajectory.x.

Return type:

ConditionalNode[V]

property problem: N

Where its ODE binds, the rate handed to declare loose: ^solve.<fn>.

class Dt[V: Place](state: V, rate: V, initial: V)[source]

Bases: Frozen, Generic[V]

x’ = r from x(t0) = x0: state changes at the rate held at rate, starting from the value held at initial.

state: V
rate: V
initial: V
relabel(renaming: Renaming[V])[source]
Return type:

Dt[V]

class OdeCondition[V: Place](relations: tuple[Dt[V], ...], span: V)[source]

Bases: ConditionalNode[V], Generic[V]

x’ = r from x0 per relation, over the span: an initial-value problem, so one solution. It determines exactly its states, so it is always a problem: outside its cycle a state is its value at t1; inside, the current state. The initial values and the span are its parameters, held fixed while it is integrated. Supports addition.

relations: tuple[Dt[V], ...]

A state twice, or a state that is a rate or an initial value, is core’s refusal (OwnsTwice, ReadsOwn).

span: V

one for every state.

Type:

Where (t0, t1) is read

property states: tuple[V, ...]
property rates: tuple[V, ...]
property initials: tuple[V, ...]
property parameters: tuple[V, ...]

The initial values, then the span.

property unknowns: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property conditions: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reads: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property owns: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

determined(unknowns: tuple[V, ...])[source]

Itself, handed exactly its states: what it determines is not edited.

Return type:

OdeCondition[V]

relabel(renaming: Renaming[V])[source]

The same definition with its places renamed.

Return type:

OdeCondition[V]

class Integration[V: Place](trajectory: bool)[source]

Bases: Integrator[V], Generic[V]

The final state its answer; trajectory takes the Times and reports each state’s Trajectory at them: one sampling of the solution, the integrator’s to give.

trajectory: bool
property takes: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reports: tuple[type[Role], ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

class Integrator[V: Place][source]

Bases: DriverContract[V], Generic[V]

Answers an ODE by integrating it.

static accepts(node: object)

An ODE: what an integrator answers.

Return type:

bool

class Times[source]

Bases: PerProblem

The times a trajectory is saved at: one array, within the span and monotone in the direction of integration; its length is the trajectory’s.

class Trajectory[source]

Bases: PerUnknown

Reported: each state at every one of the Times, stacked along a leading axis.

class Newton(rtol: float = 0.0001, atol: float = 0.0001, max_steps: int = 256)[source]

Bases: Optimistix[RootFinder]

optx.Newton on the equality residuals, as many numbers as the unknowns.

solve[V: Place](posed: Posed[V], context: Context, data: ByRole)[source]

The optimistix solve answering posed: its function takes args=(posed, context).

Return type:

Solution

implements

alias of RootFinder

class Picard(rtol: float = 0.0001, atol: float = 0.0001, max_steps: int = 256)[source]

Bases: Optimistix[FixedPointIterator]

optx.FixedPointIteration: u <- g(u), no Jacobian taken.

solve[V: Place](posed: Posed[V], context: Context, data: ByRole)[source]

The optimistix solve answering posed: its function takes args=(posed, context).

Return type:

Solution

implements

alias of FixedPointIterator

class BFGS(rtol: float = 0.0001, atol: float = 0.0001, max_steps: int = 256)[source]

Bases: Optimistix[Minimiser]

optx.BFGS on the one objective.

solve[V: Place](posed: Posed[V], context: Context, data: ByRole)[source]

The optimistix solve answering posed: its function takes args=(posed, context).

Return type:

Solution

implements

alias of Minimiser

class SLSQP(tol: float = 1e-08, max_steps: int = 200, strict: bool = True, jacobian: Callable = <function jacfwd>)[source]

Bases: DriverImplementation[ConstrainedMinimiser]

scipy.optimize.minimize(method=’SLSQP’) on the canonical form: the objective, the equalities as eq, the inequalities negated as ineq (scipy’s >= 0), and the box as scipy’s bounds, so every iterate stays inside it.

needs: AbstractClassVar[frozenset[type[Role]]] = frozenset({<class 'cottax.core.driven.roles.Start'>})
provides: AbstractClassVar[frozenset[type[Role]]] = frozenset({<class 'cottax.core.driven.roles.Steps'>})
tol: float = 1e-08
max_steps: int = 200
strict: bool = True

Raise when scipy does not report success; off, the answer is taken as it stands.

jacobian(argnums: int | Sequence[int] = 0, has_aux: bool = False, holomorphic: bool = False)

How the Jacobian is taken: jax.jacfwd, jax.jacrev, or any hashable function of a function, such as one pulling rows back one at a time to save memory.

Return type:

Callable

implements

alias of ConstrainedMinimiser

canonical[V: Place](condition: RelationalCondition[V], unknowns: tuple[Any, ...], values: tuple[Any, ...])[source]

The objectives, and every relation but a bound as a residual in its group.

Return type:

Canonical

box[V: Place](condition: RelationalCondition[V], unknowns: tuple[Any, ...], values: tuple[Any, ...])[source]

Each unknown’s bounds: the tightest of its lower bounds, and of its upper ones.

Return type:

Box

class Box(lower: tuple[Any, ...], upper: tuple[Any, ...])[source]

Bases: NamedTuple

Per unknown, in condition.unknowns order, its lower and upper bound, None where it has none.

lower: tuple[Any, ...]

Alias for field number 0

upper: tuple[Any, ...]

Alias for field number 1

class NotSquare(implementation: str, got: int, unknowns: int)[source]

Bases: Violation

implementation: str
got: int
unknowns: int
template: AbstractClassVar[str] = '{implementation} needs as many numbers in the residuals as in the unknowns -- this problem gives {got} for {unknowns}'

e.g. ‘output {place!r} is owned by both {other!r} and {node!r}’

Type:

Wording

class JitGraph[N: Label, V: Place](graph: NestingGraph[N, V])[source]

Bases: CallableGraph[N, V], Generic[N, V]

A callable graph whose every node is a jit cache key.

checks_node: PerLevel[tuple[Callable[[N, NodeDefinition[V]], Iterator[Violation]], ...]] = (<function check_hashable>, <function check_reassembles>)

the one thing a level below adds.

Type:

(name, node) -> violations

class Running(locator: Locator[V, N])[source]

Bases: Part

A model run on values written by name (values) or read from a caller’s structures (read_from), each keyed by Inputs or a driver’s role: run(model, values, read_from), through valued. A datum of a per-unknown role is read in a structure at its unknown’s place, or, the unknown a copy by this surface’s copies, at what it copies.

copies: AbstractVar[PlaceToPlace]

a copy’s datum is read at what it copies.

Type:

Where a cut’s copy of a place goes

valued(model: NestingGraph | ProvedGraph | Model, values: Mapping[type, Mapping[Any, Any]] = OrderedMap(), read_from: Mapping[type, Any] = OrderedMap(), *, proof: type = CallableGraph)[source]

model (a graph, a proof, or a Model: a Declared), proved a proof unless it is one, with a value at each boundary input, from exactly one source: the declaration’s own values; values, by name, {Inputs: {‘x’: 1.}, Start: {‘z_1’: 5., s.copy(‘y_2’): 1.}}, a driver’s data by role and unknown, a per-problem role at any one unknown of its problem; or read_from, a structure per key, {Inputs: state, Start: state}. Refused: a value nothing reads, a place given twice, a key that is no problem’s unknown, a role its driver does not take, and any input left without a value.

Return type:

GraphWithValues

run(model: NestingGraph | ProvedGraph | Model, values: Mapping[type, Mapping[Any, Any]] = OrderedMap(), read_from: Mapping[type, Any] = OrderedMap())[source]

model run, valued as valued says: every place’s value, read by name.

Return type:

Results

class Results(values: OrderedMap, surface: Surface, graph: NestingGraph)[source]

Bases: Mapping

Every place’s value after a run, read by any name the surface reads: out[‘y_1’], out[V.y_1], or the place itself; a driver’s datum or report by role at an unknown, out[Trajectory, ‘x’]. out.into(state) writes them into a structure, out.into(history, Trajectory) a role’s at each unknown’s place.

into(state: Any, key: type = Inputs)[source]

state with each place the run computed written where the state holds it, an input never; under a per-unknown role, that role’s value at each unknown’s place (at what a copy copies), as read_from reads it.

Return type:

Any

class Inputs[source]

Bases: object

The key for a variable’s own value, by name or in a structure, beside a driver’s roles: s.run(model, {Inputs: {‘x’: 1.0}}, read_from={Inputs: state}). Not a role.

class Traced[N: Label, V: Place](valued: GraphWithValues[CallableGraph[N, V], V])[source]

Bases: Frozen, Generic[N, V]

The run traced once by jax, nothing computed: the whole graph as one jaxpr, and every place’s shape. Refused: the first refusal the run raises (a body’s miscount, ReturnedUnlike), or a body failing at these shapes (TraceFailed), by node. A value handed in may be an array or a jax.ShapeDtypeStruct; any other value reaches the bodies as it is, so a setting stays a setting.

traced = Traced(GraphWithValues(graph, values)) traced.shapes, traced.jaxpr

valued: GraphWithValues[CallableGraph[N, V], V]
checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_traced_callable>, <function check_traces>)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

property jaxpr: Any

The whole graph as one closed jaxpr, its inputs the shapes handed in.

property shapes: OrderedMap[V, Any]

the inputs, then what the graph computes.

Type:

Every place’s shape and dtype (a pytree of them where its value is one)

class Start[source]

Bases: PerUnknown

Where each unknown starts.

class Driven[V: Place](condition: ConditionalNode[V], contract: DriverContract[V], data: tuple[tuple[V, ...], ...], reports: tuple[tuple[V, ...], ...])[source]

Bases: DrivenNode[V], Generic[V]

Final of DrivenNode that has no implementation.

condition: ConditionalNode[V]

The node answered, without the driver.

contract: DriverContract[V]
data: tuple[tuple[V, ...], ...]

One slot per role in driver.takes, each as many places as its role’s arity.

reports: tuple[tuple[V, ...], ...]

One slot per role in driver.reports, the same way.

checks: PerLevel[tuple[Callable[[Any], object], ...]] = (<function check_pairing>, <function check_slots>)

Callable [self] -> iterable of violations, which are raised at construction unless skipped (see unchecked).

property unknowns: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property conditions: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property reads: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

property owns: tuple[V, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

determined(unknowns: tuple[V, ...])[source]

Refused: an algorithm was chosen for the node as it stands, and its per-unknown slots are laid out against the unknowns it had.

Return type:

Driven[V]

undriven()[source]

The condition node with the driver taken off: what Undrive edits. A final that cannot have it taken off refuses here.

Return type:

ConditionalNode[V]

relabel(renaming: Renaming[V])[source]

The same definition with its places renamed.

Return type:

Driven[V]

class CallableGraph[N: Label, V: Place](graph: NestingGraph[N, V])[source]

Bases: RealisedGraph[N, V], Generic[N, V]

A realised graph whose every implementation is callable / driver implemented

checks_node: PerLevel[tuple[Callable[[N, NodeDefinition[V]], Iterator[Violation]], ...]] = (<function check_function_callable>, <function check_implements_its_driver>)

the one thing a level below adds.

Type:

(name, node) -> violations

completed(graph: Union[NestingGraph[Any, VarPath], ProvedGraph[Any, VarPath]], tree: Any)[source]

tree with None at each place of graph it lacks, a minted one aside, so a run has a slot for every value it writes back. Only a dict grows a key; a None the run must read, an input or a start, is still refused there by name.

Return type:

Any

class PlainFormat(notation: Notations | None = None)[source]

Bases: Formatter

Every name by spell_plain, a minted one in its purpose’s notation (notation keyed by the Mint class, else its MintDrawing), else as <spelling>(·) – what a drawing writes unless told otherwise.

spell(path: Label)[source]
Return type:

str

set(source: str)[source]
Return type:

str

label(text: str)[source]
Return type:

str

text(text: Text)[source]
Return type:

str

outright(path: Label)[source]
Return type:

bool

notation(m: Mint)[source]
Return type:

Notation

class LatexFormatter(names: Mapping[str, str] | None = None, notation: Notations | None = None, spell: Callable[[Label], str] = spell_plain)[source]

Bases: Formatter

Every name spelt as LaTeX: names maps a plain spelling (spell, spell_plain by default) to the LaTeX that replaces it – {‘V1’: r’mathcal{D}_1’} – and anything not in it is read as LaTeX as it stands, digits made subscripts (subscripted).

A minted name given in names is named outright: drawn as given, and not under the notation of its purpose – {‘^solve.S1’: ‘S_1’} draws S_1. Every other minted name is written in its purpose’s notation, in LaTeX: notation by Mint class – {Solve: Around(r’S_{{}}’)} – else its MintDrawing’s, else as mathrm{<spelling>}(·).

spell(path: Label)[source]
Return type:

str

set(source: str)[source]
Return type:

str

label(text: str)[source]
Return type:

str

text(text: Text)[source]
Return type:

str

outright(path: Label)[source]
Return type:

bool

notation(m: Mint)[source]
Return type:

Notation

render_xdsm_svg(model, **kw)[source]

Visualization’s render_xdsm_svg, as render_html takes its model and formatter.

render_matrix_svg(model, **kw)[source]

Visualization’s render_matrix_svg, as render_html takes its model and formatter.

by_namespace(depth: int | None = None)[source]

The grouping a graph’s own names declare (PlaceDrawing.namespace_of: its leading names without its own, a minted one read through its namespace), depth levels deep.

Return type:

Callable[[Label], tuple[str, ...]]

render_html(model, **kw)[source]

Visualization’s render_html of a graph, a proof, a Plan or a Declared (its plan, stepped op by op), written plainly unless formatter= says otherwise (LatexFormatter(names)).

draw(model, **kw)[source]

Visualization’s draw, as render_html takes its model and formatter.

render(model, **kw)[source]

Visualization’s render, as render_html takes its model and formatter.

to_dot(model, **kw)[source]

Visualization’s to_dot, as render_html takes its model and formatter.

class Style(name: str, surface: str, ink: str, muted: str, model: Pair, variable: Pair, variable_ink: str, boundary: Pair, edge: str, chip: Pair, ground: Ground, stated: Pair, unanswered: str, bands: tuple[str, ...], band_stroke: str, dashed: bool, run_ring: str | None, undriven: str, tint: float, driven_tint: float, cut_em: float, bold: bool, font: str | None, ring_gap: float, nest_em: float, ring_radius_em: float, groups: tuple[str, ...])[source]

Bases: Frozen

The colours and marks of every drawing in this package. A problem’s hue is its category’s; value is structure; fill and contour are how far a problem is decided.

surface is the ground, ink a box’s label, muted a boundary label or a key entry. model, variable and boundary are (fill, stroke) for a box that runs, a coupling and the two boxes standing for the world outside; variable_ink a variable’s name. edge a coupling line. chip is a condition slot’s (fill, stroke), drawn translucent over its problem.

A category’s colour is its own (Kind.colour), and ground paints it (paint): the hexagon of a problem of that category, and the contour of the ring it answers. A renderer holding a category’s name takes the colour from its struct. stated is a condition that determines nothing and whose type is unknown; one whose type is known is drawn hollow in that type’s stroke. unanswered is the contour of a ring no driver answers (a bare cycle, or several problems with nothing nested).

bands fills a solve ring, one entry per nesting depth (cycling); empty draws the ring as a contour alone. band_stroke is the contour of a band’s key sample, dashed whether a solve ring’s contour is dashed. run_ring is the contour of a block merely run in order, None to draw none.

undriven says how a problem without a driver is drawn: ‘tint’ fills it tint of the way to its type’s fill (driven_tint once driven) and cuts its contour, and a ring nothing answers, open by cut_em in the middle of top and bottom; ‘solid’ draws every problem alike. bold sets every name in a heavier weight. font is a CSS family list, None for the renderer’s own. ring_gap is a solve ring’s clearance as a fraction of the gap between two boxes, nest_em what a nested ring and a driver’s chevron stand off a ring (in ems, floored at that clearance), ring_radius_em a ring’s corner.

groups is the categorical palette a drawing colours groups of nodes with; it keeps clear of the categories’ hues.

name: str
surface: str
ink: str
muted: str
model: Pair
variable: Pair
variable_ink: str
boundary: Pair
edge: str
chip: Pair
ground: Ground
stated: Pair
unanswered: str
bands: tuple[str, ...]
band_stroke: str
dashed: bool
run_ring: str | None
undriven: str
tint: float
driven_tint: float
cut_em: float
bold: bool
font: str | None
ring_gap: float
nest_em: float
ring_radius_em: float
groups: tuple[str, ...]
paint(colour: Pair | None)[source]

The (fill, stroke) of a problem of a category coloured colour, or stated’s for none.

Return type:

Pair

fill(colour: Pair | None, driven: bool)[source]

What a problem of a category coloured colour is filled with, driven or not; stated’s grey, tinted as any, for none.

Return type:

str

band(depth: int)[source]

The fill of a solve ring at depth, or None for a contour alone.

Return type:

str | None

property cuts: bool

Whether a problem without a driver has its contour cut open.