gameanalysis.rsgame module

Module for base role symmetric game structures

Role symmetric games have a number of common attributes and functions that are defined in the RsGame class that actual RsGame interfaces should support. In addition, an implementation of an EmptyGame is provided for convenience purposes. Note, that the constructor to EmptyGame (and most games) should not be called, and instead, various convenience functions to create EmptyGames that start with the prefix emptygame should be called instead.

Most structures in a role symmetric game are an array of length game.num_strats, that lists a value for every strategy in the game. In this form, each roles strategies are contiguous. To aggregate elements by role, it is helpful to use numpy ufuncs, such as np.add.reduceat(profile, game.role_starts) will add up all of the players in each role of a profile. np.split(profile, game.role_starts[1:]) will return a list where each element is that role’s data. To convert a role array into a strategy array, one can do something like role_array.repeat(game.num_role_strats).

As a general rule, any attribute of a game that begins with num_ is an actual attribute instead of a getter function. Attributes that have the world role in them tend to be arrays of size num_roles and attributes that have strat in the name tend to be arrays of size num_strats.

class gameanalysis.rsgame.CompleteGame(role_names, strat_names, num_role_players)[source]

Bases: gameanalysis.rsgame.RsGame

A game that defines everything for complete games

Extend this if your game by default has payoff data for every profile.

num_complete_profiles
num_profiles
payoffs[source]
profiles[source]
class gameanalysis.rsgame.EmptyGame(role_names, strat_names, num_role_players)[source]

Bases: gameanalysis.rsgame.RsGame

A game with no payoff data

deviation_payoffs(mixture, *, jacobian=False)[source]
get_payoffs(profile)[source]
max_strat_payoffs()[source]
min_strat_payoffs()[source]
normalize()[source]
num_complete_profiles
num_profiles
payoffs()[source]
profiles()[source]
restrict(rest)[source]
to_json()[source]
class gameanalysis.rsgame.RsGame(role_names, strat_names, num_role_players)[source]

Bases: gameanalysis.rsgame.StratArray

Role-symmetric game representation

This object only contains methods and information about definition of the game, without defining how payoff data is generated / accessed.

Parameters:
  • role_names ((str,)) – The name of each role.
  • strat_names (((str,),)) – The name of each strategy for each role.
  • num_role_players (ndarray) – The number of players in each role. Must contain non-negative integers.
all_profiles()[source]

Return all profiles

best_response(mix)[source]

Returns the best response to a mixture

The result is a new mixture with uniform support over all best deviating strategies.

deviation_payoffs(mixture, *, jacobian=False)[source]

The payoffs for deviating from mixture

Optionally with the jacobian with respect to mixture. This is the primary method that needs to implemented for nash finding.

devpay_from_json(deviations, dest=None)[source]
devpay_to_json(payoffs)[source]

Format a profile and deviation payoffs as json

expected_payoffs(mix, *, jacobian=False, deviations=None)[source]

Returns the payoff of each role under mixture

If the payoffs for deviating from mix is already known, that an be passed in to save computation.

get_dev_payoffs(dev_profs)[source]

Compute the payoffs for deviating

Given partial profiles per role, compute the mean payoff for deviating to each strategy.

Parameters:dev_profs (array-like, shape = (num_samples, num_roles, num_strats)) – A list of partial profiles by role. This is the same structure as returned by random_dev_profiles.
get_payoffs(profile)[source]

The payoffs for all profiles

is_asymmetric()[source]

Returns true if this game is asymmetric

is_complete()[source]

Returns true if every profile has data

is_constant_sum()[source]

Returns true if this game is constant sum

is_empty()[source]

Returns true if no profiles have data

is_profile(prof, *, axis=-1)[source]

Verify that a profile is valid for game

is_symmetric()[source]

Returns true if this game is symmetric

max_prob_prof(mix)[source]

Returns the pure strategy profile with highest probability.

max_role_payoffs()[source]

Returns the maximum payoff for each role

max_strat_payoffs()[source]

An upper bound on the payoff for each strategy

min_role_payoffs()[source]

Returns the minimum payoff for each role

min_strat_payoffs()[source]

A lower bound on the payoff for each strategy

