API reference

Core objects

The main public objects are imported from the top-level package:

from demovuln import (
    MatrixPopulationModel,
    PerturbationGrid,
    simulate_dynamics,
    run_grid,
    population_reduction,
    compute_vulnerability,
)

Models

demovuln.models.dominant_eigenvalue(A)[source]

Return the asymptotic growth rate of a projection matrix.

Parameters:

A (array_like of shape (n_stages, n_stages)) – Non-negative projection matrix. Columns represent source stages at one projection interval and rows represent destination stages at the next projection interval.

Returns:

Dominant eigenvalue of A, corresponding to the asymptotic population growth rate under the unperturbed linear dynamics.

Return type:

float

Raises:

ValueError – If A is not a finite, square, non-negative matrix or if the dominant eigenvalue is not positive.

demovuln.models.stable_stage_distribution(A)[source]

Return the stable stage distribution of a projection matrix.

Parameters:

A (array_like of shape (n_stages, n_stages)) – Non-negative projection matrix.

Returns:

Dominant right eigenvector of A, normalized to sum to one.

Return type:

numpy.ndarray of shape (n_stages,)

Notes

For irreducible non-negative projection matrices, the normalized dominant right eigenvector gives the asymptotic distribution of individuals among stages. The returned vector is used as the default initial condition in simulation routines.

class demovuln.models.MatrixPopulationModel(A, fecundity_mask=None, fecundity_rows=(0,), adult_stages=None, juvenile_stages=None, name=None)[source]

Bases: object

Matrix population model with explicit demographic target definitions.

Parameters:
  • A (array_like of shape (n_stages, n_stages)) – Projection matrix defining transitions and reproductive contributions over one projection interval. Columns are source stages at time t; rows are destination stages at time t + 1.

  • fecundity_mask (array_like of bool, optional) – Boolean matrix identifying entries interpreted as fecundity or newborn production. If omitted, non-zero entries in fecundity_rows are used.

  • fecundity_rows (tuple of int, default=(0,)) – Row indices corresponding to newborn or reproductive-output classes. By default, fecundity is inferred from non-zero entries in the first row.

  • adult_stages (iterable of int, optional) – Column indices corresponding to source stages classified as adult or reproductive. If omitted together with juvenile_stages, adult stages are inferred as columns contributing to at least one fecundity entry.

  • juvenile_stages (iterable of int, optional) – Column indices corresponding to source stages classified as juvenile or pre-reproductive. If omitted, juvenile stages are inferred as all stages not classified as adult.

  • name (str, optional) – Optional label for the model, population or species.

Notes

The projection matrix is stored internally as a NumPy array. The model also stores inferred or user-defined demographic masks identifying fecundity entries, adult source stages, juvenile source stages, and the dominant eigenvalue of the unperturbed projection matrix.

Stage indices are zero-based, following Python indexing.

property matrix: ndarray

Return a copy of the projection matrix.

property n_stages: int

Number of stages or classes in the projection matrix.

property fecundity_element_mask: ndarray

Boolean matrix selecting fecundity entries.

property adult_stage_mask: ndarray

Boolean vector selecting adult or reproductive source stages.

property juvenile_stage_mask: ndarray

Boolean vector selecting juvenile or pre-reproductive source stages.

property lambda_: float

Dominant eigenvalue of the unperturbed projection matrix.

stable_distribution()[source]

Return the stable stage distribution of the model.

Return type:

ndarray

Perturbations

demovuln.perturbations.build_target_mask(model, target, *, survival_affects_fecundity=True, custom_mask=None)[source]

Construct the matrix-entry mask associated with a perturbation target.

Parameters:
  • model (MatrixPopulationModel) – Matrix population model defining the projection matrix and the mapping between matrix entries and demographic components.

  • target ({"adult_survival", "juvenile_survival", "fecundity", "all", "custom"}) – Demographic component to perturb. Survival targets are defined by source-stage columns; fecundity targets are defined by model.fecundity_element_mask.

  • survival_affects_fecundity (bool, default=True) – If True, survival perturbations applied to adult or juvenile source stages scale the full source-stage column, including fecundity entries. If False, fecundity entries are excluded from survival targets.

  • custom_mask (array_like of bool, optional) – Boolean matrix selecting entries to perturb when target="custom". It must have the same shape as the projection matrix.

