egttools.numerical.PairwiseComparisonNumerical¶
- class PairwiseComparisonNumerical¶
Bases:
pybind11_objectNumerical solver for evolutionary dynamics under the pairwise comparison rule.
Construct a numerical solver for a finite-population game.
- Parameters:
pop_size (int) – Number of individuals in the population.
game (egttools.games.AbstractGame) – Game object implementing the payoff and fitness structure.
cache_size (int) – Maximum cache size for fitness computations.
Methods
Replace the game used for fitness computation.
Estimate the absorption probability for each strategy from a given initial state.
Estimate the fixation probability of an invading strategy in a resident population.
Estimate the mean absorption time (fixation time) from a given initial state.
Estimate the stationary distribution of population states.
Estimate the stationary distribution in sparse format.
Estimate expected indicator values under the stationary distribution.
Estimate expected indicator values under the stationary distribution without computing the full distribution first.
Estimate the average frequency of each strategy over time.
Simulate the pairwise comparison process with mutation.
Simulate the stochastic dynamics with mutation.
Simulate the stochastic dynamics without mutation.
Set a full source-strategy-dependent mutation bias.
Set the mutation bias.
Attributes
Maximum number of cached fitness values.
Current (nb_strategies, nb_strategies) mutation matrix.
Number of discrete states in the population.
Number of strategies in the population.
Payoff matrix used for selection dynamics.
Current population size.
- __init__()¶
Construct a numerical solver for a finite-population game.
- Parameters:
pop_size (int) – Number of individuals in the population.
game (egttools.games.AbstractGame) – Game object implementing the payoff and fitness structure.
cache_size (int) – Maximum cache size for fitness computations.
- __new__(**kwargs)¶
- change_game()¶
Replace the game used for fitness computation.
The solver retains a pointer to the new game object; the caller must ensure the game stays alive for the lifetime of this solver (enforced automatically when called from Python via the keep-alive policy).
- Parameters:
game (egttools.games.AbstractGame) – New game object. Must have the same number of strategies as the current game.
- estimate_absorption_probabilities()¶
Estimate the absorption probability for each strategy from a given initial state.
Runs independent trajectories of the mutation-free Moran process from
init_stateand records which strategy fixed in each run. Generalisesestimate_fixation_probabilityto k > 2 strategies.- Parameters:
beta (float) – Intensity of selection.
init_state (numpy.ndarray) – Initial population state — array of strategy counts summing to
pop_size.nb_runs (int) – Number of independent trajectories.
- Returns:
Array of shape
(nb_strategies,)with the empirical fixation probability for each strategy.- Return type:
- estimate_fixation_probability()¶
Estimate the fixation probability of an invading strategy in a resident population.
- estimate_mean_absorption_time()¶
Estimate the mean absorption time (fixation time) from a given initial state.
Runs independent trajectories of the mutation-free Moran process from
init_stateand counts generations until any strategy reachespop_size.- Parameters:
beta (float) – Intensity of selection.
init_state (numpy.ndarray) – Initial population state — array of strategy counts summing to
pop_size.nb_runs (int) – Number of independent trajectories.
- Return type:
dict with keys
"mean"(float),"stderr"(float),"nb_runs"(int).
- estimate_stationary_distribution()¶
Estimate the stationary distribution of population states.
When
tolerance > 0, runs are processed in batches ofcheck_every(default:max(1, nb_runs // 10)). After each batch the L1 norm of the change in the normalised estimate is computed; if it falls belowtolerancethe simulation stops early. This can save significant computation when the distribution converges before allnb_runsare exhausted.Warning
If
mu * (nb_generations - transitory)is much less than 10 (i.e. fewer than ~10 mutations are expected in the counting window) aUserWarningis raised. The geometric-skip approximation becomes inaccurate in this regime. Increasenb_generations, decreasetransitory, or raisemu.- Parameters:
nb_runs (int) – Maximum number of independent simulation runs.
nb_generations (int) – Number of generations per run.
transitory (int) – Transient period (generations not counted toward the distribution).
beta (float) – Intensity of selection.
mu (float) – Mutation probability (must be > 0).
tolerance (float, optional) – Convergence threshold on the L1 norm of the change between consecutive batch estimates. 0.0 (default) disables early stopping.
check_every (int, optional) – Number of runs per convergence-check batch. 0 (default) uses
max(1, nb_runs // 10).
- Returns:
Estimated stationary distribution.
- Return type:
- estimate_stationary_distribution_sparse()¶
Estimate the stationary distribution in sparse format.
Identical to
estimate_stationary_distributionbut returns a sparse matrix. Use this method when the number of population states is very large, since most entries of the stationary distribution will be zero.Warning
If
mu * (nb_generations - transitory)is much less than 10 aUserWarningis raised. Seeestimate_stationary_distributionfor details.- Parameters:
nb_runs (int) – Maximum number of independent simulation runs.
nb_generations (int) – Number of generations per run.
transitory (int) – Transient period (generations not counted toward the distribution).
beta (float) – Intensity of selection.
mu (float) – Mutation probability (must be > 0).
tolerance (float, optional) – Convergence threshold on the L1 norm; 0.0 disables early stopping.
check_every (int, optional) – Runs per convergence-check batch; 0 uses
max(1, nb_runs // 10).
- Returns:
Estimated stationary distribution in sparse format.
- Return type:
- estimate_stationary_indicators()¶
Estimate expected indicator values under the stationary distribution.
Runs stochastic simulations and accumulates indicator values at each post-transitory step. The time-average converges to the true expectation by the ergodic theorem without storing the full stationary distribution.
For
indicator_type='state', whennb_states * len(indicators)exceedsprecompute_limitthis method automatically falls back to evaluating the indicators directly on the live simulation state at each recorded step, instead of precomputing a dense(nb_states, nb_indicators)matrix upfront. This keeps memory use atO(nb_indicators)regardless of the size of the state space, at the cost of a Python callback per indicator per recorded generation (slower per-step than the matrix lookup, but the only way to stay within memory whennb_statesis too large to enumerate). This fallback is not yet available forindicator_type='group', which raises a clear error instead of attempting the same allocation.- Parameters:
indicators (callable or list[callable]) –
One or more indicator functions.
indicator_type='state': receives a population state asnp.ndarrayof shape(nb_strategies,)with integer counts summing topop_size, returns afloat. Use for quantities like the fraction of cooperators.indicator_type='group': receives a group configuration asnp.ndarrayof shape(nb_strategies,)summing togroup_size, returns afloat. The expectation is marginalised over group configs using the multivariate hypergeometric distribution. Requiresgroup_size.
nb_runs (int) – Maximum number of independent simulation runs.
nb_generations (int) – Number of generations per run.
transitory (int) – Transitory period (generations excluded from accumulation).
beta (float) – Intensity of selection.
mu (float) – Mutation probability (must be > 0).
indicator_type ({'state', 'group'}, default 'state') – Whether indicators operate on population states or group configurations.
group_size (int, optional) – Required when
indicator_type='group'.tolerance (float, default 0.0) – L1 convergence threshold on column-means between batches. 0.0 disables early stopping.
check_every (int, default 0) – Batch size for convergence checks. 0 →
max(1, nb_runs // 10).confidence (float, default 0.95) – Confidence level for the bootstrap CI.
verbose (bool, default False) – If
True, attach per-run values to the result.n_bootstrap (int, default 9999) – Number of bootstrap resamples.
precompute_limit (int, default 20_000_000) – Maximum number of elements (
nb_states * len(indicators)) allowed in the precomputed indicator matrix. Above this,indicator_type='state'switches automatically to a direct, memory-bounded estimator (see above);indicator_type='group'raises instead.
- Returns:
.mean— grand mean, shape(nb_indicators,)..confidence_interval—(low, high)non-parametric bootstrap CI..nb_runs_used— runs actually completed..converged—Trueif tolerance-based early stopping triggered..per_run_values— per-run means(nb_runs_used, nb_indicators)whenverbose=True, elseNone.- Return type:
See also
estimate_stationary_indicators_precomputedlow-level fast path accepting a precomputed indicator matrix directly.
egttools.precompute_group_to_state_indicator_matrixbuild the indicator matrix manually for repeated reuse.
- estimate_stationary_indicators_precomputed()¶
Estimate expected indicator values under the stationary distribution without computing the full distribution first.
At each post-transitory simulation step the method looks up the precomputed indicator values for the current population state and accumulates them. The per-run time-average converges to
E[f_k] = sum_s sd(s) * indicator_values(s, k)by the ergodic theorem.indicator_valuesmust be a dense matrix of shape(nb_states, nb_indicators)where rowscontains the values of all indicators for the population state at indexs.For state-level indicators
f(state): buildindicator_valuesby evaluatingfonegttools.sample_simplex(s, pop_size, nb_strategies)for each state indexs.For group-level indicators
f(group_config): useegttools.precompute_group_to_state_indicator_matrixto marginalise over group configurations first, then pass the resulting matrix here.
Returns a matrix of shape
(nb_runs_used, nb_indicators)— one row per completed run. Prefer the high-level methodestimate_stationary_indicators(same class) which accepts Python callables, builds the indicator matrix automatically, and returns aStationaryIndicatorResultwith mean and bootstrap CI.Warning
If
mu * (nb_generations - transitory)is much less than 10 aUserWarningis raised. Seeestimate_stationary_distributionfor details.- Parameters:
nb_runs (int) – Maximum number of independent simulation runs.
nb_generations (int) – Number of generations per run.
transitory (int) – Transitory period (not counted toward indicator accumulation).
beta (float) – Intensity of selection.
mu (float) – Mutation probability (must be > 0).
indicator_values (numpy.ndarray) – Precomputed matrix of shape (nb_states, nb_indicators).
tolerance (float, optional) – L1 convergence threshold on column-means between batches. 0.0 (default) disables early stopping.
check_every (int, optional) – Batch size for convergence checks; 0 uses max(1, nb_runs // 10).
- Returns:
Per-run means of shape (nb_runs_used, nb_indicators).
- Return type:
- estimate_strategy_distribution()¶
Estimate the average frequency of each strategy over time.
This method bypasses state indexing and is safe when the total number of population states exceeds
MAX_LONG_INT.Warning
If
mu * (nb_generations - transitory)is much less than 10 aUserWarningis raised. Seeestimate_stationary_distributionfor details.- Parameters:
nb_runs (int) – Maximum number of independent simulation runs.
nb_generations (int) – Number of generations per run.
transitory (int) – Transient period (generations not counted toward the distribution).
beta (float) – Intensity of selection.
mu (float) – Mutation probability (must be > 0).
tolerance (float, optional) – Convergence threshold on the L1 norm; 0.0 disables early stopping.
check_every (int, optional) – Runs per convergence-check batch; 0 uses
max(1, nb_runs // 10).
- Returns:
Average frequency of each strategy.
- Return type:
- evolve()¶
Simulate the pairwise comparison process with mutation.
- Parameters:
nb_generations (int) – Number of generations to simulate.
beta (float) – Intensity of selection.
mu (float) – Mutation rate.
init_state (numpy.ndarray) – Initial population state.
- Returns:
Final population state.
- Return type:
- run()¶
- run_with_mutation()¶
Simulate the stochastic dynamics with mutation.
- Returns:
Matrix containing all intermediate population states.
- Return type:
Simulate the stochastic dynamics with mutation, skipping the transient phase.
- Returns:
Matrix containing the population states after the transient period.
- Return type:
- run_without_mutation()¶
Simulate the stochastic dynamics without mutation.
- Returns:
Matrix containing all intermediate population states.
- Return type:
Simulate the stochastic dynamics without mutation, skipping the transient phase.
- Returns:
Matrix containing the population states after the transient period.
- Return type:
- set_mutation_matrix()¶
Set a full source-strategy-dependent mutation bias.
Row
iofmutation_matrixis the (unnormalized) distribution over target strategies when an individual currently playing strategyimutates. The diagonal is always ignored (mutation always changes strategy). Each row must have at least one strictly positive entry among the other strategies.- Parameters:
mutation_matrix (numpy.ndarray) – Shape
(nb_strategies, nb_strategies), non-negative entries.
See also
set_mutation_weightsconvenience method accepting a single vector (bias shared by all source strategies) or a full matrix.
- set_mutation_weights()¶
Set the mutation bias. Accepts either shape:
1D, length
nb_strategies: a target-strategy bias shared by all source strategies (broadcast into every row of the mutation matrix; equivalent toset_mutation_matrixwith every row equal to this vector and the diagonal zeroed).2D, shape
(nb_strategies, nb_strategies): rowiis the bias over target strategies when mutating away from strategyi(equivalent to callingset_mutation_matrixdirectly).
Diagonal entries are always ignored (mutation always changes strategy). Each row must have at least one positive entry among the other strategies, otherwise mutating away from that strategy would have no valid target and this raises. A solver’s mutation is uniform by default; call this to bias it.
- Parameters:
weights (array_like) – 1D (length
nb_strategies) or 2D (nb_strategies x nb_strategies).
- __annotations__ = {}¶
- property cache_size¶
Maximum number of cached fitness values.
- property mutation_matrix¶
Current (nb_strategies, nb_strategies) mutation matrix. Row i is the (unnormalized) distribution over target strategies when mutating away from strategy i; the diagonal is always 0. Defaults to uniform (all-ones off-diagonal) until set_mutation_weights is called.
- property nb_states¶
Number of discrete states in the population.
- property nb_strategies¶
Number of strategies in the population.
- property payoffs¶
Payoff matrix used for selection dynamics.
- property pop_size¶
Current population size.