Пример #1
0
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))
Пример #2
0
    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)
Пример #3
0
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))
Пример #4
0
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))
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
0
    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"
Пример #8
0
    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"
Пример #9
0
 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)