RECAST Social Relationships
fastmob.social implements RECAST (Random rElationship ClASsifier sTrategy)
for temporal physical contacts inferred from globally assigned staypoints.
recast_from_staypoints uses UTC calendar days as its event snapshots. This
matches RECAST's human-mobility setting and avoids exposing an arbitrary time
delta as a social parameter. A daily edge is created only when two users' stay
intervals overlap at a shared global location for at least
min_minutes_for_encounter (default: 5 minutes). It then uses the paper's
T-RND: each daily event graph is independently sampled with the degree-product
RND probability. This preserves degrees in expectation rather than exactly in
every replica. The pooled randomized persistence and topological-overlap
distributions define both thresholds at p_rnd.
Every observed aggregate edge is returned as one of:
Friends: social persistence and social overlap.Bridges: social persistence and random-like overlap.Acquaintances: random-like persistence and social overlap.Random: random-like persistence and overlap.
The defaults reproduce the paper's five randomized replicas, while keeping the graph construction, randomization, and metric calculations in Rust.
RECAST parallelizes independent (day, location) contact buckets and T-RND
replica/window work through Rayon. The public API intentionally has no worker
parameter: use the RAYON_NUM_THREADS environment variable to bound the
process-wide Rayon pool when coordinating CPU use with other workloads.
validate_recast_from_staypoints adds the validation artifacts from the paper
without expanding into its application-specific routing experiments: pooled
null distributions for the Figure 4 CCDFs, full cumulative clustering curves
(Figure 3), and random-edge-only clustering curves (Figure 8). The dedicated
temporal_graph_from_staypoints, rnd, and t_rnd APIs expose the underlying
Arrow-backed event graphs for independent inspection.
Catalogue
Build contact networks
| API | Description | Example |
|---|---|---|
co_presence_graph_from_staypoints |
Build the aggregate contact network from the co-presence of users at the same location. | Build the contact network |
temporal_graph_from_staypoints |
Build the daily contact graphs from staypoints and a global location catalogue, without classifying. | Look inside |
graph_from_edges |
Build a normalized undirected graph from a list of edges. | A random baseline |
NetworkGraph |
An undirected graph stored as sorted, dense integer edge arrays. | |
NetworkGraph.degrees |
Return the number of contacts of each node, as an integer array of length node_count. |
|
ContactNetworkResult |
Daily RECAST event graphs plus their raw aggregate contact network. |
Network statistics
| API | Description | Example |
|---|---|---|
clustering_coefficients |
Return the local clustering coefficient of every node. | Structure |
topological_overlap |
Return the neighbourhood overlap of every edge. | Structure |
distribution_summary |
Summarize a sample with stable statistics after dropping non-finite values. | Structure |
safe_wasserstein |
Return the 1-D Wasserstein distance between two samples, or None when it is undefined. |
A random baseline |
Null models
| API | Description | Example |
|---|---|---|
degree_preserving_random_graph |
Sample a random graph whose node degrees match the given degrees in expectation (Chung-Lu model). | A random baseline |
random_persistence |
Sample the persistence that edges of a degree-preserving random baseline would have. | Look inside |
rnd |
Generate one randomized copy of a daily contact graph (the paper's RND null model). | Look inside |
t_rnd |
Generate independent randomized replicas of every daily contact graph (the T-RND null model). | Look inside |
Recast: re-timing a contact network
| API | Description | Example |
|---|---|---|
recast_from_staypoints |
Classify contacts as Friends, Bridges, Acquaintances or Random (the RECAST method). | Classify the contacts |
validate_recast_from_staypoints |
Run the RECAST classifier and return it together with the validation distributions. | Look inside |
RecastClass |
Relationship classes defined by RECAST Algorithm 1. | |
RecastResult |
Classification arrays aligned one-for-one with aggregate observed edges. | |
RecastResult.mask |
Return a boolean array that is true for the contacts classified as relationship. |
|
RecastTemporalGraph |
Packed Arrow event graphs; offsets delimit the edges for each day. | |
RecastTemporalGraph.event |
Return the contact graph of time step index (one day), raising IndexError if out of range. |
|
RecastEventGraph |
One Arrow-backed, undirected event graph with integer node ids. | |
RecastClusteringComparison |
Cumulative clustering coefficients for observed G_t and T-RND G^R_t. | |
RecastValidation |
Section 4/5 RECAST validation artifacts, all in Arrow arrays. |
Raw co-presence networks
co_presence_graph_from_staypoints returns raw contacts from the same daily
event graphs RECAST uses. It applies globally assigned locations, stay
interval overlap, and min_minutes_for_encounter, and returns both the daily
RecastTemporalGraph and its aggregate NetworkGraph with per-edge daily
persistence. Groups are not capped.
The raw contact result does not estimate random thresholds or assign relationship classes. Those steps belong to RECAST. Generic graph diagnostics such as clustering coefficients and topological overlap remain available for the aggregate graph.
co_presence_graph_from_staypoints(staypoints, locations, *, min_minutes_for_encounter=5)
Build the aggregate contact network from the co-presence of users at the same location.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
staypoints
|
Staypoints
|
Stays that carry a global |
required |
locations
|
Locations
|
The global location catalogue. |
required |
min_minutes_for_encounter
|
int
|
Minimum time overlap, in minutes, for two users to count as in contact on a day. Default 5. |
5
|
Returns:
| Type | Description |
|---|---|
ContactNetworkResult
|
|
Worked example: Build the contact network
temporal_graph_from_staypoints(staypoints, locations, *, min_minutes_for_encounter=5)
Build the daily contact graphs from staypoints and a global location catalogue, without classifying.
Two users are in contact on a day when their stays at the same location overlap in time for at least
min_minutes_for_encounter minutes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
staypoints
|
Staypoints
|
Stays that carry a global |
required |
locations
|
Locations
|
The global location catalogue. |
required |
min_minutes_for_encounter
|
int
|
Minimum overlap, in minutes, for a contact. Default 5. |
5
|
Returns:
| Type | Description |
|---|---|
RecastTemporalGraph
|
One contact graph per day; |
Worked example: Look inside
graph_from_edges(node_count, edges)
Build a normalized undirected graph from a list of edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_count
|
int
|
Number of nodes; nodes are the integers |
required |
edges
|
iterable of (int, int)
|
Undirected edges. Self-loops are dropped and duplicate edges (in either direction) are merged. |
required |
Returns:
| Type | Description |
|---|---|
NetworkGraph
|
The graph, with |
Worked example: A random baseline
NetworkGraph
dataclass
An undirected graph stored as sorted, dense integer edge arrays.
degrees()
Return the number of contacts of each node, as an integer array of length node_count.
ContactNetworkResult
dataclass
Daily RECAST event graphs plus their raw aggregate contact network.
clustering_coefficients(graph)
Return the local clustering coefficient of every node.
For a node with at least two neighbours it is the share of pairs of its neighbours that are also connected to each other (0 to 1); for a node with fewer than two neighbours it is 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
NetworkGraph
|
An undirected graph, for example |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
One value per node, in node order. |
Worked example: Structure
topological_overlap(graph)
Return the neighbourhood overlap of every edge.
For an edge between nodes u and v it is the Jaccard overlap of their neighbourhoods: the number
of neighbours they share divided by the size of the union of their neighbourhoods (0 to 1). High values
mean the two people have many common contacts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
NetworkGraph
|
An undirected graph. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
One value per edge, in the order of |
Worked example: Structure
distribution_summary(values)
Summarize a sample with stable statistics after dropping non-finite values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ndarray
|
The sample. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
|
Worked example: Structure
safe_wasserstein(left, right)
Return the 1-D Wasserstein distance between two samples, or None when it is undefined.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
ndarray
|
The two samples. |
required |
right
|
ndarray
|
The two samples. |
required |
Returns:
| Type | Description |
|---|---|
float or None
|
The distance in the units of the values, or |
Worked example: A random baseline
degree_preserving_random_graph(degrees, *, seed=42)
Sample a random graph whose node degrees match the given degrees in expectation (Chung-Lu model).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
degrees
|
ndarray
|
Target degree of each node; its length is the number of nodes. |
required |
seed
|
int
|
Random seed. Default 42. |
42
|
Returns:
| Type | Description |
|---|---|
NetworkGraph
|
A random undirected graph. Its degrees equal |
Worked example: A random baseline
random_persistence(graph, degrees, *, time_steps, seed)
Sample the persistence that edges of a degree-preserving random baseline would have.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
NetworkGraph
|
The observed graph, whose edges define how many values are drawn. |
required |
degrees
|
ndarray
|
Degree of each node used by the Chung-Lu baseline. |
required |
time_steps
|
int
|
Number of time steps (days) over which persistence is measured. |
required |
seed
|
int
|
Random seed. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
One persistence value (share of time steps in which the edge exists, 0 to 1) per sampled edge. |
Worked example: Look inside
rnd(event_graph, *, seed=42)
Generate one randomized copy of a daily contact graph (the paper's RND null model).
Each node keeps about the number of contacts it had that day, but contacts are redrawn at random.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_graph
|
RecastEventGraph
|
The contact graph of one day, for example |
required |
seed
|
int
|
Random seed. Default 42. |
42
|
Returns:
| Type | Description |
|---|---|
RecastEventGraph
|
The randomized graph. Degrees are preserved in expectation, not exactly. |
Worked example: Look inside
t_rnd(temporal_graph, *, random_replicates=5, seed=42)
Generate independent randomized replicas of every daily contact graph (the T-RND null model).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
temporal_graph
|
RecastTemporalGraph
|
The daily contact graphs. |
required |
random_replicates
|
int
|
Number of independent replicas of the whole period. Default 5. |
5
|
seed
|
int
|
Random seed. Default 42. |
42
|
Returns:
| Type | Description |
|---|---|
list of RecastTemporalGraph
|
|
Worked example: Look inside
recast_from_staypoints(staypoints, locations, *, min_minutes_for_encounter=5, p_rnd=0.001, random_replicates=5, seed=42)
Classify contacts as Friends, Bridges, Acquaintances or Random (the RECAST method).
Each contact has a persistence (share of days it occurred) and a topological overlap (neighbourhood
overlap). A value counts as high when it exceeds the 1 - p_rnd quantile of the same quantity in
degree-preserving randomized copies of the data. Friends have high persistence and high overlap, Bridges
high persistence and low overlap, Acquaintances low persistence and high overlap, and Random neither.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
staypoints
|
Staypoints
|
Stays that carry a global |
required |
locations
|
Locations
|
The global location catalogue. |
required |
min_minutes_for_encounter
|
int
|
Minimum time overlap, in minutes, for a contact. Default 5. |
5
|
p_rnd
|
float
|
Tail probability of the null distributions used for the thresholds. Default 0.001. |
0.001
|
random_replicates
|
int
|
Number of randomized replicas of the period. Default 5. |
5
|
seed
|
int
|
Random seed. Default 42. |
42
|
Returns:
| Type | Description |
|---|---|
RecastResult
|
Per-contact |
Worked example: Classify the contacts
validate_recast_from_staypoints(staypoints, locations, *, min_minutes_for_encounter=5, p_rnd=0.001, random_replicates=5, seed=42)
Run the RECAST classifier and return it together with the validation distributions.
Takes the same arguments as recast_from_staypoints and returns a RecastValidation that holds the
classification and the observed and null distributions of persistence, topological overlap and clustering,
which are the data for the method's diagnostic plots.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
staypoints
|
Staypoints
|
Stays that carry a global |
required |
locations
|
Locations
|
The global location catalogue. |
required |
min_minutes_for_encounter
|
optional
|
As in |
5
|
p_rnd
|
optional
|
As in |
0.001
|
random_replicates
|
optional
|
As in |
5
|
seed
|
optional
|
As in |
42
|
Returns:
| Type | Description |
|---|---|
RecastValidation
|
With |
Worked example: Look inside
RecastClass
Bases: IntEnum
Relationship classes defined by RECAST Algorithm 1.
RecastResult
dataclass
Classification arrays aligned one-for-one with aggregate observed edges.
mask(relationship)
Return a boolean array that is true for the contacts classified as relationship.
RecastTemporalGraph
dataclass
Packed Arrow event graphs; offsets delimit the edges for each day.
event(index)
Return the contact graph of time step index (one day), raising IndexError if out of range.
RecastEventGraph
dataclass
One Arrow-backed, undirected event graph with integer node ids.
RecastClusteringComparison
dataclass
Cumulative clustering coefficients for observed G_t and T-RND G^R_t.
RecastValidation
dataclass
Section 4/5 RECAST validation artifacts, all in Arrow arrays.
*_null arrays are the pooled RND/T-RND distributions used to infer
thresholds and plot the paper's CCDF diagnostics. full_clustering
corresponds to Figure 3; random_only_clustering corresponds to Figure
8 after retaining only edges classified as Random.