egttools.numerical.structure.NetworkMCEstimatorPC

class NetworkMCEstimatorPC(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, game: egttools.numerical.numerical_.games.AbstractSpatialGame, topology: collections.abc.Mapping[SupportsInt | SupportsIndex, collections.abc.Sequence[SupportsInt | SupportsIndex]], nb_strategies: SupportsInt | SupportsIndex, beta: SupportsFloat | SupportsIndex, mu: SupportsFloat | SupportsIndex, cache_size: SupportsInt | SupportsIndex = 100000)

Bases: pybind11_object

Monte Carlo estimator for evolutionary games on networks using the Pairwise Comparison update rule.

Provides gradient of selection, fixation probability, strategy distribution estimation, and trajectory generation. Uses OpenMP for parallel runs and an LRU cache for fitness memoization.

The network topology is stored as a contiguous adjacency list for O(1) neighbour lookup.

Construct a NetworkMCEstimator.

Parameters:
  • game (egttools.games.AbstractSpatialGame) – Spatial game used to evaluate node fitness.

  • topology (dict[int, list[int]]) – Network adjacency dictionary (e.g. from NetworkX G.adjacency()).

  • nb_strategies (int) – Number of distinct strategies.

  • beta (float) – Selection intensity.

  • mu (float) – Mutation probability per time step.

  • cache_size (int, optional) – Per-thread LRU fitness cache size (default 100000).

Methods

beta

calculate_gradient_of_selection

Numerically exact gradient of selection for the given per-node strategy assignment.

estimate_agos

Estimate the time-independent Average Gradient of Selection G^A(j).

estimate_agos_time_dependent

Estimate the time-dependent Average Gradient of Selection G^A(j, t).

estimate_fixation_probability

Estimate the fixation probability of a single invader in an otherwise resident population.

estimate_strategy_distribution

Estimate time-averaged strategy frequencies after the transitory period.

initialize

Overloaded function.

mean_population_state

Return strategy count vector (length = nb_strategies).

mu

nb_strategies

population_size

population_strategies

Return per-node strategy assignments as a list of integers (length = population_size).

run

Run a single trajectory and return aggregate strategy counts per generation.

run_snapshots

Run a trajectory and call callback(generation, population) at each snapshot.

set_beta

set_mu

step

Advance the session by one generation.

topology

__init__(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, game: egttools.numerical.numerical_.games.AbstractSpatialGame, topology: collections.abc.Mapping[SupportsInt | SupportsIndex, collections.abc.Sequence[SupportsInt | SupportsIndex]], nb_strategies: SupportsInt | SupportsIndex, beta: SupportsFloat | SupportsIndex, mu: SupportsFloat | SupportsIndex, cache_size: SupportsInt | SupportsIndex = 100000) None

Construct a NetworkMCEstimator.

Parameters:
  • game (egttools.games.AbstractSpatialGame) – Spatial game used to evaluate node fitness.

  • topology (dict[int, list[int]]) – Network adjacency dictionary (e.g. from NetworkX G.adjacency()).

  • nb_strategies (int) – Number of distinct strategies.

  • beta (float) – Selection intensity.

  • mu (float) – Mutation probability per time step.

  • cache_size (int, optional) – Per-thread LRU fitness cache size (default 100000).

__new__(**kwargs)
beta(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) float
calculate_gradient_of_selection(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, population: collections.abc.Sequence[SupportsInt | SupportsIndex]) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Numerically exact gradient of selection for the given per-node strategy assignment.

Parameters:

population (list[int]) – Strategy index for each node (length = population_size).

Returns:

Gradient vector of length nb_strategies.

Return type:

numpy.ndarray

estimate_agos(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, nb_runs: SupportsInt | SupportsIndex, nb_generations: SupportsInt | SupportsIndex, transitory: SupportsInt | SupportsIndex = 0, runs_per_j: SupportsInt | SupportsIndex = 0) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]']]

Estimate the time-independent Average Gradient of Selection G^A(j).

Runs independent trajectories; at each post-transitory generation computes the numerically exact gradient and bins the result by cooperator count j. OpenMP-parallelised over runs; per-thread caches prevent contention.

Parameters:
  • nb_runs (int) – Total trajectories when runs_per_j == 0 (random starts).

  • nb_generations (int) – Generations (each = N elementary steps) per trajectory.

  • transitory (int, optional) – Burn-in generations not counted (default 0).

  • runs_per_j (int, optional) – When > 0, uses the paper’s sampling scheme: for each initial cooperator count j0 ∈ {1, …, N-1} exactly runs_per_j trajectories are started with j0 cooperators on random nodes. Total runs = runs_per_j × (N-1); nb_runs is ignored. This gives uniform coverage of all j values.

