def test_acartesian2(): """Test acartesian2""" one = np.array([[1, 2, 3], [4, 5, 6]], int) two = np.array([[7, 8], [9, 10], [11, 12]], int) three = np.array([[13]], int) assert array_set_equals(one, utils.acartesian2(one)) assert array_set_equals(two, utils.acartesian2(two)) assert array_set_equals(three, utils.acartesian2(three)) expected = np.array( [[1, 2, 3, 7, 8, 13], [1, 2, 3, 9, 10, 13], [1, 2, 3, 11, 12, 13], [4, 5, 6, 7, 8, 13], [4, 5, 6, 9, 10, 13], [4, 5, 6, 11, 12, 13]], int) assert array_set_equals(expected[:, :-1], utils.acartesian2(one, two)) assert array_set_equals(expected, utils.acartesian2(one, two, three))
def pure_profiles(self): """Return all pure profiles A pure profile is a profile where only one strategy is played per role.""" role_profiles = [num_play * np.eye(num_strats, dtype=int) for num_play, num_strats in zip(self.num_players, self.num_strategies)] return utils.acartesian2(*role_profiles)
def test_acartesian2(): a = np.array([[1, 2, 3], [4, 5, 6]], int) b = np.array([[7, 8], [9, 10], [11, 12]], int) c = np.array([[13]], int) assert array_set_equals(a, utils.acartesian2(a)) assert array_set_equals(b, utils.acartesian2(b)) assert array_set_equals(c, utils.acartesian2(c)) expected = np.array([[1, 2, 3, 7, 8, 13], [1, 2, 3, 9, 10, 13], [1, 2, 3, 11, 12, 13], [4, 5, 6, 7, 8, 13], [4, 5, 6, 9, 10, 13], [4, 5, 6, 11, 12, 13]], int) assert array_set_equals(expected[:, :-1], utils.acartesian2(a, b)) assert array_set_equals(expected, utils.acartesian2(a, b, c))
def test_acartesian2(): """Test acartesian2""" one = np.array([[1, 2, 3], [4, 5, 6]], int) two = np.array([[7, 8], [9, 10], [11, 12]], int) three = np.array([[13]], int) assert array_set_equals(one, utils.acartesian2(one)) assert array_set_equals(two, utils.acartesian2(two)) assert array_set_equals(three, utils.acartesian2(three)) expected = np.array([[1, 2, 3, 7, 8, 13], [1, 2, 3, 9, 10, 13], [1, 2, 3, 11, 12, 13], [4, 5, 6, 7, 8, 13], [4, 5, 6, 9, 10, 13], [4, 5, 6, 11, 12, 13]], int) assert array_set_equals(expected[:, :-1], utils.acartesian2(one, two)) assert array_set_equals(expected, utils.acartesian2(one, two, three))
def grid_mixtures(self, num_points): """Returns all of the mixtures in a grid with n points Arguments --------- num_points : int > 1 The number of points to have along one dimensions """ assert num_points > 1, "Must have at least two points on a dimensions" role_mixtures = [utils.acomb(num_strats, num_points - 1, True) / (num_points - 1) for num_strats in self.num_strategies] return utils.acartesian2(*role_mixtures)
def biased_mixtures(self, bias=.9): """Generates mixtures biased towards one strategy for each role Each role has one strategy played with probability bias; the reamaining 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.""" assert 0 <= bias <= 1, "probabilities must be between zero and one" role_mixtures = [] for num_strats in self.num_strategies: if num_strats == 1: mix = np.ones((1, 1)) else: mix = np.empty((num_strats, num_strats)) mix.fill((1 - bias)/(num_strats - 1)) np.fill_diagonal(mix, bias) role_mixtures.append(mix) return utils.acartesian2(*role_mixtures)
def __init__(self, *args, verify=True): if len(args) == 1 and isinstance(args[0], SampleGame): # From SampleGame game = args[0] num_players = game.num_players num_strategies = game.num_strategies profiles = game.profiles.copy() sample_payoffs = [p.copy() for p in game.sample_payoffs] verify = False elif len(args) == 1 and isinstance(args[0], Game): # From Game game = args[0] num_players = game.num_players num_strategies = game.num_strategies profiles = game.profiles.copy() sample_payoffs = [game.payoffs.copy()[..., None]] verify = False elif len(args) == 1 and isinstance(args[0], BaseGame): # From BaseGame game = args[0] num_players = game.num_players num_strategies = game.num_strategies profiles = np.empty((0, game.num_role_strats), int) sample_payoffs = [] verify = False elif len(args) == 1: # Matrix constructor matrix = np.asarray(args[0], float) assert matrix.shape[-2] == matrix.ndim - 2, \ ("matrix shape is inconsistent with a matrix sample game {}" .format(matrix.shape)) num_players = np.ones(matrix.shape[-2], int) num_strategies = np.array(matrix.shape[:-2], int) num_samples = matrix.shape[-1] profiles = utils.acartesian2(*[np.eye(s, dtype=int) for s in num_strategies]) payoffs = np.zeros(profiles.shape + (num_samples,)) # This next set of steps is a hacky way of avoiding duplicating # mask by num_samples pview = payoffs.view() pview.shape = (-1, num_samples) mask = profiles > 0 mask.shape = (-1, 1) mask = np.broadcast_to(mask, (mask.size, num_samples)) np.place(pview, mask, matrix.flat) sample_payoffs = [payoffs] verify = False elif len(args) == 2: # Empty game num_players, num_strategies, = args num_role_strats = BaseGame(num_players, num_strategies).num_role_strats profiles = np.empty((0, num_role_strats), int) sample_payoffs = [] elif len(args) == 3: # Copy base from game num_players = args[0].num_players num_strategies = args[0].num_strategies profiles, sample_payoffs = args[1:] elif len(args) == 4: # Specify everything num_players, num_strategies, profiles, sample_payoffs = args else: raise ValueError('Invalid constructor arguments') sample_payoffs = tuple(np.asarray(p) for p in sample_payoffs) assert len(set(x.shape[1] for x in sample_payoffs)) <= 1, \ "Not all sample payoffs shapes compatible" # In case an empty list is passed if sample_payoffs: payoffs = np.concatenate([s.mean(2) for s in sample_payoffs]) else: payoffs = np.empty((0,) + profiles.shape[1:]) super().__init__(num_players, num_strategies, profiles, payoffs, verify=verify) self.sample_payoffs = sample_payoffs for spay in self.sample_payoffs: spay.setflags(write=False) self.num_sample_profs = np.fromiter( (x.shape[0] for x in self.sample_payoffs), int, len(self.sample_payoffs)) self.sample_starts = np.insert(self.num_sample_profs.cumsum(), 0, 0) self.num_samples = np.fromiter( (v.shape[2] for v in self.sample_payoffs), int, len(self.sample_payoffs)) assert not self.sample_payoffs or not verify or all( (samp[np.broadcast_to(count[..., None], samp.shape) == 0] == 0) .all() for count, samp in zip(np.split(self.profiles, self.sample_starts[1:]), self.sample_payoffs)), \ "some sample payoffs were nonzero for invalid payoffs"
def __init__(self, *args, verify=True): if len(args) == 1 and isinstance(args[0], Game): # From Game game = args[0] num_players = game.num_players num_strategies = game.num_strategies profiles = game.profiles.copy() payoffs = game.payoffs.copy() verify = False elif len(args) == 1 and isinstance(args[0], BaseGame): # From BaseGame game = args[0] num_players = game.num_players num_strategies = game.num_strategies profiles = np.empty((0, game.num_role_strats), int) payoffs = np.empty((0, game.num_role_strats)) verify = False elif len(args) == 1: # Matrix constructor matrix = np.asarray(args[0], float) assert matrix.shape[-1] == matrix.ndim - 1, \ "matrix shape is inconsistent with a matrix game {}".format( matrix.shape) num_players = np.ones(matrix.shape[-1], int) num_strategies = np.array(matrix.shape[:-1], int) profiles = utils.acartesian2(*[np.eye(s, dtype=int) for s in num_strategies]) payoffs = np.zeros(profiles.shape, float) payoffs[profiles > 0] = matrix.flat verify = False elif len(args) == 2: # Empty game num_players, num_strategies, = args num_role_strats = BaseGame(num_players, num_strategies).num_role_strats profiles = np.empty((0, num_role_strats), int) payoffs = np.empty((0, num_role_strats), float) elif len(args) == 3: # Copy base from game num_players = args[0].num_players num_strategies = args[0].num_strategies profiles, payoffs = args[1:] elif len(args) == 4: # Specify everything num_players, num_strategies, profiles, payoffs = args else: raise ValueError('Invalid constructor arguments') super().__init__(num_players, num_strategies) profiles = np.asarray(profiles, int) payoffs = np.asarray(payoffs) assert profiles.shape == payoffs.shape, \ ("profiles and payoffs must be the same shape : " "profiles {0}, payoffs {1}").format(profiles.shape, payoffs.shape) expected_shape = (profiles.shape[0], self.num_role_strats) assert profiles.shape == expected_shape, \ "profiles must have proper shape : expected {0} but was {1}"\ .format(expected_shape, profiles.shape) assert np.issubdtype(profiles.dtype, int), \ "profiles must contain integers : dtype {0}".format( profiles.dtype) assert not verify or np.all(profiles >= 0), \ "profiles was not non negative {} {}".format( np.any(profiles < 0, 1).nonzero(), profiles[profiles < 0]) assert not verify or np.all(self.role_reduce(profiles) == self.num_players), \ "not all profiles equaled player total {} {}".format( np.any(self.role_reduce(profiles) == self.num_players, 1).nonzero(), profiles[np.any(self.role_reduce(profiles) == self.num_players, 1)]) assert not verify or np.all(payoffs[profiles == 0] == 0), \ "there were nonzero payoffs for strategies without players" self.profiles = profiles self.profiles.setflags(write=False) self.payoffs = payoffs self.payoffs.setflags(write=False) self.num_profiles = profiles.shape[0] self._writeable_payoffs() # Reset # compute log dev reps player_factorial = np.sum(sps.gammaln(self.profiles + 1), 1) totals = (np.sum(sps.gammaln(self.num_players + 1)) - player_factorial) with np.errstate(divide='ignore'): self._dev_reps = (totals[:, None] + np.log(self.profiles) - self.role_repeat(np.log(self.num_players))) self._dev_reps.setflags(write=False) # Add profile lookup self._profile_id_map = dict(zip(map(utils.hash_array, self.profiles), self.payoffs)) if np.isnan(self.payoffs).any(): self._complete_profiles = frozenset( prof for prof, pay in self._profile_id_map.items() if not np.isnan(pay).any()) else: self._complete_profiles = self._profile_id_map self.num_complete_profiles = len(self._complete_profiles) assert len(self._profile_id_map) == self.num_profiles, \ "There was at least one duplicate profile"
def all_profiles(self): """Return all profiles""" role_arrays = [utils.acomb(n_strats, players, True) for n_strats, players in zip(self.num_strategies, self.num_players)] return utils.acartesian2(*role_arrays)