Skip to main content

solvers.compartmental

solvers.compartmental

Not for the user: the compartmental engine: a declared model run as groups of people (ode, ide, binomial, gillespie, and tau)

It exists so that a model with nothing per person can run faster than as agents, from the same declaration.

Used with: compartments; declared modules

Classes

Name Description
Compartmental Runs a graph as compartments: deterministically (ode, ide) or stochastically

Compartmental

solvers.compartmental.Compartmental(module, sim, solver=None)

Runs a graph as compartments: deterministically (ode, ide) or stochastically (binomial, gillespie, or tau)

It exists so that the deterministic and stochastic forms share one engine.

The states are expanded into compartments (one per branch and sub-stage) and the transitions into a flat list of flows, each with a source compartment, a rate, and the compartments it feeds. Every solver steps the same list of flows.

Attributes

Name Description
engines The engines whose people its program holds, as joint states’: this one
owner What holds the people and the program that runs them: this engine, or the joint states its disease is tracked jointly in (see ss.solvers.JointStates), whose program steps them all
saturates Whether a term of the mixing is a network whose edges each transmit at most once in a step (see saturation())
shared Whether this engine moves people in ways that belong to the sim rather than to the module (aging, relocating, the movement register): in joint states, only one does (see ss.solvers.JointStates.lead), since they all see the same people
smooth Whether any parameter varies smoothly in time (not as a step function), so is taken at the middle of each step
transfer_index The position of each transfer among the flows of a whole run (after the transitions, with the other movers)

Methods