Returns:

(mean_G, se_G) each of shape (N+1, nb_strategies). Row j holds the average/SE gradient at cooperator count j. Rows 0 and N are zero (absorbing states).

Return type:

tuple[numpy.ndarray, numpy.ndarray]

estimate_agos_time_dependent(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, nb_runs: SupportsInt | SupportsIndex, nb_generations: SupportsInt | SupportsIndex) tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]]

Estimate the time-dependent Average Gradient of Selection G^A(j, t).

Like estimate_agos but preserves the generation index, letting you study how the gradient landscape evolves from the initial transient to the stationary regime (e.g. Fig. 2 of Pinheiro et al. 2012).

Returns:

(mean_G_t, se_G_t) each of shape (nb_generations, N+1, nb_strategies). mean_G_t[t, j, k] is the mean gradient of strategy k at generation t and cooperator count j.

Return type:

tuple[numpy.ndarray, numpy.ndarray]

estimate_fixation_probability(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, invader: SupportsInt | SupportsIndex, resident: SupportsInt | SupportsIndex, nb_runs: SupportsInt | SupportsIndex, nb_generations: SupportsInt | SupportsIndex) float

Estimate the fixation probability of a single invader in an otherwise resident population.

Parameters:
  • invader (int)

  • resident (int)

  • nb_runs (int)

  • nb_generations (int) – Maximum time-steps per trial.

Returns:

Estimated fixation probability in [0, 1].

Return type:

float

estimate_strategy_distribution(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, nb_runs: SupportsInt | SupportsIndex, nb_generations: SupportsInt | SupportsIndex, transitory: SupportsInt | SupportsIndex, tolerance: SupportsFloat | SupportsIndex = 0.0, check_every: SupportsInt | SupportsIndex = 0) tuple[Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']]

Estimate time-averaged strategy frequencies after the transitory period.

Returns:

(mean_frequencies, standard_errors), each of length nb_strategies.

Return type:

tuple[numpy.ndarray, numpy.ndarray]

initialize(*args, **kwargs)

Overloaded function.

  1. initialize(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, init_state: typing.Annotated[numpy.typing.ArrayLike, numpy.uint64, “[m, 1]”]) -> None

Initialise a manual-stepping session with the given strategy counts.

Parameters:

init_state (numpy.ndarray) – Strategy count vector of length nb_strategies; sum must equal population_size.

  1. initialize(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) -> None

Initialise a manual-stepping session with a uniformly random strategy assignment.

mean_population_state(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) Annotated[numpy.typing.NDArray[numpy.uint64], '[m, 1]']

Return strategy count vector (length = nb_strategies).

mu(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) float
nb_strategies(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) int
population_size(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) int
population_strategies(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) list[int]

Return per-node strategy assignments as a list of integers (length = population_size).

run(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, nb_generations: SupportsInt | SupportsIndex, transitory: SupportsInt | SupportsIndex, init_state: Annotated[numpy.typing.ArrayLike, numpy.uint64, '[m, 1]']) Annotated[numpy.typing.NDArray[numpy.uint64], '[m, n]']

Run a single trajectory and return aggregate strategy counts per generation.

Returns:

Matrix of shape (nb_generations - transitory, nb_strategies).

Return type:

numpy.ndarray

run_snapshots(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, nb_generations: SupportsInt | SupportsIndex, transitory: SupportsInt | SupportsIndex, snapshot_interval: SupportsInt | SupportsIndex, init_state: Annotated[numpy.typing.ArrayLike, numpy.uint64, '[m, 1]'], callback: object) None

Run a trajectory and call callback(generation, population) at each snapshot.

Parameters:
  • snapshot_interval (int) – Call callback every this many generations after transitory.

  • callback (callable) – Called as callback(generation: int, population: list[int]).

set_beta(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, beta: SupportsFloat | SupportsIndex) None
set_mu(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC, mu: SupportsFloat | SupportsIndex) None
step(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) None

Advance the session by one generation.

For asynchronous rules: N individual update steps (one per node on average). For synchronous rules (e.g. LinearProportional): one full simultaneous sweep. Raises RuntimeError if initialize() has not been called first.

topology(self: egttools.numerical.numerical_.structure.NetworkMCEstimatorPC) list[list[int]]
__annotations__ = {}