예제 #1
0
def test_empty_add_noise():
    base_game = rsgame.game([3, 3], [4, 4])
    game = gamegen.add_noise(base_game, 1)
    assert game.is_empty()

    base_game = gamegen.role_symmetric_game([3] * 3, 4)
    game = gamegen.add_noise(base_game, 0)
    assert game.is_empty()
예제 #2
0
def test_rand_dpr_allow_incomplete(add_prob, num_obs, game_desc):
    """Test that allow_incomplete works for random games"""
    # Generate games
    players, strategies, red_players = game_desc
    base = rsgame.BaseGame(players, strategies)
    game = gamegen.add_profiles(base, add_prob)
    sgame = gamegen.add_noise(game, 1, num_obs)
    red = reduction.DeviationPreserving(strategies, players, red_players)

    # Try to reduce game
    red_game = red.reduce_game(game, True)
    red_sgame = red.reduce_game(sgame, True)

    # Verify that when allow_incomplete, then reduce returns all profiles
    reduced_full_profiles = utils.axis_to_elem(
        red.reduce_profiles(game.profiles))
    reduced_profiles = utils.axis_to_elem(red_game.profiles)
    assert np.setxor1d(reduced_profiles, reduced_full_profiles).size == 0
    reduced_sample_profiles = utils.axis_to_elem(red_sgame.profiles)
    assert np.setxor1d(reduced_sample_profiles,
                       reduced_full_profiles).size == 0

    redord = np.argsort(reduced_profiles)
    redsord = np.argsort(reduced_sample_profiles)
    assert np.all(np.isnan(red_game.payoffs[redord]) ==
                  np.isnan(red_sgame.payoffs[redsord])), \
        "sample game and game didn't have same nan payoffs"
    assert all(np.all(np.isnan(p).any(-1) == np.isnan(p).all(-1)) for p
               in red_sgame.sample_payoffs), \
        "some sample payoffs had partial nans"
예제 #3
0
def test_mixture_regret_single_mix(players, strategies):
    num_boots = 200
    game = gamegen.add_noise(gamegen.role_symmetric_game(players, strategies),
                             1, 3)
    mix = game.random_mixtures()[0]
    boots = bootstrap.mixture_regret(game, mix, num_boots, processes=1)
    assert boots.shape == (1, num_boots)
    assert np.all(boots >= 0)
예제 #4
0
def test_mixture_welfare(players, strategies):
    num_mixes = 5
    num_boots = 200
    game = gamegen.add_noise(gamegen.role_symmetric_game(players, strategies),
                             1, 3)
    mixes = game.random_mixtures(num_mixes)
    boots = bootstrap.mixture_welfare(game, mixes, num_boots, processes=1)
    assert boots.shape == (num_mixes, num_boots)
예제 #5
0
def test_mixture_regret_parallel():
    num_mixes = 5
    num_boots = 200
    game = gamegen.add_noise(gamegen.role_symmetric_game([4, 3], [3, 4]), 1,
                             3)
    mixes = game.random_mixtures(num_mixes)
    boots = bootstrap.mixture_regret(game, mixes, num_boots)
    assert boots.shape == (num_mixes, num_boots)
    assert np.all(boots >= 0)
예제 #6
0
def test_json_copy_samplegame(game_size, samples):
    base = gamegen.role_symmetric_game(*game_size)
    game1 = gamegen.add_noise(base, 1, samples)
    serial = gamegen.serializer(game1)
    game2, _ = gameio.read_samplegame(serial.to_samplegame_json(game1))
    assert game1 == game2
    assert np.all(game1.profiles == game2.profiles)
    assert np.allclose(game1.payoffs, game2.payoffs)
    for spay1, spay2 in zip(game1.sample_payoffs, game2.sample_payoffs):
        assert np.allclose(spay1, spay2)
