egttools.numerical.numerical_.PairwiseComparisonTransitionOperator

class PairwiseComparisonTransitionOperator

Bases: pybind11_object

Matrix-free transition operator for the pairwise comparison process.

Computes matrix-vector products y = P x, y = P^T x, and y = (I - P^T) x without ever assembling the transition matrix P. Designed for iterative eigensolvers (scipy.sparse.linalg, petsc4py) and as the basis for future MPI-distributed computation.

The stationary distribution π satisfies P^T π = π. Use apply_transpose or wrap this object with egttools.numerical.linear_operator.make_transition_operator to obtain a scipy.sparse.linalg.LinearOperator.

Construct the matrix-free transition operator.

Parameters:
  • population_size (int) – Number of individuals Z (must be >= 2).

  • game (egttools.games.AbstractGame) – Game object defining strategy fitnesses.

  • beta (float) – Intensity of selection (Fermi parameter, >= 0).

  • mu (float) – Mutation probability per step (in [0, 1]).

Methods

apply

Compute y = P x in-place.

apply_residual

Compute y = (I - P^T) x in-place.

apply_transpose

Compute y = P^T x in-place.

compute_stationary_distribution

Compute the stationary distribution via power iteration (pure C++).

Attributes

beta

Intensity of selection β.

mu

Mutation probability μ.

nb_strategies

Number of strategies k.

population_size

Population size Z.

size

Total number of simplex states C(Z+k-1, k-1).

__init__()

Construct the matrix-free transition operator.

Parameters:
  • population_size (int) – Number of individuals Z (must be >= 2).

  • game (egttools.games.AbstractGame) – Game object defining strategy fitnesses.

  • beta (float) – Intensity of selection (Fermi parameter, >= 0).

  • mu (float) – Mutation probability per step (in [0, 1]).

__new__(**kwargs)
apply()

Compute y = P x in-place.

Parameters:
apply_residual()

Compute y = (I - P^T) x in-place.

Useful for iterative linear solvers: find π such that (I - P^T) π = 0.

Parameters:
apply_transpose()

Compute y = P^T x in-place.

The stationary distribution π satisfies P^T π = π, so this is the primary operation for iterative eigensolver use.

Parameters:
compute_stationary_distribution()

Compute the stationary distribution via power iteration (pure C++).

Iterates π ← P^T π / ‖P^T π‖₁ until L1 convergence or max_iter is reached. Runs entirely in C++ with no Python callbacks — much faster than wrapping the operator in a scipy.sparse.linalg.LinearOperator for large state spaces.

Parameters:
  • tol (float) – L1 convergence threshold (default 1e-10).

  • max_iter (int) – Maximum number of power-iteration steps (default 10000).

Returns:

Normalised stationary distribution of length size.

Return type:

numpy.ndarray

Raises:

RuntimeError – If convergence is not reached within max_iter iterations.

__annotations__ = {}
property beta

Intensity of selection β.

property mu

Mutation probability μ.

property nb_strategies

Number of strategies k.

property population_size

Population size Z.

property size

Total number of simplex states C(Z+k-1, k-1).