Returns:

Boolean matrix with True at entries affected by the perturbation.

Return type:

numpy.ndarray of bool

Raises:

ValueError – If target="custom" is used without a valid custom_mask, or if target is not recognized.

demovuln.perturbations.apply_perturbation(model, target, magnitude, *, survival_affects_fecundity=True, custom_mask=None)[source]

Apply a multiplicative demographic perturbation to a projection matrix.

Parameters:
  • model (MatrixPopulationModel) – Matrix population model defining the unperturbed projection matrix and demographic target definitions.

  • target ({"adult_survival", "juvenile_survival", "fecundity", "all", "custom"}) – Demographic component affected by the perturbation.

  • magnitude (float) – Proportional reduction applied to the selected entries. A value of 0 leaves the matrix unchanged, whereas 1 sets the selected entries to zero.

  • survival_affects_fecundity (bool, default=True) – If True, survival perturbations scale whole source-stage columns, including fecundity entries. This represents perturbations acting on the contribution of individuals in a source stage. If False, fecundity entries are not modified by survival targets.

  • custom_mask (array_like of bool, optional) – Boolean matrix selecting entries to perturb when target="custom".

Returns:

Perturbed projection matrix.

Return type:

numpy.ndarray

Notes

The perturbation is implemented as a_ij -> (1 - m) a_ij for selected entries, where m is magnitude. For target="all" with survival_affects_fecundity=True, fecundity entries receive two multiplicative reductions, (1 - m)^2, representing simultaneous effects on reproductive output and on the survival or availability of reproductive source stages.

Simulation

class demovuln.simulation.SimulationResult(abundance, baseline_abundance, stage_vectors, baseline_stage_vectors, reduction, final_population, baseline_final_population, magnitude, duration, period, target)[source]

Bases: object

Result of a single temporally structured perturbation simulation.

Parameters:
  • abundance (ndarray)

  • baseline_abundance (ndarray)

  • stage_vectors (ndarray | None)

  • baseline_stage_vectors (ndarray | None)

  • reduction (float)

  • final_population (float)

  • baseline_final_population (float)

  • magnitude (float)

  • duration (int)

  • period (int)

  • target (str)

abundance

Total population size through time under the perturbed dynamics. The first element corresponds to the initial state.

Type:

numpy.ndarray

baseline_abundance

Total population size through time under the unperturbed baseline dynamics, evaluated over the same time horizon.

Type:

numpy.ndarray

stage_vectors

Stage-vector trajectory under the perturbed dynamics. Returned only when return_stage_vectors=True.

Type:

numpy.ndarray or None

baseline_stage_vectors

Stage-vector trajectory under the unperturbed baseline dynamics. Returned only when return_stage_vectors=True.

Type:

numpy.ndarray or None

reduction

Percent population reduction at the final time step, measured relative to the unperturbed baseline trajectory.

Type:

float

final_population

Final total population size under the perturbed dynamics.

Type:

float

baseline_final_population

Final total population size under the unperturbed baseline dynamics.

Type:

float

magnitude

Proportional reduction used in the perturbation.

Type:

float

duration

Number of consecutive projection intervals during which each perturbation event was active.

Type:

int

period

Number of projection intervals between consecutive perturbation onsets.

Type:

int

target

Demographic component affected by the perturbation.

Type:

str

demovuln.simulation.population_reduction(final_population, baseline_final_population)[source]

Compute percent population reduction relative to a baseline trajectory.

Parameters:
  • final_population (float) – Final population size under the perturbed dynamics.

  • baseline_final_population (float) – Final population size under the unperturbed baseline dynamics evaluated over the same time horizon.

Returns:

Percent population reduction, defined as 100 * (1 - final_population / baseline_final_population).

Return type:

float

Raises:

ValueError – If baseline_final_population is not positive.

demovuln.simulation.simulate_dynamics(model, *, target='adult_survival', magnitude, duration, period, t_max, recovery_steps=0, start=0, initial_state=None, normalize_by_lambda=True, survival_affects_fecundity=True, custom_mask=None, return_stage_vectors=False, force_during_recovery=False)[source]

Simulate a population trajectory under a demographic perturbation regime.

Parameters:
  • model (MatrixPopulationModel or array_like of shape (n_stages, n_stages)) – Unperturbed matrix population model. If a raw matrix is supplied, it is converted to MatrixPopulationModel using the default target definitions.

  • target ({"adult_survival", "juvenile_survival", "fecundity", "all", "custom"}, default="adult_survival") – Demographic component affected by the perturbation.

  • magnitude (float) – Proportional reduction applied to the selected entries. Values must lie in the interval [0, 1].

  • duration (int) – Number of consecutive projection intervals during which each perturbation event is active. A value of 0 produces no perturbation.

  • period (int) – Number of projection intervals between the onset of consecutive perturbation events. Must be greater than or equal to duration.

  • t_max (int) – Number of projection intervals in the perturbation-forcing window.

  • recovery_steps (int, default=0) – Number of additional unperturbed projection intervals after the forcing window.

  • start (int, default=0) – Projection interval at which the first perturbation event starts.

  • initial_state (array_like of shape (n_stages,), optional) – Initial population vector. If omitted, the stable stage distribution of the unperturbed model is used. If supplied, the vector is normalized to unit total abundance.

  • normalize_by_lambda (bool, default=True) – If True, divide both the baseline and perturbed projection matrices by the dominant eigenvalue of the unperturbed matrix. This makes abundance trajectories relative to the asymptotic growth of the unperturbed model.

  • survival_affects_fecundity (bool, default=True) – If True, survival perturbations scale whole source-stage columns, including fecundity entries. If False, fecundity entries are excluded from adult- and juvenile-survival perturbations.

  • custom_mask (array_like of bool, optional) – Boolean matrix selecting entries to perturb when target="custom".

  • return_stage_vectors (bool, default=False) – If True, store the full stage-vector trajectory for both perturbed and baseline dynamics.

  • force_during_recovery (bool, default=False) – If True, scheduled perturbation events continue during the recovery window. If False, recovery steps use the unperturbed matrix.

Returns:

Object containing abundance trajectories, optional stage-vector trajectories, final abundances and percent population reduction.

Return type:

SimulationResult

Notes

Population reduction is measured against the unperturbed baseline trajectory at the same final time step. This separates the effect of the perturbation regime from the intrinsic growth or decline of the unperturbed projection matrix.

Vulnerability

class demovuln.vulnerability.PerturbationGrid(magnitudes, durations, periods)[source]

Bases: object

Discrete perturbation space used for vulnerability calculations.

Parameters:
  • magnitudes (iterable of float) – Proportional reductions applied to the selected demographic component. Values must lie in the interval [0, 1].

  • durations (iterable of int) – Number of consecutive projection intervals during which each perturbation event is active.

  • periods (iterable of int) – Number of projection intervals between the onset of consecutive perturbation events.

Notes

The package represents recurrence using period rather than frequency because simulations are performed in discrete projection intervals. Grids can also be constructed from event frequencies with from_frequencies().

classmethod from_frequencies(*, magnitudes, durations, frequencies, generation_time=1.0, rounding='nearest')[source]

Create a perturbation grid from event frequencies.

Parameters:
  • magnitudes (iterable of float) – Proportional reductions applied to the selected demographic component.

  • durations (iterable of int) – Number of consecutive projection intervals during which each event is active.

  • frequencies (iterable of float) – Event frequencies, interpreted as the number of events per generation_time projection intervals.

  • generation_time (float, default=1.0) – Number of projection intervals defining the reference time unit for frequencies. For example, if frequencies are specified as events per generation, this should be the generation time expressed in projection intervals.

  • rounding ({"nearest", "floor", "ceil"}, default="nearest") – Rule used to convert non-integer recurrence periods into integer projection intervals.