nearby_profiles(profile, num_devs)[source]

Returns profiles reachable by at most num_devs deviations

normalize()[source]

Return a new game where the max payoff is 1 and min payoff is 0

num_all_dpr_profiles

The number of unique dpr profiles

This calculation takes time exponential in the number of roles.

num_all_payoffs

The number of payoffs in all profiles

num_all_profiles

The total number of profiles in the game

Not just the ones with data.

num_all_role_profiles

The number of profiles in each role (independent of others)

num_complete_profiles

The number of profiles with complete payoff information

num_profiles

The number of profiles with any payoff information

payoff_from_json(pays, dest=None)[source]

Read a payoff from json

Parameters:
  • pays ({role: {strat: payoff}}) – A description of a payoff.
  • dest (ndarray, optional) – If supplied, dest will be written to instead of allocating a new array.
payoff_to_json(payoffs)[source]

Format payoffs as json

Parameters:payoffs (ndarray) – The payoffs to serialize.
payoffs()[source]

An array with all of the payoff corresponding to profiles()

profile_from_id(ids)[source]

Return a profile from its integer representation

profile_from_json(prof, dest=None, *, verify=True)[source]

Read a profile from json

Parameters:
  • prof ({role: {strat: count}}) – A description of a profile.
  • dest (ndarray, optional) – If supplied, dest will be written to instead of allocating a new array.
  • verify (bool, optional) – If true, verify that a proepr profile for this game was read.
profile_from_repr(prof_str, dest=None, *, verify=True)[source]

Read a profile from a string

profile_from_str(prof_str, dest=None, *, verify=True)[source]
profile_to_id(profiles)[source]

Return a unique integer representing a profile

profile_to_json(prof)[source]

Convert a profile array to json

profile_to_repr(prof)[source]

Convert a profile to a string

profile_to_str(prof)[source]

Convert a profile to a printable string

profiles()[source]

An array all of the profiles with any data

pure_profiles()[source]

Return all pure profiles

A pure profile is a profile where only one strategy is played per role.

random_deviation_profile(mixture=None)[source]
random_deviation_profiles(num_samples, mixture=None)[source]

Return a profiles where one player is deviating from mix

Resulting shape of profiles is (num_samples, num_role_strats, num_role_strats). The first dimension is the sample, the next is the deviating strategy, leaving the last dimension for the actual profile.

Parameters:
  • mixture (ndarray) – Mixture to sample from.
  • num_samples (int, optional) – Number of samples to return. If None or omitted, then a single sample, without a leading singleton dimension is returned.
random_profile(mixture=None)[source]
random_profiles(num_samples, mixture=None)[source]

Sample profiles from a mixture

Parameters:
  • num_samples (int) – Number of samples to return.
  • mixture (ndarray, optional) – Mixture to sample from, of None or omitted, then uses the uniform mixture.
random_role_deviation_profile(mixture=None)[source]
random_role_deviation_profiles(num_samples, mixture=None)[source]

Return partial profiles where dev player is missing

Resulting shape of profiles is (num_samples, num_roles, num_role_strats). The first dimension is the sample, the next is the deviating role, leaving the last dimension for the partial profile.

Parameters:
  • mixture (ndarray) – Mixture to sample from.
  • num_samples (int, optional) – Number of samples to return. If None or omitted, then a single sample, without a leading singleton dimension is returned.
restrict(restriction)[source]

Restrict viable strategies

round_mixture_to_profile(mixture)[source]

Round a mixture to the nearest profile

This finds the profile with the minimum absolute error to the product of the profile and the number of players per role.

to_json()[source]

Format game as json

class gameanalysis.rsgame.StratArray(role_names, strat_names)[source]

Bases: abc.ABC

A class with knowledge of the number of strategies per role

This has methods common to working with strategy arrays, which essentially represent points in a simplotope (a cross product of simplicies), or points in a discretized simplotope.

Parameters:
  • role_names ((str,)) – The name of each role. Names must be unique, sorted, and can only contain printable ascii characters less semi-colon and colon.
  • strat_names (((str,),)) – The name of each strategy for each role. Must be the same length as role_names. Names must be sorted and unique per role, and can only contain printable ascii characters less semi-colon and comma. Must have at lease one strategy per role.
