normal_form_game¶
Tools for normal form games.
Definitions and Basic Concepts¶
An \(N\)player normal form game \(g = (I, (A_i)_{i \in I}, (u_i)_{i \in I})\) consists of
 the set of players \(I = \{0, \ldots, N1\}\),
 the set of actions \(A_i = \{0, \ldots, n_i1\}\) for each player \(i \in I\), and
 the payoff function \(u_i \colon A_i \times A_{i+1} \times \cdots \times A_{i+N1} \to \mathbb{R}\) for each player \(i \in I\),
where \(i+j\) is understood modulo \(N\). Note that we adopt the convention that the 0th argument of the payoff function \(u_i\) is player \(i\)‘s own action and the \(j\)th argument is player (\(i+j\))’s action (modulo \(N\)). A mixed action for player \(i\) is a probability distribution on \(A_i\) (while an element of \(A_i\) is referred to as a pure action). A pure action \(a_i \in A_i\) is identified with the mixed action that assigns probability one to \(a_i\). Denote the set of mixed actions of player \(i\) by \(X_i\). We also denote \(A_{i} = A_{i+1} \times \cdots \times A_{i+N1}\) and \(X_{i} = X_{i+1} \times \cdots \times X_{i+N1}\).
The (pureaction) best response correspondence \(b_i \colon X_{i} \to A_i\) for each player \(i\) is defined by
where \(u_i(a_i, x_{i}) = \sum_{a_{i} \in A_{i}} u_i(a_i, a_{i}) \prod_{j=1}^{N1} x_{i+j}(a_j)\) is the expected payoff to action \(a_i\) against mixed actions \(x_{i}\). A profile of mixed actions \(x^* \in X_0 \times \cdots \times X_{N1}\) is a Nash equilibrium if for all \(i \in I\) and \(a_i \in A_i\),
or equivalently, \(x_i^* \cdot v_i(x_{i}^*) \geq x_i \cdot v_i(x_{i}^*)\) for all \(x_i \in X_i\), where \(v_i(x_{i})\) is the vector of player \(i\)‘s payoffs when the opponent players play mixed actions \(x_{i}\).
Creating a NormalFormGame¶
There are three ways to construct a NormalFormGame instance.
The first is to pass an array of payoffs for all the players:
>>> matching_pennies_bimatrix = [[(1, 1), (1, 1)], [(1, 1), (1, 1)]]
>>> g = NormalFormGame(matching_pennies_bimatrix)
>>> print(g.players[0])
Player in a 2player normal form game with payoff array:
[[ 1, 1],
[1, 1]]
>>> print(g.players[1])
Player in a 2player normal form game with payoff array:
[[1, 1],
[ 1, 1]]
If a square matrix (2dimensional array) is given, then it is considered to be a symmetric twoplayer game:
>>> coordination_game_matrix = [[4, 0], [3, 2]]
>>> g = NormalFormGame(coordination_game_matrix)
>>> print(g)
2player NormalFormGame with payoff profile array:
[[[4, 4], [0, 3]],
[[3, 0], [2, 2]]]
The second is to specify the sizes of the action sets of the players, which gives a NormalFormGame instance filled with payoff zeros, and then set the payoff values to each entry:
>>> g = NormalFormGame((2, 2))
>>> print(g)
2player NormalFormGame with payoff profile array:
[[[ 0., 0.], [ 0., 0.]],
[[ 0., 0.], [ 0., 0.]]]
>>> g[0, 0] = 1, 1
>>> g[0, 1] = 2, 3
>>> g[1, 0] = 3, 2
>>> print(g)
2player NormalFormGame with payoff profile array:
[[[ 1., 1.], [2., 3.]],
[[ 3., 2.], [ 0., 0.]]]
The third is to pass an array of Player instances, as explained in the next section.
Creating a Player¶
A Player instance is created by passing a payoff array:
>>> player0 = Player([[3, 1], [0, 2]])
>>> player0.payoff_array
array([[3, 1],
[0, 2]])
Passing an array of Player instances is the third way to create a NormalFormGame instance.
>>> player1 = Player([[2, 0], [1, 3]])
>>> player1.payoff_array
array([[2, 0],
[1, 3]])
>>> g = NormalFormGame((player0, player1))
>>> print(g)
2player NormalFormGame with payoff profile array:
[[[3, 2], [1, 1]],
[[0, 0], [2, 3]]]
Beware that in payoff_array[h, k], h refers to the player’s own action, while k refers to the opponent player’s action.

