Skip to main content

solvers.mixing

solvers.mixing

Not for the user: who meets whom in a compartmental run: the contact rates between groups that the networks become

It exists so that the networks of a model, usually written as code, can run without agents. A run as agents uses it too, for the contact matrices of mixing pools and the movement between places.

Used with: agents and compartments; declared and coded modules

Classes

Name Description
Mixing Who meets whom in a compartmental run

Mixing

solvers.mixing.Mixing(sim)

Who meets whom in a compartmental run

With no networks, mixing is homogeneous with one contact per unit time, so exposure to a state is the fraction of the population in it. A mixing pool sets the contact rate; mixing pools between age groups give a contact matrix; an individual-level network is approximated by its mean number of contacts, and lasting partnerships by the partner-change model (see partnerships()).

Parameters

Name Type Description Default
sim ss.Sim the sim required

Methods

Name Description
age_cdf The fraction of people younger than each age: from a named population (or, for a guessed age split, the world’s), or from the age split, with ages uniform within each 5-year group or age group
age_matrix Aggregate the contact matrix of age-based mixing pools to the model’s age groups
by_place The chance that a contact is infectious, for the residents of each place
carries Whether a beta for a network can be above 0: a probability per act if any direction’s can, and anything that is not a number (e.g. an expression)
check_bands check_reciprocal() for a contact matrix over age bands of its own (contacts, rows as the contacts of a person in each band), with the fraction of people in each from cdf (see age_cdf())
check_ragged Contacts by a dimension need everyone who transmits or is infected to have a level of it
check_reciprocal Say if a contact matrix is not reciprocal for the dimension’s split: the contacts of the people in level i with level j should equal those of j with i, N_i·C_ij = N_j·C_ji;
count_terms The contact matrices that act on a count in a rate (I.n, I.frac: see ss.graph.Graph.met_counts), of the terms given or the
counts Whether a term of the mixing acts on counts as well as fractions: a contact matrix, not homogeneous mixing or partnerships (see count_terms())
dim_matrices A contact matrix for each of one or more of the model’s dimensions: the contacts between two groups are the product of the entries; or one matrix over several dimensions together (ss.contacts(matrix, dims=[...]))
edge_dur How long each edge of a network transmits over before it is drawn again, in units of the sim’s time, for its approximation
events The events of the movement register, on the sim’s timeline: see ss.geo.Mobility.events()
exposure Exposure of each group to an infectious state: contacts per unit time, times the chance that a contact is infectious; or, with
init Turn the sim’s networks into contact rates between groups, for the sim’s solver (or the one given: the ODE, when the mixing is laid out to choose the solver, see ss.solvers.choose.lay_out())
init_movement The movement between places, from the current values of its parameters (again on a restart with new ones: see ss.Sim.restart())
init_pools As agents: the contact matrices of mixing pools from counts in each group, in a model with places (within each
init_space Find the spatial dimension, if there is one, and the movement between its levels
mean The mean of a number of contacts, given as a number or a distribution; one given as a rate (e.g. ss.perday(10)) is per unit of the sim’s time, as a bare number is
note_regrouped Say which contact matrices were given over other age groups than the model’s, once for all of them
partnerships Lasting partnerships (ss.DegreeNet, ss.SexualNet) under the partner-change model: a matrix of the
regroup_ages A contact matrix over age bands of its own, as one over the model’s age groups, weighted by population (adding the
spread The product of the time fraction between places with values by place, or by place and level (block levels in each place): v @ frac if by_columns, else frac @ v
term_exposure Exposure of each group through one term of the mixing (with counts, to the number in the state): see exposure()
within_places Make a contact matrix act within each place
age_cdf
solvers.mixing.Mixing.age_cdf(strat)

The fraction of people younger than each age: from a named population (or, for a guessed age split, the world’s), or from the age split, with ages uniform within each 5-year group or age group

age_matrix
solvers.mixing.Mixing.age_matrix(net)

Aggregate the contact matrix of age-based mixing pools to the model’s age groups

by_place
solvers.mixing.Mixing.by_place(places, infectious, n, n_places)

The chance that a contact is infectious, for the residents of each place

People mix where they are: at home, or, if they commute, in each place in proportion to the time they spend there.

Parameters
Name Type Description Default
places array the place of each entry of the other arrays required
infectious array the (infectiousness-weighted) number in the infectious state required
n array the number of people required
n_places int the number of places required
carries
solvers.mixing.Mixing.carries(beta, unit)

Whether a beta for a network can be above 0: a probability per act if any direction’s can, and anything that is not a number (e.g. an expression)

check_bands
solvers.mixing.Mixing.check_bands(net, bands, contacts, cdf)

check_reciprocal() for a contact matrix over age bands of its own (contacts, rows as the contacts of a person in each band), with the fraction of people in each from cdf (see age_cdf())

check_ragged
solvers.mixing.Mixing.check_ragged(d, net)

Contacts by a dimension need everyone who transmits or is infected to have a level of it

check_reciprocal
solvers.mixing.Mixing.check_reciprocal(net, strat, mat)

Say if a contact matrix is not reciprocal for the dimension’s split: the contacts of the people in level i with level j should equal those of j with i, N_i·C_ij = N_j·C_ji; or, for a matrix that acts only on counts (beta*I.n, beta*I.frac: see count_terms()), whose entries are for pairs of people, C_ij = C_ji

count_terms
solvers.mixing.Mixing.count_terms(terms=None)

The contact matrices that act on a count in a rate (I.n, I.frac: see ss.graph.Graph.met_counts), of the terms given or the sim’s; with none, a count is the number in the same place

A matrix acts on what the rate says: beta*I is exposure to the fraction of each group (beta·Σ_j C_ij·I_j/N_j), beta*I.n to the number in each (beta·Σ_j C_ij·I_j), and beta*I.frac to that number over everyone in the same place (beta·Σ_j C_ij·I_j/N). Other networks do not act on a count, as without a matrix.

counts
solvers.mixing.Mixing.counts(term)

Whether a term of the mixing acts on counts as well as fractions: a contact matrix, not homogeneous mixing or partnerships (see count_terms())

dim_matrices
solvers.mixing.Mixing.dim_matrices(net)

A contact matrix for each of one or more of the model’s dimensions: the contacts between two groups are the product of the entries; or one matrix over several dimensions together (ss.contacts(matrix, dims=[...]))

edge_dur
solvers.mixing.Mixing.edge_dur(net, sim)

How long each edge of a network transmits over before it is drawn again, in units of the sim’s time, for its approximation by homogeneous mixing: the network’s own step (a disease that steps less often uses its own: see ss.solvers.Compartmental.saturation()); None for a network whose edges never change (dynamic=False)

As agents, an edge transmits at most once to its susceptible end over a step D, with probability 1 − e^(−b·D) for a rate b, so the force of infection over K contacts per unit time is K·(1 − e^(−b·D))/D, not the K·b of mass action. The two agree as K → ∞ with K·b held fixed, but on a sparse network with long steps the difference matters, most of all near the epidemic threshold. Edges that last several steps (ss.RandomNet(dur=)) are taken a step at a time: within a lasting edge, the partners’ states change (recovery, reinfection), which is the partner-change model’s concern (ss.DegreeNet).

events
solvers.mixing.Mixing.events()

The events of the movement register, on the sim’s timeline: see ss.geo.Mobility.events()

exposure
solvers.mixing.Mixing.exposure(infectious, n, mults=None, counts=False)

Exposure of each group to an infectious state: contacts per unit time, times the chance that a contact is infectious; or, with counts, a count met through the contact matrices: contacts per unit time, times the number of people in the state (see count_terms())

Parameters
Name Type Description Default
infectious array the (infectiousness-weighted) number in the state, in each group required
n array the number of people in each group required
mults list a multiplier on the contacts of each term (a number, or one for each group), from the modifiers of its network None
counts bool whether the matrices act on the number in the state rather than its fraction False
init
solvers.mixing.Mixing.init(approximations='note', solver=None)

Turn the sim’s networks into contact rates between groups, for the sim’s solver (or the one given: the ODE, when the mixing is laid out to choose the solver, see ss.solvers.choose.lay_out())

init_movement
solvers.mixing.Mixing.init_movement()

The movement between places, from the current values of its parameters (again on a restart with new ones: see ss.Sim.restart())

init_pools
solvers.mixing.Mixing.init_pools()

As agents: the contact matrices of mixing pools from counts in each group, in a model with places (within each place), and for a matrix over the model’s own dimensions (ss.contacts()), which is then exact

A mixing pool’s hazard is worked out from the fraction of each group that is infectious, so the contact matrix is used as in a compartmental run, from the agents’ counts in each group (see ss.solvers.Agents.transmit()), with any movement between places. Over the model’s dimensions, everyone in a group has the same contacts, so this is what a pool for each pair of groups would give, without making one.

init_space
solvers.mixing.Mixing.init_space()

Find the spatial dimension, if there is one, and the movement between its levels

mean
solvers.mixing.Mixing.mean(val, unit)

The mean of a number of contacts, given as a number or a distribution; one given as a rate (e.g. ss.perday(10)) is per unit of the sim’s time, as a bare number is

note_regrouped
solvers.mixing.Mixing.note_regrouped()

Say which contact matrices were given over other age groups than the model’s, once for all of them

partnerships
solvers.mixing.Mixing.partnerships(net)

Lasting partnerships (ss.DegreeNet, ss.SexualNet) under the partner-change model: a matrix of the partnerships formed per unit time by one person in each cell (a side, by a level of a dimension) with people in each other, φ_i·m_ij, with φ_i = n_i/D̄ (partners at a time over how long partnerships last), split by the side of the partner, since the chance a partnership transmits differs by direction (see Compartmental.partnership_chance())

The sides of the network and the property of people it matches or counts partners by must be dimensions of the model. Partners are drawn from the population at random, in proportion to the partners each person has, within the other side for a network between men and women, and with match=, the fraction at the same level that it gives.

regroup_ages
solvers.mixing.Mixing.regroup_ages(net, bands, target_bands, contacts)

A contact matrix over age bands of its own, as one over the model’s age groups, weighted by population (adding the matrix’s own groups as the model’s if it has none); returns the index of the age dimension and the matrix

Parameters
Name Type Description Default
net ss.networks.MixingPools the contacts, for messages required
bands array the lower and upper edge of each source band (np.inf for the last) required
target_bands array the same for each target band required
contacts array the contacts per unit time of one person in each target band (rows) with people in each source band, as a contact survey required
spread
solvers.mixing.Mixing.spread(v, block=1, by_columns=False)

The product of the time fraction between places with values by place, or by place and level (block levels in each place): v @ frac if by_columns, else frac @ v

term_exposure
solvers.mixing.Mixing.term_exposure(term, infectious, n, counts=False)

Exposure of each group through one term of the mixing (with counts, to the number in the state): see exposure()

within_places
solvers.mixing.Mixing.within_places(term)

Make a contact matrix act within each place

The cells of the matrix become pairs of a place and a level, and the movement between places applies to each level: people mix by the matrix with the people present where they are. A matrix that is given over the places themselves already says who meets whom across them, so it is used as it is.

The mixing is the product of the time fraction between places and the matrix between levels (np.kron(frac, matrix)), but is kept as the two factors, which is much smaller and faster with many places: see term_exposure().