예제 #7
0
def test_add_noise(players, strategies, lower, upper):
    roles = max(np.array(players).size, np.array(strategies).size)
    base_game = gamegen.role_symmetric_game(players, strategies)
    game = gamegen.add_noise(base_game, lower, upper)
    assert lower == 0 or game.is_complete(), "didn't generate a full game"
    assert game.num_roles == roles, \
        "didn't generate correct number of players"
    assert np.all(strategies == game.num_strategies), \
        "didn't generate correct number of strategies"
    assert (np.all(game.num_samples >= min(lower, 1)) and
            np.all(game.num_samples <= upper)), \
        "didn't generate appropriate number of samples"
예제 #8
0
def test_subgame_preserves_completeness(players, strategies, _):
    """Test that subgame function preserves completeness"""
    game = gamegen.role_symmetric_game(players, strategies)
    assert game.is_complete(), "gamegen didn't create complete game"

    mask = game.random_subgames()
    sub_game = subgame.subgame(game, mask)
    assert sub_game.is_complete(), "subgame didn't preserve game completeness"

    sgame = gamegen.add_noise(game, 1, 3)
    sub_sgame = subgame.subgame(sgame, mask)
    assert sub_sgame.is_complete(), \
        "subgame didn't preserve sample game completeness"
예제 #9
0
def test_dpr(keep_prob, game_desc):
    """Simple test that dpr functions are consistent"""
    players, strategies, red_players = game_desc
    # Create game and reduction
    game = gamegen.role_symmetric_game(players, strategies)
    game = gamegen.drop_profiles(game, keep_prob)
    sgame = gamegen.add_noise(game, 1, 3)
    red = reduction.DeviationPreserving(strategies, players, red_players)

    # Try to reduce game
    assert rsgame.basegame_copy(game) == red.full_game
    assert red.reduce_game(rsgame.basegame_copy(game)) == red.red_game
    red_game = red.reduce_game(game)
    red_game2 = reduction.reduce_game_dpr(game, red_players)
    red_sgame = red.reduce_game(sgame)

    # Assert that reduce_game_dpr produces identical results
    reduced_profiles = utils.axis_to_elem(red_game.profiles)
    reduced_profiles2 = utils.axis_to_elem(red_game2.profiles)
    assert np.setxor1d(reduced_profiles, reduced_profiles2).size == 0, \
        "different reduction functions didn't produce identical results"

    # Assert that reducing all profiles covers reduced game
    reduced_full_profiles = utils.axis_to_elem(
        red.reduce_profiles(game.profiles))
    assert np.setdiff1d(reduced_profiles, reduced_full_profiles).size == 0, \
        "reduced game contained profiles it shouldn't have"
    reduced_sample_profiles = utils.axis_to_elem(red_sgame.profiles)
    assert np.setdiff1d(reduced_sample_profiles,
                        reduced_full_profiles).size == 0, \
        "reduced sample game contained profiles it shouldn't have"
    assert np.setxor1d(reduced_sample_profiles,
                       reduced_profiles).size == 0, \
        "reduced sample game and reduced game had different profiles"

    # Assert that all contributing profiles are in the expansion of the reduced
    # game
    full_profiles = utils.axis_to_elem(game.profiles)
    full_reduced_profiles = utils.axis_to_elem(
        red.expand_profiles(red_game.profiles))
    assert np.setdiff1d(full_reduced_profiles, full_profiles).size == 0, \
        "full game did not have data for all profiles required of reduced"
    full_reduced_sample_profiles = utils.axis_to_elem(
        red.expand_profiles(red_sgame.profiles))
    assert np.setdiff1d(full_reduced_sample_profiles,
                        full_profiles).size == 0, \
        ("full sample game did not have data for all profiles required of "
         "reduced")
    assert np.setxor1d(full_reduced_profiles,
                       full_reduced_sample_profiles).size == 0, \
        "sample game didn't produce identical results"
예제 #10
0
def test_sgboot_1():
    with tempfile.NamedTemporaryFile('w') as mixed, \
            tempfile.NamedTemporaryFile('w') as game:
        sgame = gamegen.add_noise(gamegen.role_symmetric_game([2, 3], [4, 3]),
                                  20)
        serial = gamegen.serializer(sgame)
        json.dump(serial.to_samplegame_json(sgame), game)
        game.flush()

        profs = [serial.to_prof_json(sgame.uniform_mixture())]
        json.dump(profs, mixed)
        mixed.flush()

        run('sgboot', '-i', game.name, mixed.name, '-o/dev/null')
