Skip to main content

solvers.joint_states

solvers.joint_states

Not for the user: diseases whose states are tracked jointly in a compartmental run

It exists since a condition in one disease on a state of another (e.g. coinfection) needs the people counted by both.

Used with: compartments; declared modules

Classes

Name Description
Joint An engine’s compartments by its groups (engine.y), when its disease is tracked jointly with others: a view of the
JointStates Diseases whose states are tracked jointly in a compartmental run, since a condition in one refers to a state of another (e.g. ss.modify(hiv.rel_trans, multiply=3, who=syph.I))

Joint

solvers.joint_states.Joint(joint, idx)

An engine’s compartments by its groups (engine.y), when its disease is tracked jointly with others: a view of the compartments of their program (JointStates.y), so there is one copy of the people. Reading some of them gathers them, and writing them (e.g. an intervention that moves people) changes the program’s, which every engine then sees. A group that the engine keeps empty (see JointStates.init_layout()) reads as nobody, and writing to it changes nothing.

Parameters

Name Type Description Default
joint JointStates the joint states required
idx array where each of the engine’s compartments, in each of its groups, is in the program’s (flattened), or -1 required

JointStates

solvers.joint_states.JointStates(sim, names, reasons=None)

Diseases whose states are tracked jointly in a compartmental run, since a condition in one refers to a state of another (e.g. ss.modify(hiv.rel_trans, multiply=3, who=syph.I))

Each disease in the joint states is a dimension of the sim, named after it, whose levels are its compartments and which applies to the people of the others. Each keeps its own engine, which works out its rates and its results, and sees the people as it has them: by its own compartments, and by groups that include the compartments of the others (with its own dimension at its first level).

They are run by one program: its compartments are the product of the diseases’ compartments of people (and, for a compartment that is not people, such as a reservoir, one for each combination of the others’), and its groups are those of the sim’s other dimensions. Each flow of a disease is a flow of the program for each combination of the others’ compartments, so every rate is worked out from the people as they are at the start of the step (not each disease in turn), and a whole run, many runs, a particle filter, and a run in JAX take joint states as they take one disease. The solvers that draw whole events in steps draw each disease’s in turn, from those rates, so each disease’s moves (e.g. through the stages of a dwell time) are drawn as they would be for it alone. The program’s compartments (y) are the one copy of the people: each engine’s (engine.y) are a view of them (Joint), so a change made in Python (e.g. by an intervention) is seen by all of them at once. The joint states are run as one engine is (see ss.solvers.Compartmental.step() and run_all(), where it is the engine’s owner): the last disease to step takes the step for all of them, and the first to take a whole run takes it for all of them, and gives each its part. Its size is counted before it is made (see ss.solvers.choose.joint_layout()), and kept within ss.options.max_joint; sim.describe() shows it, with the memory a whole run takes.

Parameters

Name Type Description Default
sim ss.Sim the sim required
names list the names of the diseases required
reasons list why they are tracked jointly (see ss.solvers.choose.joint_groups()) None

Attributes

Name Description
lead The disease whose engine moves people in ways that belong to the sim (aging, relocating, a movement register): the first, or the first of those with the most of the states that a movement register names

Methods