Returns:

Grid with recurrence periods computed as period = generation_time / frequency.

Return type:

PerturbationGrid

Notes

Rounded duplicate periods are removed. The minimum period is one projection interval.

scenarios(*, skip_infeasible=True)[source]

Iterate over perturbation scenarios in the grid.

Parameters:

skip_infeasible (bool, default=True) – If True, omit regimes where duration > period. If False, yield these regimes with feasible=False.

Yields:

tuple – Tuple (magnitude, duration, period, feasible).

class demovuln.vulnerability.GridResult(table, trajectories=<factory>)[source]

Bases: object

Result of a perturbation-grid simulation.

Parameters:
  • table (DataFrame)

  • trajectories (dict[tuple[float, int, int], SimulationResult])

table

Long-format table with one row per perturbation regime. Standard columns include target, magnitude, duration, period, feasible, population_reduction, final_population and baseline_final_population.

Type:

pandas.DataFrame

trajectories

Dictionary mapping (magnitude, duration, period) tuples to SimulationResult objects. This dictionary is populated only when return_trajectories=True is used in run_grid().

Type:

dict

property vulnerability: float

Integrated vulnerability, computed as mean population reduction.

demovuln.vulnerability.compute_vulnerability(table, *, column='population_reduction')[source]

Compute integrated vulnerability from grid-simulation output.

Parameters:
  • table (pandas.DataFrame) – Long-format output table returned by run_grid().

  • column (str, default="population_reduction") – Name of the column containing percent population reduction values.

Returns:

Mean population reduction across perturbation regimes. Missing values are ignored, so infeasible regimes encoded as NaN do not contribute.

Return type:

float

Raises:

ValueError – If column is not present in table.

demovuln.vulnerability.run_grid(model, *, target, grid, t_max, recovery_steps=0, start=0, initial_state=None, normalize_by_lambda=True, survival_affects_fecundity=True, custom_mask=None, return_trajectories=False, skip_infeasible=True, force_during_recovery=False)[source]

Evaluate a perturbation grid and compute demographic vulnerability.

Parameters:
  • model (MatrixPopulationModel or array_like of shape (n_stages, n_stages)) – Unperturbed matrix population model.

  • target ({"adult_survival", "juvenile_survival", "fecundity", "all", "custom"}) – Demographic component affected by the perturbations.

  • grid (PerturbationGrid) – Discrete perturbation space, defined by magnitudes, durations and recurrence periods.

  • t_max (int) – Number of projection intervals in the perturbation-forcing window.

  • recovery_steps (int, default=0) – Number of additional unperturbed projection intervals after the forcing window.

  • start (int, default=0) – Projection interval at which the first perturbation event starts.

  • initial_state (array_like of shape (n_stages,), optional) – Initial population vector. If omitted, the stable stage distribution of the unperturbed model is used.

  • normalize_by_lambda (bool, default=True) – If True, divide baseline and perturbed projection matrices by the dominant eigenvalue of the unperturbed matrix.

  • survival_affects_fecundity (bool, default=True) – If True, survival perturbations scale whole source-stage columns, including fecundity entries.

  • custom_mask (array_like of bool, optional) – Boolean matrix selecting entries to perturb when target="custom".

  • return_trajectories (bool, default=False) – If True, store the full SimulationResult object for every feasible regime.

  • skip_infeasible (bool, default=True) – If True, omit regimes where duration > period. If False, retain them in the output table with feasible=False and missing response values.

  • force_during_recovery (bool, default=False) – If True, scheduled perturbation events continue during the recovery window.

Returns:

Object containing the full grid table and, optionally, individual simulation trajectories.

Return type:

GridResult

Notes

The integrated vulnerability metric is available as result.vulnerability and is computed as the mean percent population reduction across feasible perturbation regimes.