예제 #11
0
def test_mixture_regret(players, strategies):
    num_mixes = 5
    num_boots = 200
    game = gamegen.add_noise(gamegen.role_symmetric_game(players, strategies),
                             1, 3)
    mixes = game.random_mixtures(num_mixes)
    boots = bootstrap.mixture_regret(game, mixes, num_boots, processes=1)
    assert boots.shape == (num_mixes, num_boots)
    assert np.all(boots >= 0)

    perc_boots = bootstrap.mixture_regret(game, mixes, num_boots, [2.5, 97.5],
                                          processes=1)
    assert perc_boots.shape == (num_mixes, 2)
    assert np.all(perc_boots >= 0)
예제 #12
0
def test_learning():
    with tempfile.NamedTemporaryFile('w') as game:
        sgame = gamegen.add_noise(gamegen.role_symmetric_game([2, 2], [3, 3]),
                                  10)
        serial = gamegen.game_serializer(sgame)
        json.dump(sgame.to_json(serial), game)
        game.flush()

        assert not subprocess.run([GA, 'learning', '-i', game.name,
                                   '-o/dev/null', '-p1', '--dist-thresh',
                                   '1e-3', '-r1e-3', '-t1e-3',
                                   '--rand-restarts', '0', '-m10000',
                                   '-c1e-8']).returncode
        game.seek(0)
        assert not subprocess.run([GA, 'learning'], stdin=game).returncode
예제 #13
0
def test_drop_profiles(players, strategies):
    game = gamegen.role_symmetric_game(players, strategies)
    # Since independent drops might drop nothing, we keep nothing
    dropped = gamegen.drop_profiles(game, 0)
    assert dropped.is_empty(), "didn't drop any profiles"
    # 40% mean even one profile games will be incomplete
    dropped = gamegen.drop_profiles(game, 0.4, independent=False)
    assert not dropped.is_complete(), "didn't drop any profiles"

    sgame = gamegen.add_noise(game, 3)
    dropped = gamegen.drop_profiles(sgame, 0)
    assert dropped.is_empty(), "didn't drop any profiles"
    # 40% mean even one profile games will be incomplete
    dropped = gamegen.drop_profiles(sgame, 0.4, independent=False)
    assert not dropped.is_complete(), "didn't drop any profiles"
예제 #14
0
def test_sgboot_2():
    with tempfile.NamedTemporaryFile('w') as mixed:
        sgame = gamegen.add_noise(gamegen.role_symmetric_game([2, 3], [4, 3]),
                                  20)
        serial = gamegen.serializer(sgame)
        game_str = json.dumps(serial.to_samplegame_json(sgame))

        profs = [serial.to_prof_json(sgame.uniform_mixture())]
        json.dump(profs, mixed)
        mixed.flush()

        string, _ = run('sgboot', mixed.name, '-tsurplus', '--processes', '1',
                        '-n21', '-p', '5', '95', '-m', input=game_str)
        data = json.loads(string)
        assert all(j.keys() == {'5', '95', 'mean'} for j in data)
        assert all(j['5'] <= j['95'] for j in data)
예제 #15
0
def test_drop_samples(players, strategies):
    game = gamegen.role_symmetric_game(players, strategies)
    num_samples = 10000 // game.num_profiles
    game = gamegen.add_noise(game, num_samples)
    # Since independent drops might drop nothing, we keep nothing
    dropped = gamegen.drop_samples(game, 0)
    assert dropped.is_empty(), "didn't drop any profiles"
    # 40% mean even one profile games will be incomplete
    dropped = gamegen.drop_samples(game, 1)
    assert (dropped.is_complete() and
            np.all(dropped.num_samples == [num_samples]))
    # We drop half of samples, meaning is highly unlikely the game is complete
    # or empty, but these "can" still happen
    dropped = gamegen.drop_samples(game, .5)
    assert (not dropped.is_complete() or
            not np.all(dropped.num_samples == [num_samples]))
    assert not dropped.is_empty()
