Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6f1b036
adding stochastic transmission mode to expure and rdiffnet
aoliveram Dec 10, 2025
3e2f1f3
Fix stochastic exposure normalization (E<=1), improve docs, bump vers…
aoliveram Dec 10, 2025
df7054a
Switch stochastic exposure to Bernoulli-to-binary logic with degree n…
aoliveram Dec 27, 2025
c4a03f1
Switch stochastic exposure to Bernoulli-to-binary logic with degree n…
aoliveram Dec 27, 2025
6b56bf1
feat(data): integrate dynamic behavioral attrs into epigamesDiffNet (…
aoliveram Apr 7, 2026
da1ab6c
style: clean up epigames data generation scripts
aoliveram Apr 7, 2026
6bec689
chore: add t1 to edgelist format and clean up comments
aoliveram Apr 8, 2026
07218b3
Fix logic and improve printer for degree_adoption_diagnostic
aoliveram Apr 14, 2026
2c93148
Fix bug in dynamic degree extraction and symmetry detection
aoliveram Apr 14, 2026
52b8928
data: Make epigamesDiffNet non-cumulative and weighted
aoliveram Apr 16, 2026
5319ff6
docs: Update epigamesDiffNet docs with cumulative reconstruction steps
aoliveram Apr 16, 2026
0b87e69
merge: integrate issue-75-epigames-dynamic-attrs into issue-78 branch
aoliveram Apr 17, 2026
4e287f3
merge: integrate stochastic-transmission into issue-78 branch
aoliveram Apr 17, 2026
ddaec9e
feat(diffnet): add $tod slot and $transmission slot (M1, #78)
aoliveram Apr 17, 2026
a8088c8
rename get_transmissions() -> transmission_tree() (M1 follow-up, #78)
aoliveram Apr 18, 2026
a2cd639
feat(exposure): pluggable link_fun kernel (M2, #78)
aoliveram Apr 18, 2026
ebed4bd
test(exposure): continuous-weight stochastic tests + warn on out-of-r…
aoliveram Apr 18, 2026
c4ae665
refactor(exposure): user link_fun is single-arg only (M2 follow-up, #78)
aoliveram Apr 18, 2026
c6d84e9
feat: logit adoption model (M4)
aoliveram Apr 20, 2026
cd3cc8d
rename(rdiffnet): adoption_model values threshold/logit -> determinis…
aoliveram Apr 22, 2026
2087ef8
refactor(rdiffnet): adoption_mechanism callback (M6, #78), replacing …
aoliveram Apr 28, 2026
2ed6533
feat(rdiffnet) M6: disadoption-mechanism factories + adoption error f…
aoliveram Apr 29, 2026
3ebe7df
feat(diffnet): $status array as canonical state representation (M5)
aoliveram May 6, 2026
be08572
fix(diffnet): keep $status synced across cumadopt-mutating ops; renam…
aoliveram May 6, 2026
23d8890
feat(diffnet): diffnet_epi subclass for epidemiological diffnets (M7,…
aoliveram May 12, 2026
be17220
fix(diffnet-epi): document -...- in print.diffnet_epi to silence R CM…
aoliveram May 12, 2026
5e587be
feat(diffnet): -transmission- argument in new_diffnet() (M7, #78)
aoliveram May 12, 2026
576ce13
feat(rdiffnet): source_attribution callback + adoption_mechanism cont…
aoliveram May 12, 2026
c8c348f
feat(diffnet_epi): epidemiological metrics (M10, #78)
aoliveram May 12, 2026
cb879d5
fix(epi_metrics): replace em-dash with ASCII in cat() strings (M10 fo…
aoliveram May 13, 2026
5e7826e
fix(stats): hazard_rate uses the fresh-adoption indicator (M11, #78)
aoliveram May 13, 2026
d333bd6
feat(epi_metrics): repr_number() + offspring distribution plot (M12, …
aoliveram May 13, 2026
7289dc8
fix(epi_metrics): label aggregate R across viruses in repr_number pri…
aoliveram May 13, 2026
f92bc66
fix(epi_metrics): unify nomenclature to "diffusion" in repr_number pr…
aoliveram May 13, 2026
e89aed2
feat(epi_metrics): per-event keying for SIRS / re-infection support (…
aoliveram May 13, 2026
688001a
feat(transmission): general-purpose tree reconstruction from observed…
aoliveram May 13, 2026
6034610
docs(vignettes): add epidemiological-analysis vignette (M14, #78)
aoliveram May 14, 2026
f6ef96d
docs(vignettes): M14 v2 -- pedagogical fixes + stochasticity section …
aoliveram May 14, 2026
7996e82
docs(vignettes): virus-correct simulation setup + restructure stochas…
aoliveram May 14, 2026
facf305
docs(vignettes): correct the §3-§7 / Wells-Riley framing (M14, #78)
aoliveram May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: netdiffuseR
Title: Analysis of Diffusion and Contagion Processes on Networks
Version: 1.25.0
Version: 1.26.0
Authors@R: c(
person("George", "Vega Yon", email="g.vegayon@gmail.com", role=c("aut", "cre"),
comment=c(ORCID = "0000-0002-3171-0844", what="Rewrite functions with Rcpp, plus new features")
Expand Down Expand Up @@ -57,11 +57,13 @@ URL: https://github.com/USCCANA/netdiffuseR,
https://USCCANA.github.io/netdiffuseR/
BugReports: https://github.com/USCCANA/netdiffuseR/issues
Classification/MSC: 90C35, 90B18, 91D30
Collate:
Collate:
'RcppExports.R'
'imports.r'
'graph_data.r'
'adjmat.r'
'adoption_mechanisms.R'
'disadoption_mechanisms.R'
'bass.r'
'bootnet.r'
'citer_environment.R'
Expand All @@ -70,8 +72,10 @@ Collate:
'degree_adoption_diagnostic.R'
'diffnet-c.R'
'diffnet-class.r'
'diffnet-epi.R'
'diffnet-indexing.r'
'diffnet-methods.r'
'epi_metrics.R'
'egonets.R'
'formula.r'
'igraph.r'
Expand All @@ -89,8 +93,11 @@ Collate:
'rdiffnet.r'
'read_write_foreign.r'
'select_egoalter.R'
'source_attribution.R'
'spatial.R'
'stats.R'
'status_accessors.R'
'struct_equiv.R'
'struct_test.R'
'survey_to_diffnet.R'
'transmission.R'
45 changes: 45 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ S3method(dimnames,diffnet)
S3method(fitbass,default)
S3method(fitbass,diffnet)
S3method(ftable,diffnet_adopters)
S3method(generation_time,default)
S3method(generation_time,diffnet_epi)
S3method(hist,diffnet_bootnet)
S3method(hist,diffnet_struct_test)
S3method(image,diffnet_diffmap)
Expand All @@ -51,6 +53,8 @@ S3method(is_undirected,default)
S3method(is_undirected,diffnet)
S3method(is_valued,default)
S3method(is_valued,diffnet)
S3method(peak_prevalence,diffnet)
S3method(peak_time,diffnet)
S3method(plot,diffnet)
S3method(plot,diffnet_adopters)
S3method(plot,diffnet_bass)
Expand All @@ -59,6 +63,7 @@ S3method(plot,diffnet_degSeq)
S3method(plot,diffnet_diffmap)
S3method(plot,diffnet_hr)
S3method(plot,diffnet_mentor)
S3method(plot,netdiffuseR_repr)
S3method(plot_diffnet,default)
S3method(plot_diffnet,diffnet)
S3method(plot_diffnet2,default)
Expand All @@ -70,27 +75,47 @@ S3method(print,degree_adoption_diagnostic)
S3method(print,diffnet)
S3method(print,diffnet_bootnet)
S3method(print,diffnet_diffmap)
S3method(print,diffnet_epi)
S3method(print,diffnet_se)
S3method(print,diffnet_struct_test)
S3method(print,netdiffuseR_generation_time)
S3method(print,netdiffuseR_repr)
S3method(print,netdiffuseR_sar)
S3method(print,netdiffuseR_survival)
S3method(recode,data.frame)
S3method(recode,matrix)
S3method(repr_number,default)
S3method(repr_number,diffnet_epi)
S3method(secondary_attack_rate,default)
S3method(secondary_attack_rate,diffnet_epi)
S3method(str,diffnet)
S3method(summary,diffnet)
S3method(summary,diffnet_adoptChanges)
S3method(summary,diffnet_epi)
S3method(survival_curve,diffnet)
S3method(t,diffnet)
S3method(toa,diffnet)
S3method(toa_all,diffnet)
S3method(tod,diffnet)
S3method(tod_all,diffnet)
S3method(transformGraphBy,dgCMatrix)
S3method(transformGraphBy,diffnet)
export("%*%")
export("diffnet.attrs<-")
export("diffnet.toa<-")
export(adjmat_to_edgelist)
export(adopt_changes)
export(adoptmech_logit)
export(adoptmech_probit)
export(adoptmech_threshold)
export(approx_geodesic)
export(approx_geodist)
export(as.dgCMatrix)
export(as_dgCMatrix)
export(as_diffnet)
export(as_diffnet_epi)
export(as_spmat)
export(as_transmission_tree)
export(bass_F)
export(bass_dF)
export(bass_f)
Expand All @@ -114,6 +139,10 @@ export(diffnet_to_network)
export(diffnet_to_networkDynamic)
export(diffreg)
export(diffusionMap)
export(disadoptmech_bithreshold)
export(disadoptmech_logit)
export(disadoptmech_probit)
export(disadoptmech_random)
export(drawColorKey)
export(drop_isolated)
export(edgelist_to_adjmat)
Expand All @@ -123,12 +152,14 @@ export(ego_variance)
export(egonet_attrs)
export(exposure)
export(fitbass)
export(generation_time)
export(graph_power)
export(grid_distribution)
export(hazard_rate)
export(igraph_to_diffnet)
export(igraph_vertex_rescale)
export(infection)
export(is.diffnet_epi)
export(is_multiple)
export(is_self)
export(is_undirected)
Expand All @@ -150,6 +181,8 @@ export(nnodes)
export(nodes)
export(nslices)
export(nvertices)
export(peak_prevalence)
export(peak_time)
export(permute_graph)
export(plot_adopters)
export(plot_diffnet)
Expand All @@ -165,6 +198,7 @@ export(read_pajek)
export(read_ucinet)
export(read_ucinet_head)
export(recode)
export(repr_number)
export(resample_graph)
export(rescale_vertex_igraph)
export(rewire_graph)
Expand All @@ -175,17 +209,28 @@ export(rgraph_er)
export(rgraph_ws)
export(ring_lattice)
export(round_to_seq)
export(secondary_attack_rate)
export(select_egoalter)
export(source_attribution_earliest)
export(source_attribution_uniform)
export(source_attribution_weighted)
export(split_behaviors)
export(struct_equiv)
export(struct_test)
export(struct_test_asymp)
export(survey_to_diffnet)
export(survival_curve)
export(susceptibility)
export(threshold)
export(toa)
export(toa_all)
export(toa_diff)
export(toa_mat)
export(tod)
export(tod_all)
export(transformGraphBy)
export(transmission_tree)
export(transmission_tree_from_events)
export(vertex_covariate_compare)
export(vertex_covariate_dist)
export(vertex_mahalanobis_dist)
Expand Down
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
* New dataset `epigames` and `epigamesDiffNet`: a simulated epidemic game
network with 594 nodes and 15 time periods from the WKU Epi Games study.

* `exposure()` and `rdiffnet()` now support `mode = "stochastic"`, allowing
for probabilistic interpretation of edge weights in exposure calculations.

## Internal changes

* Fixed CRAN example error in `round_to_seq()`: `plot(w, x)` replaced with
Expand All @@ -19,7 +22,6 @@

* Removed `configure` framework. R already provides paths and configuration for OpenMP.


# Changes in netdiffuseR version 1.24.0 (2025-12-09)

* New function `degree_adoption_diagnostic()` analyzes the correlation between network
Expand Down
103 changes: 103 additions & 0 deletions R/adjmat.r
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,109 @@ toa_mat.default <- function(per, t0, t1) {
)
}

# Status-array helpers.
#
# A -status- array carries the multi-cycle state of a diffnet: 1 wherever
# node i is adopted at time t for behaviour q, 0 otherwise. It need not be
# monotone (adoption + recovery cycles, behavioural relapse, etc.).
#
# Single-behaviour layout: an n x T integer matrix.
# Multi-behaviour layout: a length-Q list of n x T integer matrices.
#
# These helpers mirror -toa_mat- (which builds the absorbing case from -toa-)
# but consume -status- directly.

# Internal: build {adopt, cumadopt} matrices from a single-behaviour status.
# - cumadopt is exactly status (alias; no copy thanks to R's COW).
# - adopt[i, t] = 1 iff status[i, t] == 1 AND (t == 1 OR status[i, t-1] == 0).
# That is, every "fresh" entry into the adopted state.
status_mat_single <- function(status, t0, t1, labels = NULL) {
storage.mode(status) <- "integer"
n <- nrow(status)
T <- ncol(status)

cumadopt <- status
adopt <- matrix(0L, n, T)
if (T >= 1L) adopt[, 1L] <- cumadopt[, 1L]
if (T >= 2L) {
prev <- cumadopt[, 1:(T - 1L), drop = FALSE]
curr <- cumadopt[, 2:T, drop = FALSE]
fresh <- (curr == 1L) & (prev == 0L)
sub <- adopt[, 2:T, drop = FALSE]
sub[fresh] <- 1L
adopt[, 2:T] <- sub
}

rn <- if (length(labels)) labels else seq_len(n)
dimnames(adopt) <- list(rn, t0:t1)
dimnames(cumadopt) <- list(rn, t0:t1)
list(adopt = adopt, cumadopt = cumadopt)
}

# Public-facing dispatcher: returns the same shape as -toa_mat-.
status_mat <- function(status, t0, t1, labels = NULL) {
if (is.list(status)) {
lapply(status, status_mat_single, t0 = t0, t1 = t1, labels = labels)
} else {
status_mat_single(status, t0 = t0, t1 = t1, labels = labels)
}
}

# Derive -toa- from a status array: first time of 1 per node (per behaviour).
# Returns an integer vector for single-behaviour, an n x Q matrix otherwise.
# Names / rownames are intentionally NOT preserved — -new_diffnet- assigns
# them from -meta$ids- downstream so the diffnet's labelling stays canonical.
toa_from_status <- function(status, t0 = 1L) {
if (is.list(status)) {
Q <- length(status)
n <- nrow(status[[1L]])
out <- matrix(NA_integer_, n, Q)
for (q in seq_len(Q)) out[, q] <- toa_from_status(status[[q]], t0 = t0)
return(out)
}

n <- nrow(status)
vapply(seq_len(n), function(i) {
idx <- which(status[i, ] == 1L)
if (length(idx)) as.integer(idx[1L] + t0 - 1L) else NA_integer_
}, integer(1L))
}

# Validation for -status- supplied to -new_diffnet-.
validate_status <- function(status, n, num_of_behaviors) {
if (num_of_behaviors == 1L) {
if (!is.matrix(status))
stop("-status- for a single-behaviour diffnet must be an n x T matrix.")
if (nrow(status) != n)
stop("-status- has ", nrow(status), " rows but the graph has ", n,
" nodes.")
if (any(!status %in% c(0L, 1L, NA_integer_, 0, 1)))
stop("-status- entries must be 0 or 1.")
} else {
if (!is.list(status))
stop("-status- for a multi-behaviour diffnet must be a length-Q list ",
"of n x T matrices.")
if (length(status) != num_of_behaviors)
stop("-status- has length ", length(status),
" but -toa- carries ", num_of_behaviors, " behaviours.")
for (q in seq_along(status)) {
if (!is.matrix(status[[q]]))
stop("-status[[", q, "]]- must be an n x T matrix.")
if (nrow(status[[q]]) != n)
stop("-status[[", q, "]]- has ", nrow(status[[q]]),
" rows but the graph has ", n, " nodes.")
if (any(!status[[q]] %in% c(0L, 1L, NA_integer_, 0, 1)))
stop("-status[[", q, "]]- entries must be 0 or 1.")
}
# All behaviours must share a common T.
Ts <- vapply(status, ncol, integer(1L))
if (length(unique(Ts)) > 1L)
stop("All entries of -status- must share the same number of columns ",
"(time periods).")
}
invisible(TRUE)
}

# @rdname toa_mat
# @export
toa_mat.numeric <- function(times, labels=NULL,
Expand Down
Loading
Loading