class
quantecon.game_theory.normal_form_game.
NormalFormGame
(data, dtype=None)[source]¶ Bases:
object
Class representing an Nplayer normal form game.
Parameters:  data : array_like of Player, int (ndim=1), or float (ndim=2 or N+1)
Data to initialize a NormalFormGame. data may be an array of Players, in which case the shapes of the Players’ payoff arrays must be consistent. If data is an array of N integers, then these integers are treated as the numbers of actions of the N players and a NormalFormGame is created consisting of payoffs all 0 with data[i] actions for each player i. data may also be an (N+1)dimensional array representing payoff profiles. If data is a square matrix (2dimensional array), then the game will be a symmetric twoplayer game where the payoff matrix of each player is given by the input matrix.
 dtype : datatype, optional(default=None)
Relevant only when data is an array of integers. Data type of the players’ payoff arrays. If not supplied, default to numpy.float64.
Attributes:  players : tuple(Player)
Tuple of the Player instances of the game.
 N : scalar(int)
The number of players.
 nums_actions : tuple(int)
Tuple of the numbers of actions, one for each player.
 payoff_arrays : tuple(ndarray(float, ndim=N))
Tuple of the payoff arrays, one for each player.
Methods
is_nash
(action_profile[, tol])Return True if action_profile is a Nash equilibrium. 
is_nash
(action_profile, tol=None)[source]¶ Return True if action_profile is a Nash equilibrium.
Parameters:  action_profile : array_like(int or array_like(float))
An array of N objects, where each object must be an integer (pure action) or an array of floats (mixed action).
 tol : scalar(float)
Tolerance level used in determining best responses. If None, default to each player’s tol attribute value.
Returns:  bool
True if action_profile is a Nash equilibrium; False otherwise.

payoff_profile_array
¶

class
quantecon.game_theory.normal_form_game.
Player
(payoff_array)[source]¶ Bases:
object
Class representing a player in an Nplayer normal form game.
Parameters:  payoff_array : array_like(float)
Array representing the player’s payoff function, where payoff_array[a_0, a_1, …, a_{N1}] is the payoff to the player when the player plays action a_0 while his N1 opponents play actions a_1, …, a_{N1}, respectively.
Attributes:  payoff_array : ndarray(float, ndim=N)
See Parameters.
 num_actions : scalar(int)
The number of actions available to the player.
 num_opponents : scalar(int)
The number of opponent players.
 dtype : dtype
Data type of the elements of payoff_array.
 tol : scalar(float), default=1e8
Default tolerance value used in determining best responses.
Methods
best_response
(opponents_actions[, …])Return the best response action(s) to opponents_actions. is_best_response
(own_action, opponents_actions)Return True if own_action is a best response to opponents_actions. is_dominated
(action[, tol, method])Determine whether action is strictly dominated by some mixed action. payoff_vector
(opponents_actions)Return an array of payoff values, one for each own action, given a profile of the opponents’ actions. random_choice
([actions, random_state])Return a pure action chosen randomly from actions. 
best_response
(opponents_actions, tie_breaking='smallest', payoff_perturbation=None, tol=None, random_state=None)[source]¶ Return the best response action(s) to opponents_actions.
Parameters:  opponents_actions : scalar(int) or array_like
A profile of N1 opponents’ actions, represented by either scalar(int), array_like(float), array_like(int), or array_like(array_like(float)). If N=2, then it must be a scalar of integer (in which case it is treated as the opponent’s pure action) or a 1dimensional array of floats (in which case it is treated as the opponent’s mixed action). If N>2, then it must be an array of N1 objects, where each object must be an integer (pure action) or an array of floats (mixed action).
 tie_breaking : str, optional(default=’smallest’)