예제 #16
0
def test_sgboot():
    with tempfile.NamedTemporaryFile('w') as mixed, \
            tempfile.NamedTemporaryFile('w') as game:
        sgame = gamegen.add_noise(gamegen.role_symmetric_game([2, 3], [4, 3]),
                                  20)
        serial = gamegen.game_serializer(sgame)
        json.dump(sgame.to_json(serial), game)
        game.flush()

        profs = [serial.to_prof_json(sgame.uniform_mixture())]
        json.dump(profs, mixed)
        mixed.flush()

        assert not subprocess.run([GA, 'sgboot', '-i', game.name, mixed.name,
                                   '-o/dev/null']).returncode
        game.seek(0)
        assert not subprocess.run([GA, 'sgboot', mixed.name, '-tsurplus',
                                   '--processes', '1', '-n21', '-p', '5', '95',
                                   '-m'], stdin=game).returncode
예제 #17
0
def test_sample_game_to_str():
    base = gamegen.role_symmetric_game([2, 1], [1, 2])
    serial = gamegen.game_serializer(base)

    game = gamegen.add_noise(base, 3)
    expected = ('SampleGame:\n    Roles: r0, r1\n    Players:\n        2x r0\n'
                '        1x r1\n    Strategies:\n        r0:\n            s0\n'
                '        r1:\n            s0\n            s1\n'
                'payoff data for 2 out of 2 profiles\n'
                '3 observations per profile')
    assert game.to_str(serial) == expected

    game = rsgame.SampleGame(base)
    expected = ('SampleGame:\n    Roles: r0, r1\n    Players:\n        2x r0\n'
                '        1x r1\n    Strategies:\n        r0:\n            s0\n'
                '        r1:\n            s0\n            s1\n'
                'payoff data for 2 out of 2 profiles\n'
                '1 observation per profile')
    assert game.to_str(serial) == expected

    game = rsgame.SampleGame(rsgame.BaseGame(base))
    expected = ('SampleGame:\n    Roles: r0, r1\n    Players:\n        2x r0\n'
                '        1x r1\n    Strategies:\n        r0:\n            s0\n'
                '        r1:\n            s0\n            s1\n'
                'payoff data for 0 out of 2 profiles\n'
                'no observations')
    assert game.to_str(serial) == expected

    profiles = [[2, 1, 0],
                [2, 0, 1]]
    spayoffs = [
        [[[1], [2], [0]]],
        [[[3, 4], [0] * 2, [5, 6]]],
    ]
    game = rsgame.SampleGame(base, profiles, spayoffs)
    expected = ('SampleGame:\n    Roles: r0, r1\n    Players:\n        2x r0\n'
                '        1x r1\n    Strategies:\n        r0:\n            s0\n'
                '        r1:\n            s0\n            s1\n'
                'payoff data for 2 out of 2 profiles\n'
                '1 to 2 observations per profile')
    assert game.to_str(serial) == expected