Name Description
build The program of the diseases together (see the class docstring), from the program of each
check Each dimension other than the diseases’ own has to apply to every state of people in the joint states, or to
check_short Warn if events of a movement register asked for more people than there were: by the disease that moves people for the sim (see lead)
describe For sim.describe(): the size of the program, the memory a whole run of it takes, and what is assumed
engine_flows Engine k’s flow along each transition and mover from the program’s, as engine_stocks() does
engine_stocks Engine k’s number in each state from the number in each of the program’s compartments: arrays whose last two dimensions are compartments by groups (or by one, the total) to states by the engine’s groups (or one)
flows_of Each engine’s flows over a step, by its groups, from the program’s
init Start the diseases independent of each other: the fraction of people in each compartment of one is the same in every compartment of the others
init_layout Where each engine’s compartments and flows, in each of its groups, are in the program’s
join_register The movement register of the lead engine (see lead) for the program: see ss.kernels.Register
joint The people in an engine (or y, some of them by its compartments of people and groups) as one array over the dimensions of the sim, with the engine’s own compartments as the levels of its dimension
kernels The kernels to take the run (or runs runs) with, compiled or as plain Python, chosen once for a run: see ss.solvers.compartmental.choose_kernels()
local The people in a joint array, by an engine’s compartments of people and groups
no_shifts The deliveries that the kernels take: none, since deliveries are taken in Python when several diseases are declared (see ss.Event.tabulated)
numbers The numbers in the program, from those in each engine’s: each a dict of the arrays of its program (by the
plain_seconds About how long the run would take as plain Python, from the size of the program and the rates of its diseases at the start, as ss.solvers.Compartmental.plain_seconds() works it out for one engine
reset Forget the kernels chosen, before the run starts again
run A whole run of the diseases together, in one call to the kernels (or to JAX): gives each engine its part of the output (as ss.gradients does; see ss.solvers.Compartmental.run_all())
run_args What the kernels need for a whole run of the program, as ss.solvers.Compartmental.run_args() gives it for one engine
run_many Many runs that differ only in their seed, as ss.solvers.Compartmental.run_many() takes them for one engine (start with the program’s compartments, and what came before by each engine’s name): returns, for each engine, its name and its results
set_joint Give an engine the people in a joint array
shrink Drop the arrays the run worked in, for saving
split Engine k’s compartments at the end, at each time point, and its flows over each step, from the program’s (as ss.kernels.run() returns them)
step_tables For a step taken from Python: the program’s tables, from those of each engine, which has worked out its rates for the step (see ss.solvers.Compartmental.step()), as an engine’s step_tables() gives them
tables The program’s tables for some steps (see ss.solvers.Compartmental.tables())
build
solvers.joint_states.JointStates.build(programs=None)

The program of the diseases together (see the class docstring), from the program of each

The layout is worked out here, and again only if an engine’s program is made again (e.g. when a branch probability changes); the numbers, which can change from step to step or run to run, are taken from the engines’ by numbers(), from where each is in an engine’s program (self.pieces). Returns the program.

check
solvers.joint_states.JointStates.check()

Each dimension other than the diseases’ own has to apply to every state of people in the joint states, or to some states of one disease only (e.g. a strain), but not to its first state, where people born to the others start; and the diseases step together, so they have to have the same timestep

check_short
solvers.joint_states.JointStates.check_short(short)

Warn if events of a movement register asked for more people than there were: by the disease that moves people for the sim (see lead)

describe
solvers.joint_states.JointStates.describe()

For sim.describe(): the size of the program, the memory a whole run of it takes, and what is assumed

engine_flows
solvers.joint_states.JointStates.engine_flows(k, flows, by_group=True)

Engine k’s flow along each transition and mover from the program’s, as engine_stocks() does

engine_stocks
solvers.joint_states.JointStates.engine_stocks(k, stocks, by_group=True)

Engine k’s number in each state from the number in each of the program’s compartments: arrays whose last two dimensions are compartments by groups (or by one, the total) to states by the engine’s groups (or one)

flows_of
solvers.joint_states.JointStates.flows_of(flows)

Each engine’s flows over a step, by its groups, from the program’s

init
solvers.joint_states.JointStates.init()

Start the diseases independent of each other: the fraction of people in each compartment of one is the same in every compartment of the others

init_layout
solvers.joint_states.JointStates.init_layout()

Where each engine’s compartments and flows, in each of its groups, are in the program’s

A compartment of people of an engine, in a group (with the engine’s own dimension at its first level), is the program’s compartment for it and the others’ compartments that are the levels of their dimensions in that group, in the program’s group for the levels of the other dimensions. For each engine, idx gives where each of its compartments, in each of its groups, is in the program’s compartments by groups (flattened), or -1 for the groups it keeps empty; fidx does the same for its transitions and movers.

join_register
solvers.joint_states.JointStates.join_register(reg)

The movement register of the lead engine (see lead) for the program: see ss.kernels.Register

joint
solvers.joint_states.JointStates.joint(engine, y=None)

The people in an engine (or y, some of them by its compartments of people and groups) as one array over the dimensions of the sim, with the engine’s own compartments as the levels of its dimension

kernels
solvers.joint_states.JointStates.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.solvers.compartmental.choose_kernels()

local
solvers.joint_states.JointStates.local(joint, engine)

The people in a joint array, by an engine’s compartments of people and groups

no_shifts
solvers.joint_states.JointStates.no_shifts()

The deliveries that the kernels take: none, since deliveries are taken in Python when several diseases are declared (see ss.Event.tabulated)

numbers
solvers.joint_states.JointStates.numbers(Xs, xp=np, keys=None)

The numbers in the program, from those in each engine’s: each a dict of the arrays of its program (by the names of ss.kernels.Program), its tables (fixed, mult, consts, rel_trans; see ss.solvers.Compartmental.tables()), and its compartments (y), as ss.gradients.capture() gives them

Every number is one of an engine’s, so this is a gather, in NumPy or in JAX (where it is differentiated through).

Parameters
Name Type Description Default
Xs list the numbers of each engine required
xp module NumPy, or JAX’s NumPy np
keys list the numbers to give (default: those in the first engine’s) None
plain_seconds
solvers.joint_states.JointStates.plain_seconds()

About how long the run would take as plain Python, from the size of the program and the rates of its diseases at the start, as ss.solvers.Compartmental.plain_seconds() works it out for one engine

reset
solvers.joint_states.JointStates.reset()

Forget the kernels chosen, before the run starts again

run
solvers.joint_states.JointStates.run(use_jax=False)

A whole run of the diseases together, in one call to the kernels (or to JAX): gives each engine its part of the output (as ss.gradients does; see ss.solvers.Compartmental.run_all())

run_args
solvers.joint_states.JointStates.run_args(tables=True)

What the kernels need for a whole run of the program, as ss.solvers.Compartmental.run_args() gives it for one engine

run_many
solvers.joint_states.JointStates.run_many(seeds, start=None)

Many runs that differ only in their seed, as ss.solvers.Compartmental.run_many() takes them for one engine (start with the program’s compartments, and what came before by each engine’s name): returns, for each engine, its name and its results

set_joint
solvers.joint_states.JointStates.set_joint(joint, engine)

Give an engine the people in a joint array

shrink
solvers.joint_states.JointStates.shrink()

Drop the arrays the run worked in, for saving

split
solvers.joint_states.JointStates.split(k, y, stocks, flows, xp=np)

Engine k’s compartments at the end, at each time point, and its flows over each step, from the program’s (as ss.kernels.run() returns them)

step_tables
solvers.joint_states.JointStates.step_tables()

For a step taken from Python: the program’s tables, from those of each engine, which has worked out its rates for the step (see ss.solvers.Compartmental.step()), as an engine’s step_tables() gives them

tables
solvers.joint_states.JointStates.tables(start=0, stop=None)

The program’s tables for some steps (see ss.solvers.Compartmental.tables())