Source code for modelly.space.networks.contacts
"""Contact matrices: mean contacts between groups (age bands), for epidemic models."""
from __future__ import annotations
from collections.abc import Sequence
from typing import Any
import numpy as np
[docs]
def age_groups(ages: Sequence[float], breaks: Sequence[float]) -> np.ndarray:
"""The group of every age: ``0`` below ``breaks[0]``, ``i`` in ``[breaks[i-1], breaks[i])``.
``age_groups(ages, [18, 65])`` gives ``0`` for children, ``1`` for adults and ``2``
for people aged 65 and over.
"""
return np.searchsorted(np.asarray(breaks), np.asarray(ages), side="right")
[docs]
def contact_matrix(
network: Any,
groups: Sequence[int],
layer: str | Sequence[str] | None = None,
n_groups: int | None = None,
) -> np.ndarray:
"""Mean contacts a member of group ``a`` has with members of group ``b``.
``C[a, b] = W(a, b) / N(a)``, where ``W(a, b)`` is the total weight of the edges from
members of ``a`` to members of ``b`` and ``N(a)`` the size of group ``a``; rows of empty
groups are zero. For an undirected network ``N(a) C[a, b] = N(b) C[b, a]``.
Args:
network: a ``MultilayerNetwork`` or ``TemporalNetwork``, or a sparse adjacency.
groups: the group (``0 .. n_groups-1``) of every node, in row order.
layer: for a multilayer network, the layer or layers to count (all by default),
combined with their layer weights.
n_groups: the number of groups; defaults to ``max(groups) + 1``.
"""
from scipy import sparse # noqa: PLC0415 - scipy is heavy
if sparse.issparse(network):
adjacency = sparse.csr_matrix(network)
elif layer is None:
adjacency = network.adjacency()
else:
adjacency = network.adjacency(layer)
groups = np.asarray(groups, dtype=np.intp)
k = int(groups.max()) + 1 if n_groups is None else n_groups
n = groups.shape[0]
membership = sparse.csr_matrix((np.ones(n), (np.arange(n), groups)), shape=(n, k))
totals = (membership.T @ adjacency @ membership).toarray()
sizes = np.bincount(groups, minlength=k).astype(float)[:, np.newaxis]
return np.divide(totals, sizes, out=np.zeros_like(totals), where=sizes > 0)