Latent
AR1
AR1(
autoreg_rv: RandomVariable,
innovation_sd_rv: RandomVariable,
parameterization: Parameterization = "innovation",
)
Bases: TemporalProcess
AR(1) process.
Each value depends on the previous value plus noise, with reversion toward a mean level. Keeps Rt bounded near a baseline — values that drift away are "pulled back" over time.
The parameterization argument selects between a non-centered
"innovation" parameterization, which samples independent standardized
innovations, and a centered "state" parameterization, which samples
each state conditionally on the preceding state. Both produce the same
prior distribution over the state path but can have different posterior
sampling geometry.
The innovation branch uses pyrenew.process.ARProcess to construct the trajectory from sampled innovations. The state branch uses local scanned conditional transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of noise at each time step. Larger values produce more volatile trajectories; smaller values produce smoother ones. |
required |
parameterization
|
Parameterization
|
Which latent object to sample: |
'innovation'
|
Initialize AR(1) process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of innovations. |
required |
parameterization
|
Parameterization
|
|
'innovation'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If autoreg_rv or innovation_sd_rv are not RandomVariable instances |
ValueError
|
If innovation_sd_rv is a DeterministicVariable with any value <= 0, or if parameterization is not a recognized string |
Source code in pyrenew/latent/temporal_processes.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
278 279 280 281 282 283 284 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "ar1",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample AR(1) trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Mean of the initial-state prior. The first returned value is sampled
as |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites |
'ar1'
|
first_day_dow
|
int | None
|
Unused. See pyrenew.latent.TemporalProcess. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
BaseLatentInfectionProcess
BaseLatentInfectionProcess(
*, name: str, gen_int_rv: RandomVariable, n_initialization_points: int
)
Bases: RandomVariable
Base class for latent infection processes with subpopulation structure.
Provides common functionality for hierarchical and partitioned infection models: - Population fraction validation and parsing (at sample time) - Standard output structure via LatentSample
All subclasses return infections as a LatentSample named tuple with fields:
(aggregate, all_subpops). Observation processes are responsible for selecting
which subpopulations they observe via indexing.
The constructor specifies model structure (generation interval, priors, temporal processes). Population structure (subpop_fractions) is provided at sample time, allowing a single model to be fit to multiple jurisdictions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gen_int_rv
|
RandomVariable
|
Generation interval PMF |
required |
n_initialization_points
|
int
|
Number of initialization days before the first observation day.
Latent and observation arrays use a shared padded time axis with
element 0 at the start of this initialization period. In observation
natural coordinates, day 0 is the first observed data day; on the
shared padded axis, that same day is index |
required |
Notes
Population structure (subpop_fractions) is passed to the sample() method, not the constructor. This allows a single model instance to be fit to multiple datasets with different jurisdiction structures.
When using PyrenewBuilder (recommended), n_initialization_points is computed automatically from all observation processes. When constructing latent processes directly, you must specify n_initialization_points explicitly.
Initialize base latent infection process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A name for this random variable. |
required |
gen_int_rv
|
RandomVariable
|
Generation interval PMF |
required |
n_initialization_points
|
int
|
Number of initialization days; see the class-level parameter documentation for the shared padded-axis convention. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If gen_int_rv is None or n_initialization_points is insufficient. |
Source code in pyrenew/latent/base.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | |
default_subpop_fractions
default_subpop_fractions() -> ArrayLike | None
Return default population fractions, or None if caller must provide them.
Override this function in order to omit specification of subpop_fractions at sample time, in which case it will be called by _parse_and_validate_fractions. Must return a valid array of positive elements that sums to 1.
Returns:
| Type | Description |
|---|---|
ArrayLike or None
|
Default fractions array, or None if no default exists. |
Source code in pyrenew/latent/base.py
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | |
get_required_lookback
get_required_lookback() -> int
Return the generation interval length for builder pattern support.
This method is used by PyrenewBuilder to compute n_initialization_points from all model components. Returns the generation interval PMF length.
Returns:
| Type | Description |
|---|---|
int
|
Length of generation interval PMF |
Source code in pyrenew/latent/base.py
442 443 444 445 446 447 448 449 450 451 452 453 454 | |
requires_calendar_anchor
requires_calendar_anchor() -> bool
Report whether this latent process needs a calendar anchor at sample time.
The default implementation inspects this instance's attributes
for :class:pyrenew.latent.temporal_processes.TemporalProcess
instances and returns True if any of them has
requires_calendar_anchor=True. Subclasses may override to add
additional calendar-aligned components.
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in pyrenew/latent/base.py
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | |
sample
abstractmethod
sample(
n_days_post_init: int,
subpop_fractions: ArrayLike | None = None,
**kwargs: object,
) -> LatentSample
Sample latent infections for all subpopulations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_days_post_init
|
int
|
Number of days to simulate after initialization period |
required |
subpop_fractions
|
ArrayLike | None
|
Population fractions for all subpopulations.
Shape: (n_subpops,). Must sum to 1.0.
If None, falls back to |
None
|
**kwargs
|
object
|
Additional parameters required by specific implementations |
{}
|
Returns:
| Type | Description |
|---|---|
LatentSample
|
Named tuple with fields: - aggregate: shape (n_total_days,) - all_subpops: shape (n_total_days, n_subpops) where n_total_days = n_initialization_points + n_days_post_init |
Source code in pyrenew/latent/base.py
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | |
BaseSubpopulationInfections
BaseSubpopulationInfections(
*,
name: str,
gen_int_rv: RandomVariable,
n_initialization_points: int,
I0_rv: RandomVariable,
baseline_rt_process: TemporalProcess,
subpop_rt_deviation_process: TemporalProcess,
log_rt_time_0_rv: RandomVariable,
)
Bases: BaseLatentInfectionProcess
Base class for subpopulation renewal models with hierarchical \(\mathcal{R}(t)\).
Subpopulations share a baseline \(\mathcal{R}(t)\). The log \(\mathcal{R}(t)\) of each subpopulation is the log of the baseline plus a deviation, and the deviations sum to zero on each day, so the baseline is the geometric mean of the subpopulation values.
The starting log \(\mathcal{R}(t)\) and the initial infections are each either one value for all subpopulations or one value per subpopulation. Initial infections grow exponentially over the initialization period at the rate implied by each subpopulation's starting \(\mathcal{R}(t)\).
Each subclass defines how infections are generated from \(\mathcal{R}(t)\).
Notes
rt_baseline and rt_subpop are raw reproduction numbers generated
by the temporal-process hierarchy. rt_subpop_adjusted is the
reproduction number used to generate infections, as each subclass
defines it.
Initialize the shared subpopulation structure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name prefix for numpyro sample sites. All deterministic
quantities are recorded under this scope (e.g.,
|
required |
gen_int_rv
|
RandomVariable
|
Generation interval PMF |
required |
n_initialization_points
|
int
|
Number of initialization days before day 0. |
required |
I0_rv
|
RandomVariable
|
New infections per resident on the first day of the
initialization period, the earliest day on the time axis. This
is not prevalence. Returns either a scalar, one value for all
subpopulations, or an array of shape |
required |
baseline_rt_process
|
TemporalProcess
|
Temporal process for baseline \(\mathcal{R}(t)\) dynamics |
required |
subpop_rt_deviation_process
|
TemporalProcess
|
Temporal process for subpopulation deviations |
required |
log_rt_time_0_rv
|
RandomVariable
|
Starting log(\(\mathcal{R}(t)\)) on the first day of the
initialization period. Returns either a scalar, one value for all
subpopulations, or an array of shape |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If required parameters are missing or invalid. |
Source code in pyrenew/latent/subpopulation_infections.py
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
sample
sample(
n_days_post_init: int,
subpop_fractions: ArrayLike | None = None,
first_day_dow: int | None = None,
**kwargs: object,
) -> LatentSample
Sample infections for all subpopulations.
Generates daily baseline \(\mathcal{R}(t)\), daily subpopulation
deviations with a sum-to-zero constraint, and initial infections,
then computes infections after the initialization period with the
subclass's renewal. The temporal processes may sample parameters at
any supported cadence (for example daily or weekly/stepwise), but
they must return daily-length trajectories before the renewal is
evaluated. The raw subpopulation Rt is recorded as rt_subpop;
the Rt used to generate infections is recorded as
rt_subpop_adjusted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_days_post_init
|
int
|
Number of days to simulate after initialization period |
required |
subpop_fractions
|
ArrayLike | None
|
Population fractions for all subpopulations. Shape: (n_subpops,). Must sum to 1.0. |
None
|
first_day_dow
|
int | None
|
Forwarded to |
None
|
**kwargs
|
object
|
Additional keyword arguments (unused). |
{}
|
Returns:
| Type | Description |
|---|---|
LatentSample
|
Named tuple with fields: - aggregate: shape (n_total_days,) - all_subpops: shape (n_total_days, n_subpops) |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in pyrenew/latent/subpopulation_infections.py
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | |
validate
validate() -> None
Validate hierarchical infections parameters.
Checks that the generation interval is a valid PMF.
Raises:
| Type | Description |
|---|---|
ValueError
|
If gen_int_rv does not return a valid discrete distribution |
Source code in pyrenew/latent/subpopulation_infections.py
203 204 205 206 207 208 209 210 211 212 213 214 | |
DifferencedAR1
DifferencedAR1(
autoreg_rv: RandomVariable,
innovation_sd_rv: RandomVariable,
parameterization: Parameterization = "innovation",
)
Bases: TemporalProcess
AR(1) process on first differences.
Each change in value depends on the previous change plus noise, with the rate of change reverting toward a mean. Unlike AR(1), this allows Rt to trend persistently upward or downward while the growth rate stabilizes.
The parameterization argument selects between a non-centered
"innovation" parameterization, which samples independent standardized
innovations on the differences, and a centered "state"
parameterization, which samples the state path
\([x_1, \ldots, x_{T-1}]\) conditionally under the priors
where \(\phi\) is autoreg and \(\sigma\) is innovation_sd. The initial
state \(x_0\) is supplied deterministically as initial_value. Both produce
the same prior over the state path but can have different posterior
sampling geometry.
The innovation branch uses pyrenew.process.DifferencedProcess with pyrenew.process.ARProcess as its fundamental process. The state branch uses local scanned conditional transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient for differences. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of noise added to changes. Larger values produce more erratic growth rates; smaller values produce smoother trends. |
required |
parameterization
|
Parameterization
|
Which latent object to sample: |
'innovation'
|
Initialize differenced AR(1) process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient for differences. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of innovations. |
required |
parameterization
|
Parameterization
|
|
'innovation'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If autoreg_rv or innovation_sd_rv are not RandomVariable instances |
ValueError
|
If innovation_sd_rv is a DeterministicVariable with any value <= 0, or if parameterization is not a recognized string |
Source code in pyrenew/latent/temporal_processes.py
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
463 464 465 466 467 468 469 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "diff_ar1",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample differenced AR(1) trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Deterministic first state of the trajectory. Scalar values are
broadcast to all processes; arrays must have shape
|
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites |
'diff_ar1'
|
first_day_dow
|
int | None
|
Unused. See pyrenew.latent.TemporalProcess. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | |
GammaGroupSdPrior
GammaGroupSdPrior(
name: str,
sd_mean_rv: RandomVariable,
sd_concentration_rv: RandomVariable,
sd_min: float = 0.05,
)
Bases: RandomVariable
Gamma prior for group-level standard deviations, bounded away from zero.
Samples n_groups positive values from Gamma(concentration, rate) + sd_min.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the sampled parameter in numpyro. |
required |
sd_mean_rv
|
RandomVariable
|
RandomVariable returning the mean of the Gamma distribution. |
required |
sd_concentration_rv
|
RandomVariable
|
RandomVariable returning the concentration (shape) parameter of Gamma. |
required |
sd_min
|
float
|
Minimum SD value (lower bound). |
0.05
|
Initialize gamma group SD prior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the sampled parameter. |
required |
sd_mean_rv
|
RandomVariable
|
RandomVariable returning the mean of the Gamma distribution. |
required |
sd_concentration_rv
|
RandomVariable
|
RandomVariable returning the concentration parameter. |
required |
sd_min
|
float
|
Minimum SD value (lower bound). |
0.05
|
Source code in pyrenew/latent/hierarchical_priors.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
sample
Sample group-level standard deviations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_groups
|
int
|
Number of groups. |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Array of shape (n_groups,) with values >= sd_min. |
Source code in pyrenew/latent/hierarchical_priors.py
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
HierarchicalNormalPrior
HierarchicalNormalPrior(name: str, sd_rv: RandomVariable)
Bases: RandomVariable
Zero-centered Normal prior for group-level effects.
Samples n_groups values from Normal(0, sd).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the sampled parameter in numpyro. |
required |
sd_rv
|
RandomVariable
|
RandomVariable returning the standard deviation. |
required |
Initialize hierarchical normal prior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the sampled parameter. |
required |
sd_rv
|
RandomVariable
|
RandomVariable returning the standard deviation. |
required |
Source code in pyrenew/latent/hierarchical_priors.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
sample
Sample group-level effects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_groups
|
int
|
Number of groups. |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Array of shape (n_groups,). |
Source code in pyrenew/latent/hierarchical_priors.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
InfectionInitializationMethod
InfectionInitializationMethod(n_timepoints: int)
Method for initializing infections in a renewal process.
Default constructor for
pyrenew.latent.infection_initialization_method.InfectionInitializationMethod.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
the number of time points for which to generate initial infections |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in pyrenew/latent/infection_initialization_method.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
initialize_infections
abstractmethod
Generate the number of initialized infections at each time point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I_pre_init
|
ArrayLike
|
An array representing some number of latent infections to be used with the specified |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
An array of length |
Source code in pyrenew/latent/infection_initialization_method.py
53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
validate
staticmethod
validate(n_timepoints: int) -> None
Validate inputs to the
pyrenew.latent.infection_initialization_method.InfectionInitializationMethod
constructor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
the number of time points to generate initial infections for |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in pyrenew/latent/infection_initialization_method.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
InfectionInitializationProcess
InfectionInitializationProcess(
name: str,
I_pre_init_rv: RandomVariable,
infection_init_method: InfectionInitializationMethod,
)
Bases: RandomVariable
Generate an initial infection history
Default class constructor for InfectionInitializationProcess
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A name to assign to the RandomVariable. |
required |
I_pre_init_rv
|
RandomVariable
|
A RandomVariable representing the number of infections that occur at some time before the renewal process begins. Each |
required |
infection_init_method
|
InfectionInitializationMethod
|
An |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in pyrenew/latent/infection_initialization_process.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
sample
sample() -> ArrayLike
Sample the Infection Initialization Process.
Returns:
| Type | Description |
|---|---|
ArrayLike
|
the number of initialized infections at each time point. |
Source code in pyrenew/latent/infection_initialization_process.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | |
InfectionProcessSample
Bases: NamedTuple
Infections and the reproduction number used to compute them.
Attributes:
| Name | Type | Description |
|---|---|---|
post_initialization_infections |
ArrayLike
|
The estimated latent infections after the initialization period. |
rt |
ArrayLike
|
The reproduction number used in the renewal equation. This is the input Rt for plain renewal and the adjusted Rt when feedback is used. |
Infections
Infections(name: str)
Bases: RandomVariable
Latent infections
This class samples infections given \(\mathcal{R}(t)\), initial infections, and generation interval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A name for this random variable. |
required |
Notes
The mathematical model is given by:
where \(I(t)\) is the number of infections at time \(t\), \(\mathcal{R}(t)\) is the reproduction number at time \(t\), and \(g(t-\tau)\) is the generation interval.
Default constructor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A name for this random variable. |
required |
Source code in pyrenew/latent/infections.py
55 56 57 58 59 60 61 62 63 64 | |
sample
sample(
Rt: ArrayLike, I0: ArrayLike, gen_int: ArrayLike, **kwargs: object
) -> InfectionProcessSample
Sample infections given \(\mathcal{R}(t)\), initial infections, and generation interval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Rt
|
ArrayLike
|
Reproduction number. |
required |
I0
|
ArrayLike
|
Initial infections vector of the same length as the generation interval. |
required |
gen_int
|
ArrayLike
|
Generation interval pmf vector. |
required |
**kwargs
|
object
|
Additional keyword arguments passed through to internal sample calls, should there be any. |
{}
|
Returns:
| Type | Description |
|---|---|
InfectionProcessSample
|
A named tuple with a
|
Source code in pyrenew/latent/infections.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
InfectionsWithFeedback
InfectionsWithFeedback(
name: str,
infection_feedback_strength: RandomVariable,
infection_feedback_pmf: RandomVariable,
)
Bases: RandomVariable
Latent infections
This class computes infections, given Rt, initial infections, and generation interval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
infection_feedback_strength
|
RandomVariable
|
Infection feedback strength. |
required |
infection_feedback_pmf
|
RandomVariable
|
Infection feedback pmf. |
required |
Notes
This function implements the following renewal process (reproduced from
pyrenew.latent.infection_functions.compute_infections_from_rt_with_feedback):
where \(\mathcal{R}(t)\) is the reproductive number, \(\gamma(t)\) is the infection feedback strength, \(T_g\) is the max-length of the generation interval, \(\mathcal{R}^u(t)\) is the raw reproduction number, \(f(t)\) is the infection feedback pmf, and \(T_f\) is the max-length of the infection feedback pmf.
Default constructor for InfectionsWithFeedback class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A name for this random variable. |
required |
infection_feedback_strength
|
RandomVariable
|
Infection feedback strength. |
required |
infection_feedback_pmf
|
RandomVariable
|
Infection feedback pmf. |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in pyrenew/latent/infectionswithfeedback.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | |
sample
sample(
Rt: ArrayLike, I0: ArrayLike, gen_int: ArrayLike, **kwargs: object
) -> InfectionProcessSample
Samples infections given Rt, initial infections, and generation interval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Rt
|
ArrayLike
|
Reproduction number. |
required |
I0
|
ArrayLike
|
Initial infections, as an array at least as long as the generation interval PMF. |
required |
gen_int
|
ArrayLike
|
Generation interval PMF. |
required |
**kwargs
|
object
|
Additional keyword arguments passed through to internal sample calls, should there be any. |
{}
|
Returns:
| Type | Description |
|---|---|
InfectionProcessSample
|
Named tuple with post-initialization infections and Rt. |
Source code in pyrenew/latent/infectionswithfeedback.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
validate
staticmethod
Validates the input parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inf_feedback_strength
|
any
|
Infection feedback strength. |
required |
inf_feedback_pmf
|
any
|
Infection feedback pmf. |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in pyrenew/latent/infectionswithfeedback.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | |
InitializeInfectionsExponentialGrowth
InitializeInfectionsExponentialGrowth(
n_timepoints: int, rate_rv: RandomVariable, t_pre_init: int | None = None
)
Bases: InfectionInitializationMethod
Generate initial infections according to exponential growth.
Notes
The number of incident infections at time t is given by:
Where \(I_p\) is I_pre_init, \(r\) is rate, and \(t_p\) is t_pre_init.
This ensures that \(I(t_p) = I_p\).
We default to t_pre_init = n_timepoints - 1, so that
I_pre_init represents the number of incident infections immediately
before the renewal process begins.
Default constructor for the pyrenew.latent.infection_initialization_method.InitializeInfectionsExponentialGrowth class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
the number of time points to generate initial infections for |
required |
rate_rv
|
RandomVariable
|
A random variable representing the rate of exponential growth |
required |
t_pre_init
|
int | None
|
The time point whose number of infections is described by |
None
|
Source code in pyrenew/latent/infection_initialization_method.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
initialize_infections
Generate initial infections according to exponential growth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I_pre_init
|
ArrayLike
|
An array of size 1 representing the number of infections at time |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
An array of length |
Source code in pyrenew/latent/infection_initialization_method.py
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | |
InitializeInfectionsFromVec
InitializeInfectionsFromVec(n_timepoints: int)
Bases: InfectionInitializationMethod
Create initial infections from a vector of infections.
Source code in pyrenew/latent/infection_initialization_method.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
initialize_infections
Create initial infections from a vector of infections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I_pre_init
|
ArrayLike
|
An array with the same length as |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
An array of length |
Source code in pyrenew/latent/infection_initialization_method.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
InitializeInfectionsZeroPad
InitializeInfectionsZeroPad(n_timepoints: int)
Bases: InfectionInitializationMethod
Create an initial infection vector of specified length by padding a shorter vector with an appropriate number of zeros at the beginning of the time series.
Source code in pyrenew/latent/infection_initialization_method.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
initialize_infections
Pad the initial infections with zeros at the beginning of the time series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I_pre_init
|
ArrayLike
|
An array with initialized infections to be padded with zeros. |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
An array of length |
Source code in pyrenew/latent/infection_initialization_method.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | |
LatentSample
Bases: NamedTuple
Output from latent infection process sampling.
Attributes:
| Name | Type | Description |
|---|---|---|
aggregate |
ArrayLike
|
Total infections aggregated across all subpopulations. Shape: (n_total_days,) |
all_subpops |
ArrayLike
|
Infections for all subpopulations. Shape: (n_total_days, n_subpops) |
MobilitySubpopulationInfections
MobilitySubpopulationInfections(
*,
name: str,
gen_int_rv: RandomVariable,
n_initialization_points: int,
I0_rv: RandomVariable,
baseline_rt_process: TemporalProcess,
subpop_rt_deviation_process: TemporalProcess,
log_rt_time_0_rv: RandomVariable,
mobility_matrix_rv: DeterministicVariable,
susceptible_depletion: bool = True,
)
Bases: BaseSubpopulationInfections
Subpopulation renewal model coupled by a fixed mobility matrix.
Subpopulations are home regions whose residents spend part of each day at other locations. Transmission happens at each location, at that location's reproduction number, among the people present there, and each infection is assigned to the home region of the person infected. This implements Equation 2 of Roy, Clapham, and Mishra (2025), Incorporating human mobility to enhance epidemic response and estimate real-time reproduction numbers. With depletion enabled, PyRenew additionally caps each day's new infections at the remaining susceptible population.
Infections are per resident: infections[t, k] is new infections
among residents of home region k on day t, divided by the number
of residents of k. With M the mobility matrix and
p = subpop_fractions, one day with depletion enabled is:
present = M @ p
share_present = M * p[None, :] / jnp.where(present > 0, present, 1.0)[:, None]
infectiousness = reversed_gen_int @ history
susceptible = 1.0 - cumulative
new_infections_raw = M.T @ (rt * (share_present @ infectiousness))
new_infections = jnp.minimum(susceptible * new_infections_raw, susceptible)
share_present[j, k] is the share of the people present at location
j who live in region k, and cumulative counts every infection
since the first day of the initialization period. Initial infections
must be finite and non-negative. With depletion enabled, their sum
over all initialization days must be at most 1 per resident in each
region. Concrete invalid values raise ValueError; during JAX
tracing, callers must ensure sampled initialization meets these bounds.
M[j, k] is the fraction of residents of home region k present at
location j: columns are home regions, rows are locations, and each
column sums to 1. Regions must be in the same order in the matrix,
subpop_fractions, a vector-valued I0_rv, a vector-valued
log_rt_time_0_rv, and every observation's subpop_indices.
The recorded values are those of
pyrenew.latent.SubpopulationInfections, plus
susceptible_fraction. Under mobility:
rt_subpop[t, j]is the reproduction number at locationj, where transmission happens, when everyone is susceptible.rt_subpop_adjustedisrt_subpop * (share_present @ susceptible_fraction)after the initialization period, with depletion enabled. This adjusts for susceptibility but does not account for the incidence ceiling. It equals new infections per unit of infectiousness present only when the ceiling does not bind. It is 0 at a location with no one present.susceptible_fraction[t, i]is the share of residents of home regioninot infected before dayt. It is recorded as 1 minus cumulative infections and can become negative with depletion off.
Susceptible depletion is on by default, as in Eq 2. With it off,
neither susceptibility scaling nor the incidence ceiling is applied,
and inferred raw values of rt_subpop will need to directly absorb
any reductions in transmission due to susceptible depletion.
The matrix is fixed. Fitting and prediction use the matrix the model
was built with; it is available as mobility_matrix_rv.value.
Initialize the mobility-coupled infections process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name prefix for numpyro sample sites. All deterministic
quantities are recorded under this scope (e.g.,
|
required |
gen_int_rv
|
RandomVariable
|
Generation interval PMF |
required |
n_initialization_points
|
int
|
Number of initialization days before day 0. |
required |
I0_rv
|
RandomVariable
|
New infections per resident on the first day of the
initialization period, the earliest day on the time axis. This
is not prevalence. Returns either a scalar, one value for all
regions, or an array of shape |
required |
baseline_rt_process
|
TemporalProcess
|
Temporal process for baseline \(\mathcal{R}(t)\) dynamics |
required |
subpop_rt_deviation_process
|
TemporalProcess
|
Temporal process for subpopulation deviations |
required |
log_rt_time_0_rv
|
RandomVariable
|
Starting log(\(\mathcal{R}(t)\)) on the first day of the
initialization period. Returns either a scalar, one value for
all regions, or an array of shape |
required |
mobility_matrix_rv
|
DeterministicVariable
|
The mobility matrix used on every day, as a
|
required |
susceptible_depletion
|
bool
|
If True (default), new infections among residents of each region
are scaled by the fraction of those residents not yet infected,
as in Roy et al. Eq 2, and capped at that fraction. If False,
neither scaling nor the ceiling is applied, and |
True
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If mobility_matrix_rv is not a DeterministicVariable. |
ValueError
|
If required parameters are missing or invalid, or if the mobility matrix is not a valid column-stochastic matrix. |
Source code in pyrenew/latent/mobility_subpopulation_infections.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
PopulationInfections
PopulationInfections(
*,
name: str,
gen_int_rv: RandomVariable,
n_initialization_points: int,
I0_rv: RandomVariable,
single_rt_process: TemporalProcess,
log_rt_time_0_rv: RandomVariable,
infection_feedback_strength_rv: RandomVariable | None = None,
infection_feedback_pmf_rv: RandomVariable | None = None,
)
Bases: BaseLatentInfectionProcess
A single \(\mathcal{R}(t)\) trajectory drives one renewal equation.
The constructor specifies model structure (priors, temporal processes).
rt_single is the raw reproduction number generated by
single_rt_process. rt_single_adjusted is the reproduction
number used to generate infections. The two are equal unless infection
feedback is on.
Infection feedback is optional. It is on when both
infection_feedback_strength_rv and infection_feedback_pmf_rv
are given. On each day after the initialization period, it multiplies
the raw \(\mathcal{R}(t)\) by a factor that depends on recent infections:
where \(I(t)\) is new infections per resident, \(\gamma(t)\) is the feedback strength, \(f\) is the feedback PMF, and \(T_g\) is the length of the generation interval. The renewal equation then uses the adjusted \(\mathcal{R}^{\mathrm{adj}}(t)\) in place of \(\mathcal{R}(t)\). Negative strength lowers \(\mathcal{R}(t)\) when recent infections are high, and positive strength raises it. Because \(I(t)\) is per resident, the effect of a given strength depends on the level of infections per resident. With both arguments left out, infections follow the plain renewal equation.
Initialize population-level infections process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name prefix for numpyro sample sites. All deterministic
quantities are recorded under this scope (e.g.,
|
required |
gen_int_rv
|
RandomVariable
|
Generation interval PMF |
required |
n_initialization_points
|
int
|
Number of initialization days before day 0. |
required |
I0_rv
|
RandomVariable
|
Initial infection prevalence (proportion of population) |
required |
single_rt_process
|
TemporalProcess
|
Temporal process for single \(\mathcal{R}(t)\) dynamics |
required |
log_rt_time_0_rv
|
RandomVariable
|
Initial value for log(\(\mathcal{R}(t)\)) at time 0. |
required |
infection_feedback_strength_rv
|
RandomVariable | None
|
Infection feedback strength \(\gamma\). Returns a scalar, or an
array of shape |
None
|
infection_feedback_pmf_rv
|
RandomVariable | None
|
Feedback PMF \(f\), which weights recent infections in the feedback
factor. Element 0 weights infections on the previous day. Must have
the same length as the generation interval. Give together with
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If required parameters are missing or invalid, or if only one of the two infection feedback arguments is given. |
Source code in pyrenew/latent/population_infections.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
default_subpop_fractions
default_subpop_fractions() -> ArrayLike
Return default population fractions for a single-population model.
Returns:
| Type | Description |
|---|---|
ArrayLike
|
|
Source code in pyrenew/latent/population_infections.py
134 135 136 137 138 139 140 141 142 143 | |
sample
sample(
n_days_post_init: int,
subpop_fractions: ArrayLike | None = None,
first_day_dow: int | None = None,
**kwargs: object,
) -> LatentSample
Sample population infections using a single renewal process.
Generates a single daily \(\mathcal{R}(t)\) trajectory, computes initial
infections via exponential backprojection, and computes infections
with the renewal equation, with infection feedback if it is on. The
temporal process may sample parameters at any supported cadence (for
example daily or weekly/stepwise), but it must return a daily-length
trajectory before the renewal equation is evaluated. The raw Rt is
recorded as rt_single; the adjusted Rt used to generate infections
is recorded as rt_single_adjusted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_days_post_init
|
int
|
Number of days to simulate after initialization period |
required |
subpop_fractions
|
ArrayLike | None
|
Population fractions. Defaults to |
None
|
first_day_dow
|
int | None
|
Day of week for element 0 of the full latent infection time axis,
including initialization days. When this latent process is used
inside MultiSignalModel, the caller passes obs_start_date to the
model and it converts the first observation day to this axis-origin
day of week by subtracting n_initialization_points. Forwarded to
|
None
|
**kwargs
|
object
|
Additional keyword arguments (unused). |
{}
|
Returns:
| Type | Description |
|---|---|
LatentSample
|
Named tuple with fields: - aggregate: shape (n_total_days,) - all_subpops: shape (n_total_days, 1) |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in pyrenew/latent/population_infections.py
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
validate
validate() -> None
Validate population infections parameters.
Checks that the generation interval is a valid PMF.
Raises:
| Type | Description |
|---|---|
ValueError
|
If gen_int_rv does not return a valid discrete distribution |
Source code in pyrenew/latent/population_infections.py
179 180 181 182 183 184 185 186 187 188 189 190 | |
PopulationStructure
dataclass
PopulationStructure(fractions: ArrayLike)
Parsed and validated population structure for a jurisdiction.
Attributes:
| Name | Type | Description |
|---|---|---|
fractions |
ArrayLike
|
Population fractions for all subpopulations. Shape: (n_subpops,) |
RandomWalk
RandomWalk(
innovation_sd_rv: RandomVariable,
parameterization: Parameterization = "innovation",
)
Bases: TemporalProcess
Random walk process for log(Rt).
Each value equals the previous value plus noise, with no reversion toward a mean. Allows Rt to drift without bound — suitable when you have no prior expectation that Rt will return to a baseline.
The parameterization argument selects between a non-centered
"innovation" parameterization, which samples independent standardized
innovations, and a centered "state" parameterization, which samples
each state conditionally on the preceding state. The initial state
x[0] = initial_value is deterministic. Both parameterizations produce
the same prior over the state path but can have different posterior
sampling geometry.
The innovation branch uses pyrenew.process.RandomWalk to construct the trajectory from sampled innovations. The state branch uses local scanned conditional transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of noise at each time step. Larger values produce faster drift; smaller values produce more gradual changes. |
required |
parameterization
|
Parameterization
|
Which latent object to sample: |
'innovation'
|
Notes
Unlike AR(1), variance grows over time — the process can wander arbitrarily far from its starting point. For long time horizons, consider AR(1) if you want Rt to stay bounded near a baseline.
Initialize random walk process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of innovations. |
required |
parameterization
|
Parameterization
|
|
'innovation'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If innovation_sd_rv is not a RandomVariable instance |
ValueError
|
If innovation_sd_rv is a DeterministicVariable with any value <= 0, or if parameterization is not a recognized string |
Source code in pyrenew/latent/temporal_processes.py
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
635 636 637 638 639 640 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "rw",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample random walk trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Deterministic first state of the trajectory. Scalar values are
broadcast to all processes; arrays must have shape
|
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites |
'rw'
|
first_day_dow
|
int | None
|
Unused. See pyrenew.latent.TemporalProcess. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 | |
StepwiseTemporalProcess
StepwiseTemporalProcess(inner: TemporalProcess, step_size: int)
Bases: TemporalProcess
Parameterize an inner temporal process at a coarser cadence and broadcast to the per-timepoint scale by model-index repetition.
Each step_size consecutive output timepoints share a single sampled
value from the inner process. Use when a parameter should be estimated at
a coarser cadence while downstream model components still need one value
per evaluation timepoint. Blocks always start at output index 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
step_size
|
int
|
Number of per-timepoint units that share each inner sample. Must be a positive integer. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Initialize stepwise temporal process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
step_size
|
int
|
Number of per-timepoint units that share each inner sample. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in pyrenew/latent/temporal_processes.py
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
774 775 776 777 778 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "stepwise",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample coarse trajectory from inner process and broadcast.
Computes the number of coarse time steps needed for the requested
length, samples the inner process at that cadence, then broadcasts each
coarse value to the per-timepoint axis and trims to n_timepoints.
The returned value always has one row per evaluation timepoint,
regardless of the inner parameter cadence. The coarse
trajectory is recorded as a NumPyro deterministic site named
"{name_prefix}_coarse".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of per-timepoint outputs to produce. |
required |
initial_value
|
float | ArrayLike | None
|
Initial value(s) for the inner process. Defaults to 0.0. |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites; forwarded to the inner process. |
'stepwise'
|
first_day_dow
|
int | None
|
Ignored. Accepted for compatibility with the
|
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape |
Source code in pyrenew/latent/temporal_processes.py
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | |
StudentTGroupModePrior
StudentTGroupModePrior(name: str, sd_rv: RandomVariable, df_rv: RandomVariable)
Bases: RandomVariable
Zero-centered Student-t prior for group-level modes (robust alternative to Normal).
Samples n_groups values from StudentT(df, 0, sd).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the sampled parameter in numpyro. |
required |
sd_rv
|
RandomVariable
|
RandomVariable returning the scale parameter. |
required |
df_rv
|
RandomVariable
|
RandomVariable returning the degrees of freedom. |
required |
Initialize Student-t group mode prior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the sampled parameter. |
required |
sd_rv
|
RandomVariable
|
RandomVariable returning the scale parameter. |
required |
df_rv
|
RandomVariable
|
RandomVariable returning the degrees of freedom. |
required |
Source code in pyrenew/latent/hierarchical_priors.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | |
sample
Sample group-level modes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_groups
|
int
|
Number of groups. |
required |
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Array of shape (n_groups,). |
Source code in pyrenew/latent/hierarchical_priors.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
SubpopulationInfections
SubpopulationInfections(
*,
name: str,
gen_int_rv: RandomVariable,
n_initialization_points: int,
I0_rv: RandomVariable,
baseline_rt_process: TemporalProcess,
subpop_rt_deviation_process: TemporalProcess,
log_rt_time_0_rv: RandomVariable,
infection_feedback_strength_rv: RandomVariable | None = None,
infection_feedback_pmf_rv: RandomVariable | None = None,
)
Bases: BaseSubpopulationInfections
Multi-subpopulation renewal model with hierarchical \(\mathcal{R}(t)\) structure.
Each subpopulation has its own renewal equation with \(\mathcal{R}(t)\) deviating from a shared baseline. Suitable when transmission dynamics vary substantially across subpopulations. Each subpopulation renews independently: infections in one subpopulation do not depend on infections in any other.
Mathematical form: - Baseline \(\mathcal{R}(t)\): log[R_baseline(t)] ~ TemporalProcess - Subpopulation \(\mathcal{R}(t)\): log R_k(t) = log[R_baseline(t)] + delta_k(t) - Deviations: delta_k(t) ~ TemporalProcess with sum-to-zero constraint - Starting values on the first day of the initialization period, from log_rt_time_0_rv: a scalar s gives log[R_baseline(0)] = s and delta_k(0) = 0; one value v_k per subpopulation gives log[R_baseline(0)] = mean(v) and delta_k(0) = v_k - mean(v), so log R_k(0) = v_k. - Renewal per subpop: I_k(t) = R_k(t) * sum_tau I_k(t-tau) * g(tau) - Aggregate total: I_aggregate(t) = sum_k p_k * I_k(t)
Infection feedback is optional. It is on when both
infection_feedback_strength_rv and infection_feedback_pmf_rv
are given. On each day after the initialization period, it multiplies
the raw \(\mathcal{R}(t)\) of each subpopulation by a factor that depends
on recent infections in that subpopulation:
where \(I_k(t)\) is new infections per resident of subpopulation \(k\),
\(\gamma_k(t)\) is the feedback strength, \(f\) is the feedback PMF, and
\(T_g\) is the length of the generation interval. The renewal equation
of subpopulation \(k\) then uses the adjusted
\(\mathcal{R}^{\mathrm{adj}}_k(t)\) in place of \(\mathcal{R}_k(t)\).
Negative strength lowers \(\mathcal{R}_k(t)\) when recent infections are
high, and positive strength raises it. With both arguments left out,
infections follow the plain renewal equation. Sampling raises
ValueError if the feedback strength does not broadcast to shape
(n_days_post_init, n_subpops), or if the feedback PMF length
differs from the generation interval length.
The constructor specifies model structure (priors, temporal processes). Population structure (subpop_fractions) is provided at sample time, allowing a single model to be fit to multiple jurisdictions.
Notes
Sum-to-zero constraint on deviations ensures R_baseline(t) is the geometric
mean of subpopulation \(\mathcal{R}(t)\) values, providing identifiability.
rt_baseline and rt_subpop are raw reproduction numbers generated by
the temporal-process hierarchy. rt_subpop_adjusted is the reproduction
number used to generate infections. It equals rt_subpop unless
infection feedback is on.
Initialize hierarchical infections process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name prefix for numpyro sample sites. All deterministic
quantities are recorded under this scope (e.g.,
|
required |
gen_int_rv
|
RandomVariable
|
Generation interval PMF |
required |
n_initialization_points
|
int
|
Number of initialization days before day 0. |
required |
I0_rv
|
RandomVariable
|
New infections per resident on the first day of the
initialization period, the earliest day on the time axis. This
is not prevalence. Returns either a scalar, one value for all
subpopulations, or an array of shape |
required |
baseline_rt_process
|
TemporalProcess
|
Temporal process for baseline \(\mathcal{R}(t)\) dynamics |
required |
subpop_rt_deviation_process
|
TemporalProcess
|
Temporal process for subpopulation deviations |
required |
log_rt_time_0_rv
|
RandomVariable
|
Starting log(\(\mathcal{R}(t)\)) on the first day of the
initialization period. Returns either a scalar, one value for all
subpopulations, or an array of shape |
required |
infection_feedback_strength_rv
|
RandomVariable | None
|
Infection feedback strength \(\gamma\). Returns an array that
broadcasts to
A 1-D array is read as one strength per subpopulation, so a
strength that varies by day must have shape
|
None
|
infection_feedback_pmf_rv
|
RandomVariable | None
|
Feedback PMF \(f\), which weights recent infections in the feedback
factor. Element 0 weights infections on the previous day. Must have
the same length as the generation interval. Give together with
|
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If required parameters are missing or invalid, or if only one of the two infection feedback arguments is given. |
Source code in pyrenew/latent/subpopulation_infections.py
443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | |
TemporalProcess
Bases: Protocol
Protocol for temporal processes generating time-varying parameters.
Used for jurisdiction-level Rt dynamics, subpopulation deviations, or allocation trajectories. All processes return 2D arrays of shape (n_timepoints, n_processes) for consistent handling.
Attributes:
| Name | Type | Description |
|---|---|---|
step_size |
int
|
Number of consecutive timepoints that share the same sampled value.
Defaults to |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "temporal",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample temporal trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Per-process starting value or initial-location parameter. Processes
with a deterministic initial state return this value at the first
timepoint. |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample site names to avoid collisions |
'temporal'
|
first_day_dow
|
int | None
|
Day of week for element 0 of the shared model time axis (0=Monday, ..., 6=Sunday). Standard temporal processes ignore this value; calendar-aligned wrappers may use it. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
WeeklyTemporalProcess
WeeklyTemporalProcess(inner: TemporalProcess, start_dow: int)
Bases: TemporalProcess
Parameterize an inner temporal process at a calendar-week cadence.
Each output timepoint in the same calendar week shares a single sampled value from the inner process. Use when a parameter should be estimated once per week while downstream model components still need one value per evaluation timepoint. For example, a weekly-parameterized R(t) process can return daily R(t) values for a daily deterministic renewal equation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
start_dow
|
int
|
Day-of-week on which the calendar-week cycle begins
(0=Monday, 6=Sunday, ISO convention). Use |
required |
Initialize weekly temporal process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
start_dow
|
int
|
Day-of-week on which the calendar-week cycle begins (0=Monday, 6=Sunday, ISO convention). |
required |
Source code in pyrenew/latent/temporal_processes.py
867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
883 884 885 886 887 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "weekly",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample weekly trajectory from inner process and broadcast.
Computes the number of weekly time steps needed for the configured
calendar-week cycle, samples the inner process at that cadence, then
broadcasts each weekly value to the per-timepoint axis and trims to
n_timepoints. The returned value always has one row per evaluation
timepoint, regardless of the inner parameter cadence. The weekly
trajectory is recorded as a NumPyro deterministic site named
"{name_prefix}_weekly".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of per-timepoint outputs to produce. |
required |
initial_value
|
float | ArrayLike | None
|
Initial value(s) for the inner process. Defaults to 0.0. |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites; forwarded to the inner process. |
'weekly'
|
first_day_dow
|
int | None
|
Day of week for element 0 of the shared model time axis (0=Monday, ..., 6=Sunday). Required. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape |
Source code in pyrenew/latent/temporal_processes.py
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 | |
compute_infections_from_rt
compute_infections_from_rt(
I0: ArrayLike, Rt: ArrayLike, reversed_generation_interval_pmf: ArrayLike
) -> ndarray
Generate infections according to a renewal process with a time-varying reproduction number \(\mathcal{R}(t)\)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I0
|
ArrayLike
|
Array of initial infections of the same length as the generation interval pmf vector. |
required |
Rt
|
ArrayLike
|
Timeseries of \(\mathcal{R}(t)\) values |
required |
reversed_generation_interval_pmf
|
ArrayLike
|
discrete probability mass vector representing the generation interval of the infection process, where the final entry represents an infection 1 time unit in the past, the second-to-last entry represents an infection two time units in the past, etc. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
The timeseries of infections. |
Source code in pyrenew/latent/infection_functions.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
compute_infections_from_rt_with_feedback
compute_infections_from_rt_with_feedback(
I0: ArrayLike,
Rt_raw: ArrayLike,
infection_feedback_strength: ArrayLike,
reversed_generation_interval_pmf: ArrayLike,
reversed_infection_feedback_pmf: ArrayLike,
) -> tuple
Generate infections according to
a renewal process with infection
feedback (generalizing Asher 2018
<https://doi.org/10.1016/j.epidem.2017.02.009>_).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I0
|
ArrayLike
|
Array of initial infections of the same length as the generation interval pmf vector. |
required |
Rt_raw
|
ArrayLike
|
Timeseries of raw \(\mathcal{R}(t)\) values not adjusted by infection feedback |
required |
infection_feedback_strength
|
ArrayLike
|
Strength of the infection feedback. Either a scalar (constant feedback strength in time) or a vector representing the infection feedback strength at a given point in time. |
required |
reversed_generation_interval_pmf
|
ArrayLike
|
discrete probability mass vector representing the generation interval of the infection process, where the final entry represents an infection 1 time unit in the past, the second-to-last entry represents an infection two time units in the past, etc. |
required |
reversed_infection_feedback_pmf
|
ArrayLike
|
discrete probability mass vector representing the infection feedback process, where the final entry represents the relative contribution to infection feedback from infections that occurred 1 time unit in the past, the second-to-last entry represents the contribution from infections that occurred 2 time units in the past, etc. |
required |
Returns:
| Type | Description |
|---|---|
tuple
|
A tuple |
Notes
This function implements the following renewal process:
where \(\mathcal{R}(t)\) is the reproductive number, \(\gamma(t)\) is the infection feedback strength, \(T_g\) is the max-length of the generation interval, \(\mathcal{R}^u(t)\) is the raw reproduction number, \(f(t)\) is the infection feedback pmf, and \(T_f\) is the max-length of the infection feedback pmf.
Note that negative \(\gamma(t)\) implies that recent incident infections reduce \(\mathcal{R}(t)\) below its raw value in the absence of feedback, while positive \(\gamma\) implies that recent incident infections increase \(\mathcal{R}(t)\) above its raw value, and \(\gamma(t)=0\) implies no feedback.
In general, negative \(\gamma\) is the more common modeling choice, as it can be used to model susceptible depletion, reductions in contact rate due to awareness of high incidence, et cetera.
Source code in pyrenew/latent/infection_functions.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
compute_infections_from_rt_with_mobility
compute_infections_from_rt_with_mobility(
I0: ArrayLike,
Rt_raw: ArrayLike,
reversed_generation_interval_pmf: ArrayLike,
mobility_matrix: ArrayLike,
subpop_fractions: ArrayLike,
susceptible_depletion: bool = True,
) -> tuple[ndarray, ndarray]
Generate infections from a renewal process coupled by a fixed mobility matrix.
Residents of each home region spend part of each day at other locations. Transmission happens at each location, at that location's reproduction number, among the people present there. Each infection is assigned to the home region of the person infected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I0
|
ArrayLike
|
New infections per resident on each day of the initialization
period, shape |
required |
Rt_raw
|
ArrayLike
|
Finite, non-negative reproduction number at each location on each
day after the initialization period, shape |
required |
reversed_generation_interval_pmf
|
ArrayLike
|
Generation interval PMF in reverse order: the last entry is one day back, the second-to-last two days back, and so on. |
required |
mobility_matrix
|
ArrayLike
|
Matrix used on every day, shape |
required |
subpop_fractions
|
ArrayLike
|
Each home region's share of the total population, shape |
required |
susceptible_depletion
|
bool
|
If True (default), new infections among residents of each region are scaled by, and capped at, the fraction of those residents not yet infected. If False, neither adjustment is applied. |
True
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
New infections per resident, shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If concrete |
Notes
This implements Equation 2 of Roy, Clapham, and Mishra (2025), https://doi.org/10.1371/journal.pcbi.1013642. In infection counts (before converting to infections per resident and applying the incidence ceiling), the equation is:
where \(m_{jk}\) is mobility_matrix[j, k], \(N_k\) is the number of
residents of region \(k\), \(R_{t,j}\) is the reproduction number at
location \(j\), \(g\) is the generation interval, and \(S_{t,i}\) is the
number of residents of region \(i\) not infected before day \(t\).
With M = mobility_matrix and p = subpop_fractions, one day with
depletion enabled is:
present = M @ p
share_present = M * p[None, :] / jnp.where(present > 0, present, 1.0)[:, None]
infectiousness = reversed_generation_interval_pmf @ history
susceptible = 1.0 - cumulative
new_infections_raw = M.T @ (rt * (share_present @ infectiousness))
new_infections = jnp.minimum(susceptible * new_infections_raw, susceptible)
share_present[j, k] is the share of the people present at location
j who live in region k. cumulative counts every day of
I0 and every earlier day of the result.
A location with no one present contributes no infections. With depletion enabled, its adjusted reproduction number is 0.
The incidence ceiling is an addition to Roy et al.'s Equation 2. With valid initialization, it keeps cumulative infections at most 1 per resident, so the susceptible fraction needs no floor. Without depletion, cumulative infections may exceed 1 per resident.
Source code in pyrenew/latent/infection_functions.py
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | |
logistic_susceptibility_adjustment
logistic_susceptibility_adjustment(
I_raw_t: float, frac_susceptible: float, n_population: float
) -> float
Apply the logistic susceptibility
adjustment to a potential new
incidence I_raw_t proposed in
equation 6 of Bhatt et al 2023
<https://doi.org/10.1093/jrsssa/qnad030>_.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
I_raw_t
|
float
|
The "unadjusted" incidence at time t, i.e. the incidence given an infinite number of available susceptible individuals. |
required |
frac_susceptible
|
float
|
fraction of remaining susceptible individuals in the population |
required |
n_population
|
float
|
Total size of the population. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The adjusted value of \(I(t)\). |
Source code in pyrenew/latent/infection_functions.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
Temporal Processes
Temporal processes for latent infection models.
Provides time-series processes for modeling Rt dynamics and subpopulation
deviations in hierarchical infection models. All processes return 2D arrays
of shape (n_timepoints, n_processes) through a unified TemporalProcess
protocol.
Relationship to pyrenew.process:
This module provides high-level, domain-specific wrappers around the low-level building blocks in pyrenew.process. The key differences:
| Aspect | pyrenew.process |
pyrenew.latent.temporal_processes |
|---|---|---|
| Abstraction level | Low-level composable primitives | High-level domain-specific API |
| Interface | Varied signatures per class | Unified TemporalProcess protocol |
| Target use | General time-series modeling | Rt dynamics, hierarchical infections |
| Vectorization | Caller manages array shapes | Automatic via n_processes parameter |
| Validation | Minimal constraints | Validates positive innovation_sd |
AR1, DifferencedAR1, and RandomWalk expose a common public
interface for two equivalent parameterizations. The "innovation"
parameterization is non-centered: it samples independent standardized
innovations and constructs the state trajectory deterministically using the
lower-level pyrenew.process implementations. The "state"
parameterization is centered: it samples each state conditionally on the
preceding state using a local NumPyro scan.
This implementation asymmetry is intentional. The existing pyrenew.process abstractions naturally represent innovation-driven processes. State-centered transitions remain local to the public temporal processes so that the state itself is the scanned NumPyro sample site, which supports replaying a fitted trajectory and extending it during posterior prediction.
When to use which:
-
Use
pyrenew.processclasses (ARProcess,DifferencedProcess,RandomWalk) when building novel statistical models or when you need fine-grained control over array shapes and numpyro sampling semantics. -
Use this module's classes (
AR1,DifferencedAR1,RandomWalk) when modeling Rt trajectories in hierarchical infection models. These provide a consistent interface, automatic vectorization, and enforce epidemiologically-sensible constraints.
Temporal processes provided:
AR1: Autoregressive process with mean reversion. Keeps Rt bounded near a baseline. Wraps pyrenew.process.ARProcess.DifferencedAR1: AR(1) on first differences. Allows persistent trends while stabilizing the growth rate. Wraps pyrenew.process.DifferencedProcess.RandomWalk: No mean reversion. Rt can drift without bound. Wraps pyrenew.process.RandomWalk.StepwiseTemporalProcess: Wrapper that parameterizes any innerTemporalProcessat a coarser model-index cadence and broadcasts to the per-timepoint scale by repetition.WeeklyTemporalProcess: Wrapper that parameterizes any innerTemporalProcessat a calendar-week cadence and broadcasts to the per-timepoint scale by repetition.
All implementations satisfy the TemporalProcess protocol and can be
used interchangeably in hierarchical infection models.
AR1
AR1(
autoreg_rv: RandomVariable,
innovation_sd_rv: RandomVariable,
parameterization: Parameterization = "innovation",
)
Bases: TemporalProcess
AR(1) process.
Each value depends on the previous value plus noise, with reversion toward a mean level. Keeps Rt bounded near a baseline — values that drift away are "pulled back" over time.
The parameterization argument selects between a non-centered
"innovation" parameterization, which samples independent standardized
innovations, and a centered "state" parameterization, which samples
each state conditionally on the preceding state. Both produce the same
prior distribution over the state path but can have different posterior
sampling geometry.
The innovation branch uses pyrenew.process.ARProcess to construct the trajectory from sampled innovations. The state branch uses local scanned conditional transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of noise at each time step. Larger values produce more volatile trajectories; smaller values produce smoother ones. |
required |
parameterization
|
Parameterization
|
Which latent object to sample: |
'innovation'
|
Initialize AR(1) process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of innovations. |
required |
parameterization
|
Parameterization
|
|
'innovation'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If autoreg_rv or innovation_sd_rv are not RandomVariable instances |
ValueError
|
If innovation_sd_rv is a DeterministicVariable with any value <= 0, or if parameterization is not a recognized string |
Source code in pyrenew/latent/temporal_processes.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
278 279 280 281 282 283 284 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "ar1",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample AR(1) trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Mean of the initial-state prior. The first returned value is sampled
as |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites |
'ar1'
|
first_day_dow
|
int | None
|
Unused. See pyrenew.latent.TemporalProcess. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
DifferencedAR1
DifferencedAR1(
autoreg_rv: RandomVariable,
innovation_sd_rv: RandomVariable,
parameterization: Parameterization = "innovation",
)
Bases: TemporalProcess
AR(1) process on first differences.
Each change in value depends on the previous change plus noise, with the rate of change reverting toward a mean. Unlike AR(1), this allows Rt to trend persistently upward or downward while the growth rate stabilizes.
The parameterization argument selects between a non-centered
"innovation" parameterization, which samples independent standardized
innovations on the differences, and a centered "state"
parameterization, which samples the state path
\([x_1, \ldots, x_{T-1}]\) conditionally under the priors
where \(\phi\) is autoreg and \(\sigma\) is innovation_sd. The initial
state \(x_0\) is supplied deterministically as initial_value. Both produce
the same prior over the state path but can have different posterior
sampling geometry.
The innovation branch uses pyrenew.process.DifferencedProcess with pyrenew.process.ARProcess as its fundamental process. The state branch uses local scanned conditional transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient for differences. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of noise added to changes. Larger values produce more erratic growth rates; smaller values produce smoother trends. |
required |
parameterization
|
Parameterization
|
Which latent object to sample: |
'innovation'
|
Initialize differenced AR(1) process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
autoreg_rv
|
RandomVariable
|
RandomVariable that returns the autoregressive coefficient for differences. For stationarity, |autoreg| < 1, but this is not enforced (use priors to constrain if needed). |
required |
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of innovations. |
required |
parameterization
|
Parameterization
|
|
'innovation'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If autoreg_rv or innovation_sd_rv are not RandomVariable instances |
ValueError
|
If innovation_sd_rv is a DeterministicVariable with any value <= 0, or if parameterization is not a recognized string |
Source code in pyrenew/latent/temporal_processes.py
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
463 464 465 466 467 468 469 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "diff_ar1",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample differenced AR(1) trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Deterministic first state of the trajectory. Scalar values are
broadcast to all processes; arrays must have shape
|
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites |
'diff_ar1'
|
first_day_dow
|
int | None
|
Unused. See pyrenew.latent.TemporalProcess. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | |
RandomWalk
RandomWalk(
innovation_sd_rv: RandomVariable,
parameterization: Parameterization = "innovation",
)
Bases: TemporalProcess
Random walk process for log(Rt).
Each value equals the previous value plus noise, with no reversion toward a mean. Allows Rt to drift without bound — suitable when you have no prior expectation that Rt will return to a baseline.
The parameterization argument selects between a non-centered
"innovation" parameterization, which samples independent standardized
innovations, and a centered "state" parameterization, which samples
each state conditionally on the preceding state. The initial state
x[0] = initial_value is deterministic. Both parameterizations produce
the same prior over the state path but can have different posterior
sampling geometry.
The innovation branch uses pyrenew.process.RandomWalk to construct the trajectory from sampled innovations. The state branch uses local scanned conditional transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of noise at each time step. Larger values produce faster drift; smaller values produce more gradual changes. |
required |
parameterization
|
Parameterization
|
Which latent object to sample: |
'innovation'
|
Notes
Unlike AR(1), variance grows over time — the process can wander arbitrarily far from its starting point. For long time horizons, consider AR(1) if you want Rt to stay bounded near a baseline.
Initialize random walk process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
innovation_sd_rv
|
RandomVariable
|
RandomVariable that returns the standard deviation of innovations. |
required |
parameterization
|
Parameterization
|
|
'innovation'
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If innovation_sd_rv is not a RandomVariable instance |
ValueError
|
If innovation_sd_rv is a DeterministicVariable with any value <= 0, or if parameterization is not a recognized string |
Source code in pyrenew/latent/temporal_processes.py
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
635 636 637 638 639 640 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "rw",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample random walk trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Deterministic first state of the trajectory. Scalar values are
broadcast to all processes; arrays must have shape
|
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites |
'rw'
|
first_day_dow
|
int | None
|
Unused. See pyrenew.latent.TemporalProcess. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 | |
StepwiseTemporalProcess
StepwiseTemporalProcess(inner: TemporalProcess, step_size: int)
Bases: TemporalProcess
Parameterize an inner temporal process at a coarser cadence and broadcast to the per-timepoint scale by model-index repetition.
Each step_size consecutive output timepoints share a single sampled
value from the inner process. Use when a parameter should be estimated at
a coarser cadence while downstream model components still need one value
per evaluation timepoint. Blocks always start at output index 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
step_size
|
int
|
Number of per-timepoint units that share each inner sample. Must be a positive integer. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Initialize stepwise temporal process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
step_size
|
int
|
Number of per-timepoint units that share each inner sample. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in pyrenew/latent/temporal_processes.py
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
774 775 776 777 778 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "stepwise",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample coarse trajectory from inner process and broadcast.
Computes the number of coarse time steps needed for the requested
length, samples the inner process at that cadence, then broadcasts each
coarse value to the per-timepoint axis and trims to n_timepoints.
The returned value always has one row per evaluation timepoint,
regardless of the inner parameter cadence. The coarse
trajectory is recorded as a NumPyro deterministic site named
"{name_prefix}_coarse".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of per-timepoint outputs to produce. |
required |
initial_value
|
float | ArrayLike | None
|
Initial value(s) for the inner process. Defaults to 0.0. |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites; forwarded to the inner process. |
'stepwise'
|
first_day_dow
|
int | None
|
Ignored. Accepted for compatibility with the
|
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape |
Source code in pyrenew/latent/temporal_processes.py
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | |
TemporalProcess
Bases: Protocol
Protocol for temporal processes generating time-varying parameters.
Used for jurisdiction-level Rt dynamics, subpopulation deviations, or allocation trajectories. All processes return 2D arrays of shape (n_timepoints, n_processes) for consistent handling.
Attributes:
| Name | Type | Description |
|---|---|---|
step_size |
int
|
Number of consecutive timepoints that share the same sampled value.
Defaults to |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "temporal",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample temporal trajectory or trajectories.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of time points to generate |
required |
initial_value
|
float | ArrayLike | None
|
Per-process starting value or initial-location parameter. Processes
with a deterministic initial state return this value at the first
timepoint. |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample site names to avoid collisions |
'temporal'
|
first_day_dow
|
int | None
|
Day of week for element 0 of the shared model time axis (0=Monday, ..., 6=Sunday). Standard temporal processes ignore this value; calendar-aligned wrappers may use it. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape (n_timepoints, n_processes) |
Source code in pyrenew/latent/temporal_processes.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
WeeklyTemporalProcess
WeeklyTemporalProcess(inner: TemporalProcess, start_dow: int)
Bases: TemporalProcess
Parameterize an inner temporal process at a calendar-week cadence.
Each output timepoint in the same calendar week shares a single sampled value from the inner process. Use when a parameter should be estimated once per week while downstream model components still need one value per evaluation timepoint. For example, a weekly-parameterized R(t) process can return daily R(t) values for a daily deterministic renewal equation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
start_dow
|
int
|
Day-of-week on which the calendar-week cycle begins
(0=Monday, 6=Sunday, ISO convention). Use |
required |
Initialize weekly temporal process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner
|
TemporalProcess
|
Inner |
required |
start_dow
|
int
|
Day-of-week on which the calendar-week cycle begins (0=Monday, 6=Sunday, ISO convention). |
required |
Source code in pyrenew/latent/temporal_processes.py
867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 | |
__repr__
__repr__() -> str
Return string representation.
Source code in pyrenew/latent/temporal_processes.py
883 884 885 886 887 | |
sample
sample(
n_timepoints: int,
initial_value: float | ArrayLike | None = None,
n_processes: int = 1,
name_prefix: str = "weekly",
*,
first_day_dow: int | None = None,
) -> ArrayLike
Sample weekly trajectory from inner process and broadcast.
Computes the number of weekly time steps needed for the configured
calendar-week cycle, samples the inner process at that cadence, then
broadcasts each weekly value to the per-timepoint axis and trims to
n_timepoints. The returned value always has one row per evaluation
timepoint, regardless of the inner parameter cadence. The weekly
trajectory is recorded as a NumPyro deterministic site named
"{name_prefix}_weekly".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_timepoints
|
int
|
Number of per-timepoint outputs to produce. |
required |
initial_value
|
float | ArrayLike | None
|
Initial value(s) for the inner process. Defaults to 0.0. |
None
|
n_processes
|
int
|
Number of parallel processes. |
1
|
name_prefix
|
str
|
Prefix for numpyro sample sites; forwarded to the inner process. |
'weekly'
|
first_day_dow
|
int | None
|
Day of week for element 0 of the shared model time axis (0=Monday, ..., 6=Sunday). Required. |
None
|
Returns:
| Type | Description |
|---|---|
ArrayLike
|
Trajectories of shape |
Source code in pyrenew/latent/temporal_processes.py
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 | |