Name Description
add_per_births After a step: the children of those who went through a transition with births driven by its flow (ss.birth(when=)), n for each, in the youngest groups of their parents’ place
aging_rates The rate per year at which people age out of each age group (but the last): the density of people in the year below
apart_fracs For several non-exponential dwell times out of a state, each for other people (who=): the fraction of each group that enters each one’s track, 1 for the one it has (the first, if none)
arrive Add an amount to a state, split between its tracks; with before=True, as if they arrived a step before (people infectious at the start, who have been so for the first step, as agents date them), so one slot along a conveyor
as_is Whether a dwell time runs as it is, as a conveyor of whole steps (see slot_rates()), rather than as Erlang stages: under
at_home Whether a time fraction between places (a sparse array) keeps everyone at home, as np.allclose(frac, np.eye(P)) would say, without forming either
at_middle Take values that vary smoothly in time at the middle of the step, which runs from time point ti to the next, as tables() does, so that a stepped run takes the same values as a whole one
attr An attribute in a compartmental run: a trait is the mean of its distribution, as a parameter that is a distribution is (see trait_mean())
backfill_burnin A module’s people who start part way through (ss.Pregnancy(burnin=True): see its burnin_plan()): each group’s
binomial_substeps The substeps the chain-binomial solver takes in each step, from the fastest total rate out of a compartment of people at the start (see substeps())
birth_map Where the children of the people in each group are born (rows to columns): the youngest group of each dimension, by the split of the others, in their parents’ place
births_of The engine and inflow of each declared module with an ss.birth(when=) of the same transition as tr (this module’s own first)
branch_where Whether a transition is a branch out of each of its sources whose who= is on states and strata, so closes it at entry (see branch_mult()) rather than changing its rate
build Lay out the compartments (after init_dims()): the dwell times, the protection between strains, and the compartments and flows; raises a CapabilityError for what has no compartmental form yet
build_layout Expand the states into compartments and the transitions into flows
call_uids A function that takes uids, which a compartmental run does not have (see Agents.call_uids())
certain The name of a transition with an infinite rate (a probability of 1 over the period) at the start, which the kernels take as everyone moving at once (see ss.kernels.certain()), and which JAX and the exact solver by place do not; or None
chain_start The compartment where the people of a group of linked states (see ss.graph.Graph.linked()) are with no immunity, for next_generation():
changes The rate of change of each compartment from new infections (new=True: arrivals only), or from every other flow; see next_generation()
changing_steps The steps on which the modifiers of this module change, if all they do is switch on and off at a date, so the tables need working out only on those steps; or None if they could change on any step
check_noise Refuse noise on a rate (ss.Transition(noise=)) where it isn’t drawn: it is drawn by the chain binomial, once a substep for each flow, and by tau-leaping once a leap, so a transition must be one flow; the ODE leaves it out (see init_program()), or with approximations=“error” refuses it
clock A clock, which a compartmental run does not keep (see Agents.clock())
collect The results of many runs, from the number in each state and the flow along each transition and mover
constant_transfer Whether a transfer’s rate holds for the whole run, so its mover can be set once before it (see run_args()): a rate or duration of plain values, with no modifiers
count_deaths For a split between states and ss.dead (with no ss.stay): those who died are its flow less those who went to a state, so the two agree in each run; flows are by flow along the axis before the last (the groups)
count_stocks As ss.solvers.Engine.count_stocks(), for every state at once
count_weighted A weighted count ((ss.by(biting=w)*I).n, A.n_infectious): the people in each state and group counted by the group’s weight (and infectiousness), in the same place
current Whether the layout holds for the sim’s groups now, and for its solver (or the one given): one made to choose the solver is used by the run unless the groups changed since (see ss.solvers.make_engine())
define Replace the declared states on the module with their run-time form
delay_steps The length of a fixed delay (ss.constant), plus any minimum stay before it, in whole steps: agents leave at the start of the step nearest its end
derived The results that are worked out from the number in each state and the flow along each transition
derived_outcomes What step_outcomes() does on each step, for every step at once (with expected, outcomes of whole events are their expected number, rather than drawn); only the outcomes in names, if given (with those they are worked out from); for many runs (the first dimension of the flows), each drawn from the random numbers of its seed in seeds
det_flow Whether a flow is of a state that is not people, so is never drawn as whole events
drawn_outcomes The outcomes of derived_outcomes() when they are drawn: a step at a time, by Engine.report_outcome(), with the runs and groups (all but the last dimension of the flows) side by side
eval An expression’s value: from the tape, if it is on it (see init_tape()), else worked out here
event_frac The people who went through a transition in the last step (or one of its branches, to), as a fraction of the state they are now in
exit_rate The rate at which people leave a state other than by infection (one over their mean time in it), as a mean over groups
exposure Exposure to people in a state through the sim’s mixing: the chance that a contact is with someone in that state
exposure_comps The set of an exposure in the program: of a state, by its name, or of a count that the contact matrices act on, which is its key (see flatten_rates())
exposure_trans The infectiousness of an exposure in the program, by group: of a state, with its modifiers and strain (mask); 1 for a count (whose state is None)
expr_key What a function’s expression is made of, to tell when it changes: its text, and the exact value of each number in it (None if it is not an expression)
find_start_deps The parameters read by the start and the branches (see start_key()), or False if something else can change them, or doing it has an effect of its own
flatten_rates The operations of the kernels for each rate: what they act on, in order; the operations, and where each flow’s start; the size of stack they need; and the row of consts of each mover’s rate (see init_program())
flow_base The rate of a flow before its multipliers: the only part that can depend on the number in each compartment
flow_mult The multipliers on a flow’s rate, which hold for the whole step
flows_of The flows of each engine its program holds, as joint states’: this one’s
force Move a fraction of the people in each state a transition leaves from (or in srcs), and each group, to a state, counted in the transition’s flow if there is one (as when a treatment cures); a synchronized flow moves other modules’ coordinates too; with y, of those people (by compartment and group) rather than the engine’s
gives_back In a branching process, whether a move from one state to another is from the infected side back into the uninfected side, which it takes people out of the model by instead
group_needs The states and flows (by position) that are needed by group: those of the results that keep their values by group, and what they are worked out from
held Whether a value that varies in time is a step function (so is held for each step)
held_frac The fraction holding a product (itn.held_frac): the fraction of the people in the same place who hold it, by what each level of holding it counts as (see ss.expressions.HeldFrac.level_weights())
init_exposures What each operation that reads an exposure needs, kept for each run, and the parameters of the operations
init_func_exprs Call each value that is a function of the sim, to find those that give an expression of the model’s states, which are worked out within the step
init_movers Movement between groups: aging, and the declared transfers
init_post Set the initial conditions
init_program Flatten the flows into arrays for the kernels: see ss.kernels
init_register The movement register as arrays for the kernels (with no events, if there is none): see ss.kernels.Register
init_shifts The deliveries that the kernels take in a whole run (see ss.Event.tabulated), as arrays: see ss.kernels.Shifts
init_syncs Synchronized flows: a transition of another module triggered by a transition of this one
init_tape Put the expressions that are worked out once a step for every group alike (the branch probabilities, and the rates
init_triggers Triggers (ss.on()): on states and strata, the compartments where they hold vanish; on time or counts, they are applied at each step
inline_modifiers Make each modifier that multiplies a rate while a comparison of this module’s counts holds (who=I.n >= 1000) part of the rate, as 1 + (multiply - 1)*(I.n >= 1000)
kernel_reason Why the whole run cannot be taken in one call to the kernels (something in Python needs to see the model between one step and the next), in a few words, or None if it can: see ss.solvers.why_not()
kernels The kernels to take the run (or runs runs) with, compiled or as plain Python, chosen once for a run: see ss.kernels.choose()
make_program The arrays of the kernels’ program (see ss.kernels.Program), with what is set later (by set_contacts() and pack_targets(), and each step) left empty
met_count The number of people in some states met through the contact matrices, by group: as exposure(), on the number (each counted by its weight in a weighted count) rather than the fraction
mod_values What the modifiers are worked out from, beyond their amounts (see par_values()): when they act, on whom, and how; to tell whether the tables of the last run still hold
mother ss.mother(x), which needs agents (see Agents.mother())
move_frac Move a fraction of each state and group (within the sources srcs) along a triggered transition: with p=, that fraction of them; with several destinations, split between them
move_some A one-off move from code (ss.move()): a fraction p of the people in some states (or n of them, exactly where the solver keeps
move_states Move a fraction of the people in each of some states, and each group, to a state: along a transition (see force()), or along none, as a one-off move (ss.vaccinate(S >> V)); with syn (synchronized flows), also returns the moves in this module’s own groups; with y, of those people rather than the engine’s; with given, the number to move from each compartment instead (see move_some())
mover_matrix The rates of a mover from group to group, as a sparse matrix (each group’s people move along one dimension, so to only a few groups)
mover_rates The current rate matrix of each mover, from group to group; with base=True, without the rate of a transfer that is a parameter the kernels take at each step (see par_transfer())
next_generation The next-generation matrix at the disease-free state, F V⁻¹, over the infected compartments of every group
note_counter In a compartmental run, a note when a counter’s levels are not one apart, so people within a wider level are taken to be at its lower edge when it goes up
note_stages In a compartmental run, a dwell time that is not exponential or Erlang is approximated by Erlang stages, which is said in one line;
others_follow Have the other diseases lose (or with added, gain) the people this one lost or gained from code (ss.move() to or from
pack_targets Put where each flow goes into the program; done again whenever a branch probability changes
par_transfer Whether a transfer’s rate is a parameter that varies in time (e.g. aging at a rate given for each year), and nothing else of it does,
par_values What the rates are worked out from, to compare with those of the last step (see settled())
partnership_chance Under the partner-change model (see ss.solvers.Mixing.partnerships()), the chance that a partnership with
pass_syncs After a step, or a move by an intervention: give each module whose transition is triggered by one of this one’s the people its flow moved, as its transition’s flow
plain_seconds About how long the run would take as plain Python, from the size of its program and its rates at the start (see ss.kernels.plain_seconds())
prog_value The value of a parameter in the program: a beta for each route is 1 here (with any modifiers), since it is applied to the exposure through each (see set_contacts())
program_mixing The mixing as the kernels take it: the groups of each place, and the arrays of each term
prop A property of people or a condition, in a rate (see ss.expressions.Prop): its value for each group (for a condition, the fraction of the group it holds for; on states, of the people in the state the flow leaves)
rates The rate of every flow, per unit time and per member of its source compartment (or in total, for an inflow)
ratio_names The results given as expressions, and the standard prevalence if it is kept by group as a ratio (see init_results())
reduce A modified value is a scalar or one value per group; if it differs by state, the row for the state it is used for
refresh_program Set the numbers in the program that hold for this step: the rates that do not depend on the compartments, and the values the others use
remove_people Take a fraction of the people in each of some states and groups (or given, the number from each compartment) out of the model, and the same people out of the other diseases (see others_follow()); returns the number by group
restart Go back to the start of the run, with the current values of the parameters and the seed: see ss.Sim.restart()
restart_movement Put the movement between places, worked out again from new values of its parameters (see ss.geo.Mobility.fitted()), into the program, as a restart with them needs (see ss.Sim.restart()); False if the new values move people between places the old ones did not, so the sim must be built again
round_preserving Round to whole numbers, keeping the total
route_betas For a transmission with a beta for each route (beta=dict(home=…, school=…)), or with a route that has acts: the beta
route_mods Whether modifiers act on a transmission on some of its routes (ss.modify(..., network=))
route_mults The multiplier on the contacts through each term of the mixing, from the modifiers of a transmission on that route: 1 − frac·(1 − multiply), a number or one for each group (of the people who would be infected)
run_all Take every step of the run in one call to the kernels (or to JAX: see ss.gradients), and fill in the results from what comes back
run_args What the kernels need for a whole run, apart from the seed (and the tables, unless tables=False)
run_many Take many runs that differ only in their seed, in calls to the kernels that take all of them, a part of the run at a time
run_parts Take a whole run a part at a time, in calls to the kernels that each take as many steps as fit in part_bytes
saturation The fraction of the transmission of mass action that a network’s edges give as agents: (1 − e^(−b·D))/(b·D), for edges that
set_contacts The contacts through each term of the mixing in the program, times the modifiers of the network’s contacts and of a transmission on a route; by exposure and group, with the beta of each route, if they differ by any of these
set_count Set the number in a state, keeping its split between groups and sub-compartments
settled Whether the program from the last step still holds, so the rates of this one need not be worked out again
shift Move a fraction of the people in each state and group to another group, without changing their state
slot_rates A dwell time as it is (see as_is()), as a conveyor of whole steps, with the rate of leaving each slot that gives the
start_key What the compartments at the start and the branches depend on, or None if that cannot be told: while it is the same, a
start_rates The rates out of compartments at the start that do not depend on them, which a stiff ODE takes many substeps for, each as an array
state_counts The number of people in each state (rows) and group (columns)
stay_comp The compartment of a state for people who stay in it with no exit of their own
stays For each transition out of a state with a minimum stay (min_stay=): the first slot of a conveyor it acts on
step Advance the compartments by one timestep
step_known The step in the sim’s unit, or None if it isn’t known yet (laid out before the module is in a sim, for its equations: see ss.display.flow_terms())
step_rates The rates of the step, worked out again if the interventions have changed them since it started (see settled()), and the program, the first time
step_tables For a step in the kernels: the tables and row to take its values from, or, with these set in the program already, no tables, and a row of -1 if they are as in the last step
step_transmit Move those a declared disease’s own transmit() gives for each of its transmissions, at the start of the step (see ss.Disease.transmit()): from its source states in proportion, in each group, counted in its flow
step_triggers The transitions moved by an event of this module (when= one of its transitions), at the end of each step: the fraction of each
store_parts The results of a whole run, from its compartments and flows at each time point, taken in one part or a part at a time;
store_replayed The results of the deliveries of a run taken in JAX, worked out again from the compartments at each time point they happened at (exact, since the run is an ODE)
store_run Store a result of a whole run: its total at each time point, and its values by group if it keeps them; returns the totals
substeps The number of substeps to take in each timestep (0 to let the solver choose)
sweep_triggers At each step: move the people a trigger holds for who are still in its source (who arrived by aging, a transfer, or another disease’s move, or for whom a condition on time or counts has come to hold)
sync_maps For a synchronized flow: the map between groups that moves the other module’s coordinate (its dimension in the
sync_rec A synchronized flow by this module’s groups (the last axis), as the other module’s
synced The map of a flow along a transition that other modules’ transitions are triggered by: its own, then moving their coordinates
syncs_of The synchronized flows of a transition (to a destination), with their maps worked out
table_years The year of each row of the tables, one a step, for a value that varies in time: the middle of the step, or its start for a step function, which is held from there, and for Euler’s method, which reads everything there
tables The parts of the program that can change over time, at each step (or as a single entry, if nothing varies)
take Some of the people in a compartment: a fraction, or a draw where the solver keeps whole numbers
take_flows After a step: the flow along each transition and mover over it, by group, and the people at its end
tape_values The value of each expression on the tape, worked out once a step (or again, whenever the values it uses can have changed, as the engine’s other cached values are)
targets The group that each group’s people move to when their level in some dimensions is changed ({dimension index: level})
trait_mean Whether an attribute (ss.attr) has a compartmental form: a trait drawn from a distribution, with no modifier, which a compartmental run takes at its mean (see attr())
transmitted The number infected in the step in each group by a transmission, as the solver works it out at the start of the step: the
trigger_frac Where a trigger holds, as the fraction of each state (rows) and group (columns) it selects
trigger_mask The groups of a state where a trigger on states and strata holds (1) or not (0); 0 for one on time or counts, which is applied at each step instead: see sweep_triggers()
update_targets Work out where each flow’s arrivals go; done once per step, since branch probabilities can change (and only worked out again if they have)
varying_dwell A dwell time whose distribution has parameters with a value for each group (ss.by)
weight What each group’s people in a state count as in a weighted count: their weight, times their infectiousness for n_infectious (as in exposure())
whole_outcomes The outcomes drawn all at once, by name: with no delay or stay, an outcome’s only draws are binomials of the flows it comes from, one call in the same order as a step at a time; or None if any has more than that
whole_steps A time as a number of whole steps (up, or to the nearest with nearest=True; at least lowest), with a note if it is not one
add_per_births
solvers.compartmental.Compartmental.add_per_births()

After a step: the children of those who went through a transition with births driven by its flow (ss.birth(when=)), n for each, in the youngest groups of their parents’ place

aging_rates
solvers.compartmental.Compartmental.aging_rates(strat)

The rate per year at which people age out of each age group (but the last): the density of people in the year below its upper edge, over the number in the group

With a given split (ages uniform within each group), this is one over its width; with a named population, or the world’s as a guess, it is from that pyramid, as agents age (so a group followed by a smaller one does not empty too fast).

apart_fracs
solvers.compartmental.Compartmental.apart_fracs(name, tracks)

For several non-exponential dwell times out of a state, each for other people (who=): the fraction of each group that enters each one’s track, 1 for the one it has (the first, if none)

arrive
solvers.compartmental.Compartmental.arrive(name, amount, y, before=False)

Add an amount to a state, split between its tracks; with before=True, as if they arrived a step before (people infectious at the start, who have been so for the first step, as agents date them), so one slot along a conveyor

as_is
solvers.compartmental.Compartmental.as_is(dwell)

Whether a dwell time runs as it is, as a conveyor of whole steps (see slot_rates()), rather than as Erlang stages: under solver=ss.solvers.ode(dwells=‘exact’), any whose distribution function is known; under every compartmental solver, one that takes only whole numbers of steps (an ss.choice of them, e.g. days with daily steps), which is then exact, as it is for agents

at_home
solvers.compartmental.Compartmental.at_home(frac)

Whether a time fraction between places (a sparse array) keeps everyone at home, as np.allclose(frac, np.eye(P)) would say, without forming either

at_middle
solvers.compartmental.Compartmental.at_middle()

Take values that vary smoothly in time at the middle of the step, which runs from time point ti to the next, as tables() does, so that a stepped run takes the same values as a whole one

attr
solvers.compartmental.Compartmental.attr(a)

An attribute in a compartmental run: a trait is the mean of its distribution, as a parameter that is a distribution is (see trait_mean())

backfill_burnin
solvers.compartmental.Compartmental.backfill_burnin(sp)

A module’s people who start part way through (ss.Pregnancy(burnin=True): see its burnin_plan()): each group’s fraction of the first state (sp.frac()) is moved to the target, spread evenly over its compartments (stages, or the slots of a fixed time), as if they entered uniformly over the steps before the start (the module’s fraction takes off those who would have left on the way)

binomial_substeps
solvers.compartmental.Compartmental.binomial_substeps()

The substeps the chain-binomial solver takes in each step, from the fastest total rate out of a compartment of people at the start (see substeps())

People who arrive in a compartment within a substep leave it from the next, so a compartment holds about x/2 too many, with x its total rate out times the substep, and R is that much too high. So x is kept to binomial_bias (5%), which bounds the bias in each compartment to about 2.5%; and near the epidemic threshold, where the prevalence moves by the bias in R over R0 - 1 (an SIS’s endemic prevalence is 1 - 1/R0), to 0.1 × |R0 - 1|, for a bias of about 5% (a model of TB resistance, +12% at 3 substeps a month, is +3% at 12; an SIS with R0 = 1.05 gave 0.083 for 0.048 at whole steps). A fixed delay doesn’t count, since its people don’t leave at a rate: a model whose only exits are fixed delays takes whole steps, which keeps its final size but lowers its peak (by about 15% for an SIR at a fifth of the delay a step); ss.solvers.binomial(substeps=3) gives about 5%, for about twice the time.

birth_map
solvers.compartmental.Compartmental.birth_map(tr)

Where the children of the people in each group are born (rows to columns): the youngest group of each dimension, by the split of the others, in their parents’ place

births_of
solvers.compartmental.Compartmental.births_of(tr)

The engine and inflow of each declared module with an ss.birth(when=) of the same transition as tr (this module’s own first)

branch_where
solvers.compartmental.Compartmental.branch_where(tr)

Whether a transition is a branch out of each of its sources whose who= is on states and strata, so closes it at entry (see branch_mult()) rather than changing its rate

build
solvers.compartmental.Compartmental.build()

Lay out the compartments (after init_dims()): the dwell times, the protection between strains, and the compartments and flows; raises a CapabilityError for what has no compartmental form yet

build_layout
solvers.compartmental.Compartmental.build_layout()

Expand the states into compartments and the transitions into flows

call_uids
solvers.compartmental.Compartmental.call_uids(func, p=None)

A function that takes uids, which a compartmental run does not have (see Agents.call_uids())

certain
solvers.compartmental.Compartmental.certain()

The name of a transition with an infinite rate (a probability of 1 over the period) at the start, which the kernels take as everyone moving at once (see ss.kernels.certain()), and which JAX and the exact solver by place do not; or None

chain_start
solvers.compartmental.Compartmental.chain_start(group)

The compartment where the people of a group of linked states (see ss.graph.Graph.linked()) are with no immunity, for next_generation(): the first state, if it is in the group, else the one state that the group is infected from (e.g. S_H2 of a second host species), or None if it has none

changes
solvers.compartmental.Compartmental.changes(y, new)

The rate of change of each compartment from new infections (new=True: arrivals only), or from every other flow; see next_generation()

changing_steps
solvers.compartmental.Compartmental.changing_steps(start, stop)

The steps on which the modifiers of this module change, if all they do is switch on and off at a date, so the tables need working out only on those steps; or None if they could change on any step

check_noise
solvers.compartmental.Compartmental.check_noise()

Refuse noise on a rate (ss.Transition(noise=)) where it isn’t drawn: it is drawn by the chain binomial, once a substep for each flow, and by tau-leaping once a leap, so a transition must be one flow; the ODE leaves it out (see init_program()), or with approximations=“error” refuses it

clock
solvers.compartmental.Compartmental.clock(clock)

A clock, which a compartmental run does not keep (see Agents.clock())

collect
solvers.compartmental.Compartmental.collect(
    stocks,
    flows,
    expected=False,
    grouped=None,
    seeds=None,
)

The results of many runs, from the number in each state and the flow along each transition and mover

Parameters
Name Type Description Default
stocks array runs by steps by states by groups (or by one group, the total) required
flows array runs by steps by transitions and movers by groups (or one) required
expected bool whether outcomes of whole events are their expected number, rather than drawn (as a particle filter needs) False
grouped tuple from run_many(): some states and flows by group instead, as runs by rows by states (or flows) by groups, which states and flows they are, and the time point of each row (or None for every one) None
seeds list the seed of each run, for the draws of the outcomes (see derived_outcomes()) None

Returns the results as run_many() describes them.

constant_transfer
solvers.compartmental.Compartmental.constant_transfer(tf)

Whether a transfer’s rate holds for the whole run, so its mover can be set once before it (see run_args()): a rate or duration of plain values, with no modifiers

count_deaths
solvers.compartmental.Compartmental.count_deaths(flows)

For a split between states and ss.dead (with no ss.stay): those who died are its flow less those who went to a state, so the two agree in each run; flows are by flow along the axis before the last (the groups)

count_stocks
solvers.compartmental.Compartmental.count_stocks()

As ss.solvers.Engine.count_stocks(), for every state at once

count_weighted
solvers.compartmental.Compartmental.count_weighted(states, expr)

A weighted count ((ss.by(biting=w)*I).n, A.n_infectious): the people in each state and group counted by the group’s weight (and infectiousness), in the same place

current
solvers.compartmental.Compartmental.current(solver=None)

Whether the layout holds for the sim’s groups now, and for its solver (or the one given): one made to choose the solver is used by the run unless the groups changed since (see ss.solvers.make_engine())

define
solvers.compartmental.Compartmental.define()

Replace the declared states on the module with their run-time form

delay_steps
solvers.compartmental.Compartmental.delay_steps(tr)

The length of a fixed delay (ss.constant), plus any minimum stay before it, in whole steps: agents leave at the start of the step nearest its end

derived
solvers.compartmental.Compartmental.derived(
    n,
    new,
    outcomes=True,
    expected=False,
    seeds=None,
)

The results that are worked out from the number in each state and the flow along each transition

Parameters
Name Type Description Default
n dict the number in each state at each step: a series, or an array whose last dimension is the steps required
new dict the same for the flow along each transition required
outcomes bool whether to work out the outcomes True
expected bool see derived_outcomes() False
seeds list see derived_outcomes() None

Returns a dict of the outcomes and the results given as expressions. This is what record_events() does on each step, for every step at once.

derived_outcomes
solvers.compartmental.Compartmental.derived_outcomes(
    new,
    expected=False,
    names=None,
    seeds=None,
)

What step_outcomes() does on each step, for every step at once (with expected, outcomes of whole events are their expected number, rather than drawn); only the outcomes in names, if given (with those they are worked out from); for many runs (the first dimension of the flows), each drawn from the random numbers of its seed in seeds

det_flow
solvers.compartmental.Compartmental.det_flow(flow)

Whether a flow is of a state that is not people, so is never drawn as whole events

drawn_outcomes
solvers.compartmental.Compartmental.drawn_outcomes(todo, new)

The outcomes of derived_outcomes() when they are drawn: a step at a time, by Engine.report_outcome(), with the runs and groups (all but the last dimension of the flows) side by side

eval
solvers.compartmental.Compartmental.eval(expr)

An expression’s value: from the tape, if it is on it (see init_tape()), else worked out here

event_frac
solvers.compartmental.Compartmental.event_frac(name, to=None)

The people who went through a transition in the last step (or one of its branches, to), as a fraction of the state they are now in

exit_rate
solvers.compartmental.Compartmental.exit_rate(state)

The rate at which people leave a state other than by infection (one over their mean time in it), as a mean over groups

exposure
solvers.compartmental.Compartmental.exposure(state)

Exposure to people in a state through the sim’s mixing: the chance that a contact is with someone in that state

exposure_comps
solvers.compartmental.Compartmental.exposure_comps(name)

The set of an exposure in the program: of a state, by its name, or of a count that the contact matrices act on, which is its key (see flatten_rates())

exposure_trans
solvers.compartmental.Compartmental.exposure_trans(state, mask)

The infectiousness of an exposure in the program, by group: of a state, with its modifiers and strain (mask); 1 for a count (whose state is None)

expr_key
solvers.compartmental.Compartmental.expr_key(out)

What a function’s expression is made of, to tell when it changes: its text, and the exact value of each number in it (None if it is not an expression)

find_start_deps
solvers.compartmental.Compartmental.find_start_deps()

The parameters read by the start and the branches (see start_key()), or False if something else can change them, or doing it has an effect of its own

flatten_rates
solvers.compartmental.Compartmental.flatten_rates()

The operations of the kernels for each rate: what they act on, in order; the operations, and where each flow’s start; the size of stack they need; and the row of consts of each mover’s rate (see init_program())

flow_base
solvers.compartmental.Compartmental.flow_base(flow)

The rate of a flow before its multipliers: the only part that can depend on the number in each compartment

flow_mult
solvers.compartmental.Compartmental.flow_mult(flow)

The multipliers on a flow’s rate, which hold for the whole step

flows_of
solvers.compartmental.Compartmental.flows_of(flows)

The flows of each engine its program holds, as joint states’: this one’s

force
solvers.compartmental.Compartmental.force(frac, tr, dst, srcs=None, y=None)

Move a fraction of the people in each state a transition leaves from (or in srcs), and each group, to a state, counted in the transition’s flow if there is one (as when a treatment cures); a synchronized flow moves other modules’ coordinates too; with y, of those people (by compartment and group) rather than the engine’s

gives_back
solvers.compartmental.Compartmental.gives_back(src, dst)

In a branching process, whether a move from one state to another is from the infected side back into the uninfected side, which it takes people out of the model by instead

group_needs
solvers.compartmental.Compartmental.group_needs()

The states and flows (by position) that are needed by group: those of the results that keep their values by group, and what they are worked out from

held
solvers.compartmental.Compartmental.held(raw)

Whether a value that varies in time is a step function (so is held for each step)

held_frac
solvers.compartmental.Compartmental.held_frac(expr)

The fraction holding a product (itn.held_frac): the fraction of the people in the same place who hold it, by what each level of holding it counts as (see ss.expressions.HeldFrac.level_weights())

init_exposures
solvers.compartmental.Compartmental.init_exposures(rates)

What each operation that reads an exposure needs, kept for each run, and the parameters of the operations

init_func_exprs
solvers.compartmental.Compartmental.init_func_exprs()

Call each value that is a function of the sim, to find those that give an expression of the model’s states, which are worked out within the step

init_movers
solvers.compartmental.Compartmental.init_movers()

Movement between groups: aging, and the declared transfers

init_post
solvers.compartmental.Compartmental.init_post()

Set the initial conditions

init_program
solvers.compartmental.Compartmental.init_program()

Flatten the flows into arrays for the kernels: see ss.kernels

A value that is a function of the sim is called once a step (see refresh_program()), and held within it, unless it gives an expression of the model’s states (I.n), which is flattened in its place (and again whenever the expression changes). A beta for each route, and a modifier of a network’s contacts for some people only (who=), make the contacts through each term differ by exposure and group (see set_contacts()).

init_register
solvers.compartmental.Compartmental.init_register()

The movement register as arrays for the kernels (with no events, if there is none): see ss.kernels.Register

init_shifts
solvers.compartmental.Compartmental.init_shifts()

The deliveries that the kernels take in a whole run (see ss.Event.tabulated), as arrays: see ss.kernels.Shifts

init_syncs
solvers.compartmental.Compartmental.init_syncs()

Synchronized flows: a transition of another module triggered by a transition of this one (ss.on(a.tr), or a branch, ss.on(a.tr.to(X))). The two modules are tracked jointly (ss.solvers.JointStates), so this module’s flow also carries the other’s coordinate from the source of its transition to its destination, in the same flow: exact. Each has a row of its own after the transitions, which the flow credits, and which the other module records as its transition’s flow (see pass_syncs())

init_tape
solvers.compartmental.Compartmental.init_tape()

Put the expressions that are worked out once a step for every group alike (the branch probabilities, and the rates of the flows other than infection) on a tape that the kernels work out in one call (see ss.kernels.evaluate())

Each part is on the tape once, however many expressions it is in: the same parameter, the same number, a count of the same states, or the same operation on the same parts. This matters for an imported model, whose expressions can share large parts (an Atomica model’s parameter functions, which it writes out where they are used). An expression with a part the tape does not have (exposure, a condition, another disease’s states, a function of the sim, …) is left to ss.expressions.evaluate().

init_triggers
solvers.compartmental.Compartmental.init_triggers()

Triggers (ss.on()): on states and strata, the compartments where they hold vanish; on time or counts, they are applied at each step

inline_modifiers
solvers.compartmental.Compartmental.inline_modifiers()

Make each modifier that multiplies a rate while a comparison of this module’s counts holds (who=I.n >= 1000) part of the rate, as 1 + (multiply - 1)*(I.n >= 1000)

The kernels work this out as they do any rate, so the run needs no Python between its steps. The ODE reads the comparison at each stage of a step, not once a step. Anything else about the modifier leaves it to be applied each step.

kernel_reason
solvers.compartmental.Compartmental.kernel_reason()

Why the whole run cannot be taken in one call to the kernels (something in Python needs to see the model between one step and the next), in a few words, or None if it can: see ss.solvers.why_not()

kernels
solvers.compartmental.Compartmental.kernels(runs=1)

The kernels to take the run (or runs runs) with, compiled or as plain Python, chosen once for a run: see ss.kernels.choose()

make_program
solvers.compartmental.Compartmental.make_program(rates, mix)

The arrays of the kernels’ program (see ss.kernels.Program), with what is set later (by set_contacts() and pack_targets(), and each step) left empty

met_count
solvers.compartmental.Compartmental.met_count(states, expr)

The number of people in some states met through the contact matrices, by group: as exposure(), on the number (each counted by its weight in a weighted count) rather than the fraction

mod_values
solvers.compartmental.Compartmental.mod_values()

What the modifiers are worked out from, beyond their amounts (see par_values()): when they act, on whom, and how; to tell whether the tables of the last run still hold

mother
solvers.compartmental.Compartmental.mother(expr)

ss.mother(x), which needs agents (see Agents.mother())

move_frac
solvers.compartmental.Compartmental.move_frac(tr, frac, srcs)

Move a fraction of each state and group (within the sources srcs) along a triggered transition: with p=, that fraction of them; with several destinations, split between them

move_some
solvers.compartmental.Compartmental.move_some(
    srcs,
    dst,
    p=None,
    n=None,
    where=None,
    outside=None,
)

A one-off move from code (ss.move()): a fraction p of the people in some states (or n of them, exactly where the solver keeps whole people; of those for whom where holds) to a state, or to and from outside the model (dst or srcs empty, and for people, outside: ‘dead’ and ‘outside’, or ‘unborn’ and ‘outside’), which the other diseases follow (see others_follow()); returns the number moved

move_states
solvers.compartmental.Compartmental.move_states(
    frac,
    srcs,
    dst,
    syn=None,
    y=None,
    move=None,
    given=None,
)

Move a fraction of the people in each of some states, and each group, to a state: along a transition (see force()), or along none, as a one-off move (ss.vaccinate(S >> V)); with syn (synchronized flows), also returns the moves in this module’s own groups; with y, of those people rather than the engine’s; with given, the number to move from each compartment instead (see move_some())

mover_matrix
solvers.compartmental.Compartmental.mover_matrix(src, dst, rates)

The rates of a mover from group to group, as a sparse matrix (each group’s people move along one dimension, so to only a few groups)

Moving into a group with no level of a dimension is moving to its first level, so people outside a dimension’s who= do not move along it.

mover_rates
solvers.compartmental.Compartmental.mover_rates(base=False)

The current rate matrix of each mover, from group to group; with base=True, without the rate of a transfer that is a parameter the kernels take at each step (see par_transfer())

next_generation
solvers.compartmental.Compartmental.next_generation(start=False, y=None)

The next-generation matrix at the disease-free state, F V⁻¹, over the infected compartments of every group

The infected compartments are those of the states people are infected into or infect from, of any count (such as a reservoir, or infectious mosquitoes) that the rate of an infection uses, and of the counts that infected people’s numbers move a count into (mosquitoes biting them). A new infection is a flow from any other compartment into one of these. At the disease-free state, nobody is infected (so the infected at the start are not counted), and everyone else is in the first state, or in the state their own chain of states starts from if no transition links it to the first (e.g. S_H2 of a second host species; see chain_start()), so R0 is in a population with no immunity; with start=True, the people not infected are as they start, for the reproduction number at the start. Each group keeps its size, except that the people filled by a constant inflow (births of a number a day) and the counts filled by any inflow (mosquitoes not infected) are at their equilibrium, from the rates at the disease-free state. Given the compartments y (one row per compartment, one column per group), the matrix is instead at that state as it is, for the reproduction number at that time (see ss.Disease.Rt()). The matrices are worked out by perturbing each infected compartment in turn. Returns None if nothing moves people into an infected state. See ss.Disease.R0().

note_counter
solvers.compartmental.Compartmental.note_counter(strat, what)

In a compartmental run, a note when a counter’s levels are not one apart, so people within a wider level are taken to be at its lower edge when it goes up

note_stages
solvers.compartmental.Compartmental.note_stages(name, dw, held=False)

In a compartmental run, a dwell time that is not exponential or Erlang is approximated by Erlang stages, which is said in one line; for one that may run as it is (see as_is()), only once the layout has it as stages after all (held=True)

others_follow
solvers.compartmental.Compartmental.others_follow(change, added=False)

Have the other diseases lose (or with added, gain) the people this one lost or gained from code (ss.move() to or from outside the model), by group, so that every disease has the same people. Diseases tracked jointly with this one (see ss.solvers.JointStates) have them already. A disease run apart loses them from its states in proportion, in each group, as it has them, which is exact on average: it runs apart since its states do not depend on this one’s, so within a group, which of its states someone is in does not depend on which of this one’s they are in. People added are in its first state, as at birth.

pack_targets
solvers.compartmental.Compartmental.pack_targets()

Put where each flow goes into the program; done again whenever a branch probability changes

par_transfer
solvers.compartmental.Compartmental.par_transfer(tf)

Whether a transfer’s rate is a parameter that varies in time (e.g. aging at a rate given for each year), and nothing else of it does, so that a whole run takes it from the program’s values at each step, as it does a flow’s (see ss.kernels.set_movers())

par_values
solvers.compartmental.Compartmental.par_values()

What the rates are worked out from, to compare with those of the last step (see settled())

partnership_chance
solvers.compartmental.Compartmental.partnership_chance(
    val,
    net,
    term,
    flow,
    state,
)

Under the partner-change model (see ss.solvers.Mixing.partnerships()), the chance that a partnership with someone in a source state, formed now, transmits to the people in each group before it stops being able to: H/(H + k) with k = 1/D̄ + c, for partnerships that end at a constant rate, or H/(H + c)·(1 − E[exp(−(H + c)·T)]) over their duration T otherwise; H is the hazard per unit time in the partnership (acts per unit time times the hazard per act in the direction from the partner’s side, or the beta itself on a network without acts), and c the rate at which the partner leaves the source state or the person leaves the state they are infected from

pass_syncs
solvers.compartmental.Compartmental.pass_syncs(flows)

After a step, or a move by an intervention: give each module whose transition is triggered by one of this one’s the people its flow moved, as its transition’s flow

plain_seconds
solvers.compartmental.Compartmental.plain_seconds()

About how long the run would take as plain Python, from the size of its program and its rates at the start (see ss.kernels.plain_seconds())

prog_value
solvers.compartmental.Compartmental.prog_value(par)

The value of a parameter in the program: a beta for each route is 1 here (with any modifiers), since it is applied to the exposure through each (see set_contacts())

program_mixing
solvers.compartmental.Compartmental.program_mixing()

The mixing as the kernels take it: the groups of each place, and the arrays of each term

prop
solvers.compartmental.Compartmental.prop(cond)

A property of people or a condition, in a rate (see ss.expressions.Prop): its value for each group (for a condition, the fraction of the group it holds for; on states, of the people in the state the flow leaves)

rates
solvers.compartmental.Compartmental.rates()

The rate of every flow, per unit time and per member of its source compartment (or in total, for an inflow)

ratio_names
solvers.compartmental.Compartmental.ratio_names()

The results given as expressions, and the standard prevalence if it is kept by group as a ratio (see init_results())

reduce
solvers.compartmental.Compartmental.reduce(value, state=None, what=None)

A modified value is a scalar or one value per group; if it differs by state, the row for the state it is used for

refresh_program
solvers.compartmental.Compartmental.refresh_program()

Set the numbers in the program that hold for this step: the rates that do not depend on the compartments, and the values the others use

remove_people
solvers.compartmental.Compartmental.remove_people(frac, srcs, given=None)

Take a fraction of the people in each of some states and groups (or given, the number from each compartment) out of the model, and the same people out of the other diseases (see others_follow()); returns the number by group

restart
solvers.compartmental.Compartmental.restart()

Go back to the start of the run, with the current values of the parameters and the seed: see ss.Sim.restart()

restart_movement
solvers.compartmental.Compartmental.restart_movement()

Put the movement between places, worked out again from new values of its parameters (see ss.geo.Mobility.fitted()), into the program, as a restart with them needs (see ss.Sim.restart()); False if the new values move people between places the old ones did not, so the sim must be built again

The program keeps its entries, which the new values fill (one that becomes 0 stays as an entry of 0), so a compiled run and the gradients’ check that the layout is the same both hold.

round_preserving
solvers.compartmental.Compartmental.round_preserving(y)

Round to whole numbers, keeping the total

route_betas
solvers.compartmental.Compartmental.route_betas(flow)

For a transmission with a beta for each route (beta=dict(home=…, school=…)), or with a route that has acts: the beta of each term of the mixing, which exposure() applies (and the beta itself is then 1); None otherwise

route_mods
solvers.compartmental.Compartmental.route_mods(tr)

Whether modifiers act on a transmission on some of its routes (ss.modify(..., network=))

route_mults
solvers.compartmental.Compartmental.route_mults(tr, state)

The multiplier on the contacts through each term of the mixing, from the modifiers of a transmission on that route: 1 − frac·(1 − multiply), a number or one for each group (of the people who would be infected)

run_all
solvers.compartmental.Compartmental.run_all(use_jax=False)

Take every step of the run in one call to the kernels (or to JAX: see ss.gradients), and fill in the results from what comes back

run_args
solvers.compartmental.Compartmental.run_args(tables=True)

What the kernels need for a whole run, apart from the seed (and the tables, unless tables=False)

run_many
solvers.compartmental.Compartmental.run_many(seeds, start=None)

Take many runs that differ only in their seed, in calls to the kernels that take all of them, a part of the run at a time

With start, the runs are taken from a later time point, each from compartments of its own, with what came before given (e.g. a run drawn by a particle filter, to project from: see ss.fitting.ParticleFilter); the results by group are then not kept, since what came before is given as totals.

Parameters
Name Type Description Default
seeds list the seed of each run, as would be given to the sim as rand_seed required
start dict ti, the time point to take the runs from; y, the compartments of each run there (runs by compartments by groups); and stocks and flows, by the module’s name, how many were in each state and the flow along each transition and mover in each run at each time point before it (runs by time points by states, or by flows) None

Returns each result that is a single series, as runs by steps, and (as out.groups) the values by group of the results that keep them, as runs by rows by groups: a row for each time point, or for every few steps if that would take more than max_bytes of memory (with the time point of each row as out.group_ti; see ss.solvers.group_rows()).

run_parts
solvers.compartmental.Compartmental.run_parts(part_bytes=50000000.0)

Take a whole run a part at a time, in calls to the kernels that each take as many steps as fit in part_bytes

Yields the time point each part starts at, and its compartments and flows at each of its time points (as ss.kernels.run() returns them). The deliveries’ results are stored as it goes. With self.keep_at, a part also ends at that time point, and the compartments there are kept, as self.kept_y (see ss.fitting.run_kept()).

saturation
solvers.compartmental.Compartmental.saturation(e, term, beta=1.0)

The fraction of the transmission of mass action that a network’s edges give as agents: (1 − e^(−b·D))/(b·D), for edges that transmit at rate b over a step D (the longer of the network’s and the disease’s), by group (of the people who would be infected); 1 for any other term of the mixing

As agents, an edge transmits at most once to its susceptible end in a step, with every factor of its hazard in the exponent (see ss.Network.transmit()), so the force of infection through K contacts per unit time is K·(1 − e^(−b·D))/D, not K·b (see ss.solvers.Mixing.edge_dur()). Each flow by contact has its own exposures here (see flatten_rates()), so b is that flow’s own: the coefficient of the exposure’s state in its rate (with a beta for each route, that route’s, given as beta), times the susceptibility of each group, its modifiers, and the mean infectiousness of the state. A flow from several source states takes the factor of each, not that of their mean. It is worked out each step, so a beta that varies in time is followed.

Parameters
Name Type Description Default
e int the exposure in the program required
term obj the term of the mixing required
beta float / array the beta of the term’s route, already in the contacts (1 if the beta is in the rate) 1.0
set_contacts
solvers.compartmental.Compartmental.set_contacts()

The contacts through each term of the mixing in the program, times the modifiers of the network’s contacts and of a transmission on a route; by exposure and group, with the beta of each route, if they differ by any of these

set_count
solvers.compartmental.Compartmental.set_count(state, value)

Set the number in a state, keeping its split between groups and sub-compartments

settled
solvers.compartmental.Compartmental.settled()

Whether the program from the last step still holds, so the rates of this one need not be worked out again

A module with a step of its own stops a run being taken whole, but usually changes nothing the rates depend on. So, if nothing else needs Python between the steps (kernel_reason()), the only thing that can change them is a parameter set by that module, which is looked for at each step, as is the amount of a modifier. Values that vary in time then come from the tables of a whole run. A modifier added during the run is seen at the step it is added, and from then on, as a modifier may do anything, each step works out its own values.

shift
solvers.compartmental.Compartmental.shift(frac, changes)

Move a fraction of the people in each state and group to another group, without changing their state

Parameters
Name Type Description Default
frac arr the fraction to move, states by groups required
changes dict the level to move them to, for each dimension that changes required
slot_rates
solvers.compartmental.Compartmental.slot_rates(tr, dwell, most=5000)

A dwell time as it is (see as_is()), as a conveyor of whole steps, with the rate of leaving each slot that gives the distribution’s own chance of leaving after that many steps (rounded to the nearest), out to the step by which all but 1e-6 have left, whose slot is the last: everyone left there leaves in the next step, as from a fixed delay

Returns the rates of the slots before the last

start_key
solvers.compartmental.Compartmental.start_key()

What the compartments at the start and the branches depend on, or None if that cannot be told: while it is the same, a restart takes them as they were, and a sweep of a value that they do not read (e.g. a rate) need not work them out again

start_rates
solvers.compartmental.Compartmental.start_rates()

The rates out of compartments at the start that do not depend on them, which a stiff ODE takes many substeps for, each as an array

state_counts
solvers.compartmental.Compartmental.state_counts()

The number of people in each state (rows) and group (columns)

stay_comp
solvers.compartmental.Compartmental.stay_comp(name)

The compartment of a state for people who stay in it with no exit of their own

stays
solvers.compartmental.Compartmental.stays(
    name,
    exits,
    competing,
    staged,
    branches,
)

For each transition out of a state with a minimum stay (min_stay=): the first slot of a conveyor it acts on

A person in slot j has been in the state j whole steps, and agents count a stay as whole steps too (see Agents.stayed()). A dwell time with a minimum stay of its own starts after it, so its stages come after the conveyor; a fixed delay with one is a longer conveyor (see delay_steps()). Another exit’s dwell time runs from entry, as for agents: as it is, along the conveyor (see as_is()), or with its stages in each slot.

step
solvers.compartmental.Compartmental.step()

Advance the compartments by one timestep

step_known
solvers.compartmental.Compartmental.step_known()

The step in the sim’s unit, or None if it isn’t known yet (laid out before the module is in a sim, for its equations: see ss.display.flow_terms())

step_rates
solvers.compartmental.Compartmental.step_rates()

The rates of the step, worked out again if the interventions have changed them since it started (see settled()), and the program, the first time

step_tables
solvers.compartmental.Compartmental.step_tables()

For a step in the kernels: the tables and row to take its values from, or, with these set in the program already, no tables, and a row of -1 if they are as in the last step

step_transmit
solvers.compartmental.Compartmental.step_transmit()

Move those a declared disease’s own transmit() gives for each of its transmissions, at the start of the step (see ss.Disease.transmit()): from its source states in proportion, in each group, counted in its flow

step_triggers
solvers.compartmental.Compartmental.step_triggers()

The transitions moved by an event of this module (when= one of its transitions), at the end of each step: the fraction of each source state and group the step’s event happened to moves then, as a delivery’s people do (triggers on conditions are passed straight through instead: see update_targets() and sweep_triggers())

store_parts
solvers.compartmental.Compartmental.store_parts(parts)

The results of a whole run, from its compartments and flows at each time point, taken in one part or a part at a time; the results by group are kept at each time point, or every few steps (see ss.solvers.group_rows())

Parameters
Name Type Description Default
parts iterable the time point each part starts at, and the compartments and flows at each of its time points (see run_parts()) required
store_replayed
solvers.compartmental.Compartmental.store_replayed(stocks)

The results of the deliveries of a run taken in JAX, worked out again from the compartments at each time point they happened at (exact, since the run is an ODE)

store_run
solvers.compartmental.Compartmental.store_run(key, total, by_group=None)

Store a result of a whole run: its total at each time point, and its values by group if it keeps them; returns the totals

substeps
solvers.compartmental.Compartmental.substeps()

The number of substeps to take in each timestep (0 to let the solver choose)

The chain-binomial solver takes enough substeps that its step bias is small, as far as the rates are known at the start (at most max_binomial): see binomial_substeps(). Each substep is off the ODE by an amount of order rate × dt (an acute stage of 1.7 months at monthly steps can take everyone infected from 9% to 51%). It moves people through as many stages of a dwell time as they pass in a substep (see ss.kernels.draw_chain()), so it is the dwell’s mean that counts, not its stages; a fixed delay is a conveyor of whole steps, so its length doesn’t count. ss.solvers.binomial(substeps=1) takes whole steps, as most chain-binomial models (and frameworks’ discrete-time models) do.

sweep_triggers
solvers.compartmental.Compartmental.sweep_triggers()

At each step: move the people a trigger holds for who are still in its source (who arrived by aging, a transfer, or another disease’s move, or for whom a condition on time or counts has come to hold)

sync_maps
solvers.compartmental.Compartmental.sync_maps(sy)

For a synchronized flow: the map between groups that moves the other module’s coordinate (its dimension in the joint) from the levels of its transition’s source to those of its destination (entry, split by its branches), the fraction of each group that it moves, and where the flow is recorded in the other module’s groups

sync_rec
solvers.compartmental.Compartmental.sync_rec(sy, val)

A synchronized flow by this module’s groups (the last axis), as the other module’s

synced
solvers.compartmental.Compartmental.synced(dim_map, syn)

The map of a flow along a transition that other modules’ transitions are triggered by: its own, then moving their coordinates

syncs_of
solvers.compartmental.Compartmental.syncs_of(tr, dst)

The synchronized flows of a transition (to a destination), with their maps worked out

table_years
solvers.compartmental.Compartmental.table_years(raw)

The year of each row of the tables, one a step, for a value that varies in time: the middle of the step, or its start for a step function, which is held from there, and for Euler’s method, which reads everything there

tables
solvers.compartmental.Compartmental.tables(start=0, stop=None)

The parts of the program that can change over time, at each step (or as a single entry, if nothing varies)

A value that varies in time is worked out for every step at once. Modifiers that depend only on time are applied to the steps between the times they change, each span worked out at once in the same way; only a modifier that could change at any step (e.g. one that follows a smooth time series) is worked out step by step. The tables of a whole run are kept for as long as everything they are worked out from is the same, so a sim that is run again, with the same values, does not work them out again.

Parameters
Name Type Description Default
start int the first step to give the tables for (for a run taken a part at a time: see run_parts()) 0
stop int the step after the last (default: to the end) None
take
solvers.compartmental.Compartmental.take(y, frac)

Some of the people in a compartment: a fraction, or a draw where the solver keeps whole numbers

take_flows
solvers.compartmental.Compartmental.take_flows(flows)

After a step: the flow along each transition and mover over it, by group, and the people at its end

tape_values
solvers.compartmental.Compartmental.tape_values()

The value of each expression on the tape, worked out once a step (or again, whenever the values it uses can have changed, as the engine’s other cached values are)

targets
solvers.compartmental.Compartmental.targets(changes)

The group that each group’s people move to when their level in some dimensions is changed ({dimension index: level})

trait_mean
solvers.compartmental.Compartmental.trait_mean(mod, a, sim)

Whether an attribute (ss.attr) has a compartmental form: a trait drawn from a distribution, with no modifier, which a compartmental run takes at its mean (see attr())

transmitted
solvers.compartmental.Compartmental.transmitted(tr)

The number infected in the step in each group by a transmission, as the solver works it out at the start of the step: the people in each of its source compartments times the chance of the flow in the step, 1 − exp(−rate·dt) (the default of a declared disease’s transmit(), see ss.Disease.transmit())

trigger_frac
solvers.compartmental.Compartmental.trigger_frac(tr)

Where a trigger holds, as the fraction of each state (rows) and group (columns) it selects

trigger_mask
solvers.compartmental.Compartmental.trigger_mask(tr, name)

The groups of a state where a trigger on states and strata holds (1) or not (0); 0 for one on time or counts, which is applied at each step instead: see sweep_triggers()

update_targets
solvers.compartmental.Compartmental.update_targets()

Work out where each flow’s arrivals go; done once per step, since branch probabilities can change (and only worked out again if they have)

varying_dwell
solvers.compartmental.Compartmental.varying_dwell(name, tr, raw, dw, to_unit)

A dwell time whose distribution has parameters with a value for each group (ss.by)

Each group gets the Erlang stages that match its own mean and standard deviation (ragged stages); a function as well has no compartmental form. (Agents look the parameters up for each agent, and make one draw: see Agents.varying_dwell().)

weight
solvers.compartmental.Compartmental.weight(expr, state)

What each group’s people in a state count as in a weighted count: their weight, times their infectiousness for n_infectious (as in exposure())

whole_outcomes
solvers.compartmental.Compartmental.whole_outcomes(todo, flows, weights, width)

The outcomes drawn all at once, by name: with no delay or stay, an outcome’s only draws are binomials of the flows it comes from, one call in the same order as a step at a time; or None if any has more than that

whole_steps
solvers.compartmental.Compartmental.whole_steps(
    tr,
    what,
    dur,
    lowest,
    nearest=False,
)

A time as a number of whole steps (up, or to the nearest with nearest=True; at least lowest), with a note if it is not one

Functions

Name Description
synced_event For a transition triggered by an event (ss.on(other.tr), ss.on(other.tr.to(B))): the transition of another

synced_event

solvers.compartmental.synced_event(tr, sim, home)

For a transition triggered by an event (ss.on(other.tr), ss.on(other.tr.to(B))): the transition of another declared module it is, as Bunch(mod, tr, to), which a compartmental run realizes as a synchronized flow (see Compartmental.init_syncs()); None for anything else (an event of its own module, entering or leaving a state, or an event a module records in code)