예제 #18
0
def test_hierarchical(keep_prob, game_desc):
    players, strategies, red_players = game_desc
    # Create game and reduction
    game = gamegen.role_symmetric_game(players, strategies)
    game = gamegen.drop_profiles(game, keep_prob)
    sgame = gamegen.add_noise(game, 1, 3)
    red = reduction.Hierarchical(strategies, players, red_players)

    # Try to reduce game
    assert rsgame.basegame_copy(game) == red.full_game
    assert red.reduce_game(rsgame.basegame_copy(game)) == red.red_game
    red_game = red.reduce_game(game)
    red_sgame = red.reduce_game(sgame)

    # Assert that reducing all profiles covers reduced game
    reduced_full_profiles = utils.axis_to_elem(
        red.reduce_profiles(game.profiles))
    reduced_profiles = utils.axis_to_elem(red_game.profiles)
    assert np.setxor1d(reduced_profiles, reduced_full_profiles).size == 0, \
        "reduced game contained profiles it shouldn't have"
    reduced_sample_profiles = utils.axis_to_elem(red_sgame.profiles)
    assert np.setxor1d(reduced_sample_profiles,
                       reduced_full_profiles).size == 0, \
        "reduced game contained profiles it shouldn't have"

    # Assert that all contributing profiles are in the expansion of the reduced
    # game
    full_profiles = utils.axis_to_elem(game.profiles)
    full_reduced_profiles = utils.axis_to_elem(
        red.expand_profiles(red_game.profiles))
    assert np.setdiff1d(full_reduced_profiles, full_profiles).size == 0, \
        "full game did not have data for all profiles required of reduced"
    full_reduced_sample_profiles = utils.axis_to_elem(
        red.expand_profiles(red_sgame.profiles))
    assert np.setdiff1d(full_reduced_sample_profiles,
                        full_profiles).size == 0, \
        "full game did not have data for all profiles required of reduced"
    assert np.setxor1d(full_reduced_profiles,
                       full_reduced_sample_profiles).size == 0, \
        "sample game didn't produce identical results"
예제 #19
0
def test_sample_game_function(game_size, samples):
    base = gamegen.role_symmetric_game(*game_size)
    game = gamegen.add_noise(base, 1, samples)

    # Test constructors
    game2 = rsgame.SampleGame(game)
    assert not np.may_share_memory(game.profiles, game2.profiles)
    assert not np.may_share_memory(game.payoffs, game2.payoffs)
    assert not any(np.may_share_memory(sp, sp2) for sp, sp2
                   in zip(game.sample_payoffs, game2.sample_payoffs))
    assert np.all(game.profiles == game2.profiles)
    assert np.all(game.payoffs == game2.payoffs)
    assert all(np.all(sp == sp2) for sp, sp2
               in zip(game.sample_payoffs, game2.sample_payoffs))

    game3 = rsgame.SampleGame(base)
    assert not np.may_share_memory(base.profiles, game3.profiles)
    assert not np.may_share_memory(base.payoffs, game3.payoffs)
    assert np.all(base.profiles == game3.profiles)
    assert np.all(base.payoffs == game3.payoffs)
    assert np.all(game3.num_samples == 1)

    game4 = rsgame.SampleGame(rsgame.BaseGame(*game_size))
    assert game4.is_empty()

    game5 = rsgame.SampleGame(*game_size)
    assert game5.is_empty()

    game5 = rsgame.SampleGame(game.num_players, game.num_strategies,
                              game.profiles, game.sample_payoffs)

    # Test that various methods can be called
    assert (np.all(1 <= game.num_samples) and
            np.all(game.num_samples <= samples))
    game.resample()
    game.resample(1)
    game.remean()

    assert repr(game) is not None
예제 #20
0
def test_samplegame_resample():
    game = gamegen.role_symmetric_game([1, 2, 3], [4, 3, 2])
    game = gamegen.add_noise(game, 1, 20)

    payoffs = game.payoffs.copy()
    min_values = game.min_payoffs().copy()
    max_values = game.max_payoffs().copy()

    game.resample()

    # This isn't guaranteed to be true, but they're highly unlikely
    assert np.any(payoffs != game.payoffs), \
        "resampling didn't change payoffs"

    game.remean()

    assert np.allclose(payoffs, game.payoffs), \
        "remeaning didn't reset payoffs properly"
    assert np.allclose(min_values, game.min_payoffs()), \
        "remeaning didn't reset minimum payoffs properly"
    assert np.allclose(max_values, game.max_payoffs()), \
        "remeaning didn't reset minimum payoffs properly"
예제 #21
0
def test_json_copy_sample_game(game_size, samples):
    base = gamegen.role_symmetric_game(*game_size)
    game1 = gamegen.add_noise(base, 1, samples)
    serial = gamegen.game_serializer(game1)
    game2, _ = gameio.read_sample_game(game1.to_json(serial))
    assert game1 == game2