str in {‘smallest’, ‘random’, False}. Control how, or whether, to break a tie (see Returns for details).
 payoff_perturbation : array_like(float), optional(default=None)
Array of length equal to the number of actions of the player containing the values (“noises”) to be added to the payoffs in determining the best response.
 tol : scalar(float), optional(default=None)
Tolerance level used in determining best responses. If None, default to the value of the tol attribute.
 random_state : int or np.random.RandomState, optional
Random seed (integer) or np.random.RandomState instance to set the initial state of the random number generator for reproducibility. If None, a randomly initialized RandomState is used. Relevant only when tie_breaking=’random’.
Returns:  scalar(int) or ndarray(int, ndim=1)
If tie_breaking=False, returns an array containing all the best response pure actions. If tie_breaking=’smallest’, returns the best response action with the smallest index; if tie_breaking=’random’, returns an action randomly chosen from the best response actions.

is_best_response
(own_action, opponents_actions, tol=None)[source]¶ Return True if own_action is a best response to opponents_actions.
Parameters:  own_action : scalar(int) or array_like(float, ndim=1)
An integer representing a pure action, or an array of floats representing a mixed action.
 opponents_actions : see best_response
 tol : scalar(float), optional(default=None)
Tolerance level used in determining best responses. If None, default to the value of the tol attribute.
Returns:  bool
True if own_action is a best response to opponents_actions; False otherwise.

is_dominated
(action, tol=None, method=None)[source]¶ Determine whether action is strictly dominated by some mixed action.
Parameters:  action : scalar(int)
Integer representing a pure action.
 tol : scalar(float), optional(default=None)
Tolerance level used in determining domination. If None, default to the value of the tol attribute.
 method : str, optional(default=None)
If None, lemke_howson from quantecon.game_theory is used to solve for a Nash equilibrium of an auxiliary zerosum game. If method=’simplex’, scipy.optimize.linprog is used with method=’simplex’.
Returns:  bool
True if action is strictly dominated by some mixed action; False otherwise.

payoff_vector
(opponents_actions)[source]¶ Return an array of payoff values, one for each own action, given a profile of the opponents’ actions.
Parameters:  opponents_actions : see best_response.
Returns:  payoff_vector : ndarray(float, ndim=1)
An array representing the player’s payoff vector given the profile of the opponents’ actions.

random_choice
(actions=None, random_state=None)[source]¶ Return a pure action chosen randomly from actions.
Parameters:  actions : array_like(int), optional(default=None)
An array of integers representing pure actions.
 random_state : int or np.random.RandomState, optional
Random seed (integer) or np.random.RandomState instance to set the initial state of the random number generator for reproducibility. If None, a randomly initialized RandomState is used.
Returns:  scalar(int)
If actions is given, returns an integer representing a pure action chosen randomly from actions; if not, an action is chosen randomly from the player’s all actions.

quantecon.game_theory.normal_form_game.
best_response_2p
[source]¶ Numbaoptimized version of Player.best_response compilied in nopython mode, specialized for 2player games (where there is only one opponent).
Return the best response action (with the smallest index if more than one) to opponent_mixed_action under payoff_matrix.
Parameters:  payoff_matrix : ndarray(float, ndim=2)
Payoff matrix.
 opponent_mixed_action : ndarray(float, ndim=1)
Opponent’s mixed action. Its length must be equal to payoff_matrix.shape[1].
 tol : scalar(float), optional(default=None)
Tolerance level used in determining best responses.
Returns:  scalar(int)
Best response action.

quantecon.game_theory.normal_form_game.
pure2mixed
(num_actions, action)[source]¶ Convert a pure action to the corresponding mixed action.
Parameters:  num_actions : scalar(int)
The number of the pure actions (= the length of a mixed action).
 action : scalar(int)
The pure action to convert to the corresponding mixed action.
Returns:  ndarray(float, ndim=1)
The mixed action representation of the given pure action.