egttools.games.AbstractNPlayerStateGame¶
- class AbstractNPlayerStateGame(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, nb_strategies: SupportsInt | SupportsIndex, group_size: SupportsInt | SupportsIndex)¶
Bases:
AbstractNPlayerGameAbstract base class for N-player games with state-dependent payoffs.
Use this class when payoffs cannot be precomputed at initialization because they depend on the current population state (e.g., games with variable risk functions whose value changes with population composition).
Subclasses must implement get_payoffs_for_player, which is called once per calculate_fitness invocation. The C++ base class then runs the full hypergeometric sampling loop in C++, reducing the number of Python call-throughs from O(nb_group_configurations) to exactly 1 per fitness evaluation.
- Parameters:
nb_strategies (int) – Number of strategies in the game.
group_size (int) – Number of players per interacting group.
Methods (Abstract)
----------------
get_payoffs_for_player(player_type – Returns a 1-D array of length nb_group_configurations with the expected payoff for player_type under each possible group configuration, given that the full population state (including the focal player) has linear index state_index.
state_index – Returns a 1-D array of length nb_group_configurations with the expected payoff for player_type under each possible group configuration, given that the full population state (including the focal player) has linear index state_index.
np.ndarray (calculate_payoffs() ->) – Returns a 1-D array of length nb_group_configurations with the expected payoff for player_type under each possible group configuration, given that the full population state (including the focal player) has linear index state_index.
play(group_composition – Fills game_payoffs in-place for a concrete group sample.
game_payoffs) – Fills game_payoffs in-place for a concrete group sample.
np.ndarray – Optionally pre-computes and stores the payoff matrix for inspection. Not used by calculate_fitness.
Notes
The state_index passed to get_payoffs_for_player is computed by egttools.calculate_state(group_size, full_state), where full_state is state with state[player_type] + 1.
Example
>>> import numpy as np >>> import egttools as egt >>> >>> class MyGame(egt.games.AbstractNPlayerStateGame): ... def __init__(self, nb_strategies, group_size, risk_func, payoff_func): ... super().__init__(nb_strategies, group_size) ... self._configs = [egt.sample_simplex(i, group_size, nb_strategies) ... for i in range(self.nb_group_configurations)] ... self.risk_func = risk_func ... self.payoff_func = payoff_func ... ... def get_payoffs_for_player(self, player_type, state_index, state): ... risk = self.risk_func(state_index) ... return np.array([self.payoff_func(risk, gc)[player_type] ... for gc in self._configs]) ... ... def play(self, group_composition, game_payoffs): ... ... def calculate_payoffs(self): return self.payoffs() ... def payoffs(self): return np.zeros((self.nb_strategies, self.nb_group_configurations)) ... def payoff(self, strategy, group_composition): return 0.0 ... def save_payoffs(self, file_name): pass ... def __str__(self): return "MyGame" ... def type(self): return "MyGame"
Methods
Computes the fitness of player_type in a population with state strategies.
Returns the payoff row for player_type across all group configurations.
Updates an entry in the payoff matrix.
- __init__(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, nb_strategies: SupportsInt | SupportsIndex, group_size: SupportsInt | SupportsIndex) None¶
- __new__(**kwargs)¶
- __str__(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame) str¶
- calculate_fitness(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, player_type: SupportsInt | SupportsIndex, pop_size: SupportsInt | SupportsIndex, strategies: Annotated[numpy.typing.NDArray[numpy.uint64], '[m, 1]']) float¶
Computes the fitness of player_type in a population with state strategies.
Calls get_payoffs_for_player once to obtain the full payoff row, then evaluates the hypergeometric expectation in C++.
- calculate_payoffs(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame) Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]']¶
- get_payoffs_for_player(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, player_type: SupportsInt | SupportsIndex, state_index: SupportsInt | SupportsIndex, state: Annotated[numpy.typing.NDArray[numpy.uint64], '[m, 1]']) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']¶
Returns the payoff row for player_type across all group configurations.
This method is called once per calculate_fitness invocation. Implement it in your Python subclass to return the payoffs that depend on the current population state.
- Parameters:
player_type (int) – Index of the focal player’s strategy.
state_index (int) – Linear index of the full population state (including the focal player), as returned by egttools.calculate_state(group_size, full_state).
state (np.ndarray) – Population state vector excluding the focal player (same as the strategies argument passed to calculate_fitness).
- Returns:
1-D array of length nb_group_configurations with the payoff for player_type in each possible group composition drawn from state.
- Return type:
np.ndarray
- group_size(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame) int¶
- nb_group_configurations(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame) int¶
- nb_strategies(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame) int¶
- payoff(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, strategy: SupportsInt | SupportsIndex, group_composition: collections.abc.Sequence[SupportsInt | SupportsIndex]) float¶
- payoffs(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame) Annotated[numpy.typing.NDArray[numpy.float64], '[m, n]']¶
- play(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, group_composition: collections.abc.Sequence[SupportsInt | SupportsIndex], game_payoffs: collections.abc.Sequence[SupportsFloat | SupportsIndex]) None¶
- save_payoffs(self: egttools.numerical.numerical_.games.AbstractNPlayerStateGame, file_name: str) None¶
- update_payoff(self: egttools.numerical.numerical_.games.AbstractNPlayerGame, strategy_index: SupportsInt | SupportsIndex, group_configuration_index: SupportsInt | SupportsIndex, value: SupportsFloat | SupportsIndex) None¶
Updates an entry in the payoff matrix.
- __annotations__ = {}¶