all_restrictions()[source]

Return all valid restrictions

biased_mixtures(bias=0.9)[source]

Generates mixtures biased towards one strategy for each role

Each role has one strategy played with probability bias; the remaining 1-bias probability is distributed uniformly over the remaining S or S-1 strategies. If there’s only one strategy, it is played with probability 1.

dev_from_indices

The strategy deviating from for each deviation

dev_role_starts

The start index for each role deviation

dev_strat_starts

The start index for each strategy deviation

dev_to_indices

The strategy deviating to for each deviation

grid_mixtures(num_points)[source]

Returns all of the mixtures in a grid with n points

Parameters:num_points (int > 1) – The number of points to have along one dimensions
is_mixture(mix, *, axis=-1)[source]

Verify that a mixture is valid for game

is_restriction(restrict, *, axis=-1)[source]

Verify that a restriction is valid

mixture_from_json(mix, dest=None, *, verify=True)[source]

Read a json mixture into an array

mixture_from_repr(mix_str, dest=None, *, verify=True)[source]

Read a mixture from it’s repr

mixture_from_simplex(simp)[source]

Convert a simplex back into a valid mixture

This is the inverse function of mixture_to_simplex.

mixture_from_str(mix_str, dest=None, *, verify=True)[source]

Read a mixture from a verbose string

mixture_project(mixture)[source]

Project an array into mixture space

mixture_to_json(mix, *, supp_thresh=0.001)[source]

Convert a mixture array to json

mixture_to_repr(mix)[source]

Convert a mixture to a string

mixture_to_simplex(mixture)[source]

Convert a mixture to a simplex

The simplex will have dimension num_role_strats - num_roles + 1. This uses the ray tracing homotopy. The uniform mixtures are aligned, and then rays are extended to the edges to convert proportionally along those rays on each object.

Notes

This uses a simple ray alignment algorithm. First line up the uniform simplex and the uniform mixture, then define a vector in the mixture as all but the last probabilities in each role. Now trace a line from the uniform mixture to the current mixture to the edge of the mixture, and record what proportion of along that vector the point of interest was. Copy that gradient to the simplex, trace it to the boundary, and take the point the proportion of the way to the edge.

mixture_to_str(mix)[source]

Convert a mixture to a printable string

num_all_restrictions

Number of unique restrictions

num_devs

The total number of deviations

num_pure_restrictions

The number of pure restrictions

A pure restrictions has exactly one strategy per role.

num_role_devs

The number of deviations for each role

num_strat_devs

The number of deviations for each strategy

pure_mixtures()[source]

Returns all mixtures where the probability is either 1 or 0.

pure_restrictions()[source]

Returns every pure restriction in a game

A pure restriction has only one strategy per role. This returns the pure restrictions in sorted order based off of role and strategy.

random_mixture(*, alpha=1)[source]

Return a random mixture

See random_mixtures

random_mixtures(num_samples, *, alpha=1)[source]

Return a random mixed profile

Mixed profiles are sampled from a Dirichlet distribution with parameter alpha. If alpha = 1 (the default) this is a uniform distribution over the simplex for each role. Alpha in (0, 1) is baised towards high entropy mixtures, i.e. mixtures where one strategy is played in majority. Alpha in (1, oo) is baised towards low entropy (uniform) mixtures.

random_restriction(*, strat_prob=None, normalize=True)[source]

Return a random restriction

See random_restrictions

random_restrictions(num_samples, *, strat_prob=None, normalize=True)[source]

Return random restrictions

Parameters:
  • num_samples (int) – The number of restrictions to be returned.
  • strat_prob (float or [float], optional) – The probability that a given strategy is in support. If strat_prob is None, supports will be sampled uniformly. This can either be a scalar, or an iterable of length num_roles.
  • normalize (bool, optional) – If true, the strategy probabilities are normalized, so that the conditional probability of any strategy in support equals strat_prob. The probability for any strategy must be at least 1 / num_role_strats for its role. Individual strategy probabilities are thresholded to this value when normalize is set to true.
random_sparse_mixture(*, alpha=1, support_prob=None, normalize=True)[source]

