Skip to contents

Generates multiple longitudinal network realizations from the posterior distribution of a fitted LAME (Longitudinal AME) model. This function performs posterior predictive simulation for dynamic networks, propagating both cross-sectional and temporal uncertainty through the simulated trajectories.

Usage

# S3 method for class 'lame'
simulate(
  object,
  nsim = 100,
  seed = NULL,
  newdata = NULL,
  n_time = NULL,
  burn_in = 0,
  thin = 1,
  return_latent = FALSE,
  start_from = "posterior",
  ...
)

Arguments

object

fitted model object of class "lame"

nsim

number of network trajectories to simulate (default: 100)

seed

random seed for reproducibility

newdata

optional list containing new covariate data:

Xdyad

list of T dyadic covariate arrays (n x n x p or nA x nB x p)

Xrow

list of T row/sender covariate matrices (n x p or nA x p)

Xcol

list of T column/receiver covariate matrices (n x p or nB x p)

If NULL, uses covariates from original model fit

n_time

number of time periods to simulate. If NULL, uses same as original data

burn_in

number of initial MCMC samples to discard (default: 0)

thin

thinning interval for MCMC samples (default: 1, use every sample)

return_latent

logical: return latent Z matrices in addition to Y? (default: FALSE)

start_from

character: how to initialize the simulation

"posterior"

start from posterior mean (default)

"random"

random initialization

"data"

use first time point from original data

...

additional arguments (not currently used)

Value

A list with components:

Y

list of nsim simulated longitudinal network trajectories, each element is a list of T networks

Z

if return_latent=TRUE, list of nsim latent Z trajectories

family

the family of the model (binary, normal, etc.)

mode

network mode (unipartite or bipartite)

n_time

number of time periods

Details

Mathematical Framework for Longitudinal Networks:

The LAME model extends AME to multiple time periods T with potential temporal dependencies. For each time t = 1, ..., T: $$Y_{ij,t} \sim F(Z_{ij,t})$$ where the latent network evolves as: $$Z_{ij,t} = \beta^T x_{ij,t} + a_{i,t} + b_{j,t} + u_{i,t}^T v_{j,t} + \epsilon_{ij,t}$$

Temporal Dynamics:

LAME can incorporate three types of temporal dependencies:

  1. Static Effects: Parameters constant over time

    • \(a_{i,t} = a_i\), \(b_{j,t} = b_j\) for all t

    • \(u_{i,t} = u_i\), \(v_{j,t} = v_j\) for all t

  2. Dynamic Additive Effects: AR(1) process for random effects $$a_{i,t} = \rho_{ab} a_{i,t-1} + \eta_{i,t}, \quad \eta_{i,t} \sim N(0, \sigma_a^2(1-\rho_{ab}^2))$$ $$b_{j,t} = \rho_{ab} b_{j,t-1} + \xi_{j,t}, \quad \xi_{j,t} \sim N(0, \sigma_b^2(1-\rho_{ab}^2))$$ where \(\rho_{ab}\) is the temporal correlation parameter

  3. Dynamic Multiplicative Effects: AR(1) for latent factors $$u_{i,t} = \rho_{uv} u_{i,t-1} + \omega_{i,t}$$ $$v_{j,t} = \rho_{uv} v_{j,t-1} + \psi_{j,t}$$

Uncertainty Quantification Process for Trajectories:

For each simulated trajectory k = 1, ..., nsim:

Step 1: Parameter Sampling

  • Draw MCMC iteration s uniformly from stored posterior samples

  • Extract static parameters: \(\beta^{(s)}\), variance components

  • Extract temporal parameters if applicable: \(\rho_{ab}^{(s)}\), \(\rho_{uv}^{(s)}\)

Step 2: Initialize at t = 1

Depending on start_from parameter:

  • "posterior": Use posterior means as starting values

  • "random": Draw from stationary distribution

  • For additive effects: \(a_{i,1}^{(k)} \sim N(0, \sigma_a^2)\)

  • For multiplicative effects: Initialize from prior

Step 3: Evolve Through Time

For each t = 2, ..., T:

a) Update Dynamic Effects (if applicable): $$a_{i,t}^{(k)} = \rho_{ab}^{(s)} a_{i,t-1}^{(k)} + \eta_{i,t}^{(k)}$$ where \(\eta_{i,t}^{(k)} \sim N(0, \sigma_a^2(1-[\rho_{ab}^{(s)}]^2))\)

The innovation variance \(\sigma_a^2(1-\rho_{ab}^2)\) ensures stationarity

b) Construct Latent Network: $$E[Z_{ij,t}^{(k)}] = \beta^{(s)T} x_{ij,t} + a_{i,t}^{(k)} + b_{j,t}^{(k)} + u_{i,t}^T v_{j,t}$$

c) Add Dyadic Noise: $$Z_{ij,t}^{(k)} = E[Z_{ij,t}^{(k)}] + \epsilon_{ij,t}^{(k)}$$ with correlation structure preserved from AME model

d) Generate Observations: Apply appropriate link function based on family

Sources of Uncertainty in Longitudinal Context:

  1. Cross-sectional uncertainty (as in AME):

    • Parameter uncertainty from MCMC

    • Random effect variability

    • Dyadic noise

  2. Temporal uncertainty:

    • Uncertainty in temporal correlation parameters \(\rho_{ab}, \rho_{uv}\)

    • Innovation noise in AR(1) processes

    • Propagation of uncertainty through time (compounds over periods)

  3. Initial condition uncertainty:

    • Different starting values lead to different trajectories

    • Captured through start_from options

Interpretation of Multiple Trajectories:

Each simulated trajectory represents one possible evolution of the network consistent with the posterior distribution. Variation across trajectories captures:

  • Model parameter uncertainty

  • Stochastic variation in temporal evolution

  • Accumulated uncertainty over time periods

The ensemble of trajectories provides prediction intervals that widen over time, reflecting increasing uncertainty in longer-term forecasts.

Special Considerations:

  1. Temporal Correlation: Higher \(\rho\) values create smoother trajectories with more persistence

  2. Stationarity: The AR(1) innovation variance is scaled to maintain stationary marginal distributions

  3. Missing Time Points: If simulating beyond observed data (n_time > T_observed), covariates are recycled or set to zero with appropriate warnings

Limitations:

As with simulate.ame, multiplicative effects currently use posterior means. Full uncertainty would require storing complete MCMC chains for \(u_{i,t}, v_{j,t}\) at all time points, which is memory-intensive for large networks and long time series.

Author

Shahryar Minhas

Examples

if (FALSE) { # \dontrun{
# Fit a longitudinal model
data(YX_bin_list)
fit <- lame(YX_bin_list$Y, YX_bin_list$X, burn=100, nscan=500, family="binary")

# Simulate 50 network trajectories from posterior
sims <- simulate(fit, nsim=50)

# Simulate longer time series
sims_long <- simulate(fit, nsim=25, n_time=20)

# With new covariates
new_X <- lapply(YX_bin_list$X, function(x) {
  array(rnorm(prod(dim(x))), dim=dim(x))
})
sims_new <- simulate(fit, nsim=50, newdata=list(Xdyad=new_X))
} # }