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().