Return a random sparse mixture

See random_sparse_mixtures

random_sparse_mixtures(num_samples, *, alpha=1, support_prob=None, normalize=True)[source]

Return a random sparse mixed profile

Parameters:
  • num_samples (int) – The number of mixtures to be returned.
  • alpha (float, optional) – Mixed profiles are sampled from a dirichlet distribution with parameter alpha. If alpha = 1 (the default) this is a uniform distribution over the simplex for each role. Alpha in (0, 1) is baised towards high entropy mixtures, i.e. mixtures where one strategy is played in majority. Alpha in (1, oo) is baised towards low entropy (uniform) mixtures.
  • support_prob (float or [float], optional) – The probability that a given strategy is in support. If support prob is None, supports will be sampled uniformly.
  • normalize (bool, optional) – If true, the mixtures are normalized, so that the conditional probability of any strategy in support equals support prob. If true, the support_prob for any role must be at least 1 / num_role_strats.
restriction_from_json(jrest, dest=None, *, verify=True)[source]

Read a restriction from json

Json format is {role: [strat]}

restriction_from_repr(rrest, dest=None, *, verify=True)[source]

Read a restriction from a repr string

A restriction repr is ‘role: strat, …; …’

restriction_from_str(srest, dest=None, *, verify=True)[source]

Read a restriction from a string

restriction_to_json(rest)[source]

Convert a restriction to json

restriction_to_repr(rest)[source]

Convert a restriction to a repr string

restriction_to_str(rest)[source]

Convert a restriction to a string

role_biased_mixtures(bias=0.9)[source]

Generates mixtures where one role-strategy is played with bias

If no roles have more than one strategy (a degenerate game), then this returns nothing.

role_ends
role_from_json(role_json, dest=None, dtype=<class 'float'>)[source]

Read role array from json

role_from_repr(rrole, dest=None, dtype=<class 'float'>)[source]

Read role data from repr

role_index(role)[source]

Return the index of a role by name

role_strat_dev_index(role, strat, dev)[source]

Return the index of a role strat deviating strat pair

dev and strat must both be strategies in role, and be distinct.

role_strat_index(role, strat)[source]

Return the index of a role strat pair

role_strat_names
role_to_json(role_info)[source]

Format role data as json

role_to_repr(role_info)[source]

Format role data as repr

strat_name(role_strat_index)[source]

Get the strategy name from a full index

trim_mixture_precision(mixture, *, resolution=0.001)[source]

Reduce precision of mixture

This trims the mixture so that it lies on the discretized space, where every component is an integer multiple of resolution. By default, trim mixture so every component is only accurate to 1 out of 1000, making it convenient for serialization. This function returns a valid mixture with the minimum absolute error to the input mixture.

trim_mixture_support(mixture, *, thresh=0.001, axis=-1)[source]

Trims strategies played less than supp_thresh from the support

uniform_mixture()[source]

Returns the uniform mixed profile

gameanalysis.rsgame.emptygame(num_role_players, num_role_strats)[source]

Create an empty game with default names

Parameters:
  • num_role_players (ndarray-like, int) – The number of players in each role in order, or the number of players per role if identical (will be broadcast to match the number of roles).
  • num_role_strats (ndarray-like, int) – The number of strategies in each role in order, or the number of strategies per role if identical (will be broadcast to match the number of roles).
gameanalysis.rsgame.emptygame_copy(copy_game)[source]

Copy parameters of a game into an empty game

This method is useful to keep convenience methods of game without attached data.

Parameters:copy_game (RsGame) – Game to copy info from.
gameanalysis.rsgame.emptygame_json(json)[source]

Read a EmptyGame from json

Parameters:json ({...}) – A json representation of a basic game with names. Must either be {roles: [{name: <role>, strategies: [<strat>]}]}, or {strategies: {<role>: [<strat>]}}.
gameanalysis.rsgame.emptygame_names(role_names, num_role_players, strat_names)[source]

Create an empty game with names

Parameters:
  • roles_names ([str]) – The name for each role.
  • num_role_players (ndarray, int, [int]) – The number of players in each role.
  • strat_names ([[str]]) – The name of each strategy for each role.