Exemple #1
0
async def test_sparse_trace():
    """Test that tracing sparsely samples profiles"""
    base = rsgame.empty(4, 3)
    game1 = paygame.game_replace(base, base.all_profiles(),
                                 (base.all_profiles() > 0) * [1, 0, 0])
    game2 = paygame.game_replace(base, base.all_profiles(),
                                 (base.all_profiles() > 0) * [-0.5, 1.5, 0])
    save1 = savesched.savesched(gamesched.gamesched(game1))
    save2 = savesched.savesched(gamesched.gamesched(game2))

    sgame1 = schedgame.schedgame(save1)
    sgame2 = schedgame.schedgame(save2)

    await asyncio.gather(innerloop.inner_loop(sgame1),
                         innerloop.inner_loop(sgame2))

    # Assert that innerloop doesn't scheduler all profiles
    assert save1.get_game().num_profiles == 11
    assert save2.get_game().num_profiles == 11

    ((st1, *_, en1), _), ((st2, *_, en2), _) = (  # pylint: disable=too-many-star-expressions
        await trace.trace_all_equilibria(sgame1, sgame2))

    # Assert that trace found the expected equilibria
    assert np.isclose(st1, 0)
    assert np.isclose(en1, 1 / 3, atol=1e-3)
    assert np.isclose(st2, 1 / 3, atol=1e-3)
    assert np.isclose(en2, 1)

    # Assert that trace didn't need many extra profiles
    assert save1.get_game().num_profiles == 12
    assert save2.get_game().num_profiles == 12
Exemple #2
0
async def test_random_trace_sched(base):
    """Test tracing for random schedulers"""
    sched1 = gamesched.gamesched(gamegen.game_replace(base))
    sched2 = gamesched.gamesched(gamegen.game_replace(base))
    traces = await trace.trace_all_equilibria(
        schedgame.schedgame(sched1), schedgame.schedgame(sched2), style="one"
    )
    verify_complete_traces(traces)
Exemple #3
0
async def test_nash_failure():
    """With regret thresh of zero, nash will fail"""
    game = gamegen.sym_2p2s_known_eq(1 / 3)
    sched = gamesched.gamesched(game)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     regret_thresh=0)
    assert not eqa.size
Exemple #4
0
async def test_innerloop_failures(players, strats, count, when):
    """Test that inner loop handles exceptions during scheduling"""
    game = gamegen.game(players, strats)
    sched = gamesched.gamesched(game)
    esched = tu.ExceptionScheduler(sched, count, when)
    sgame = schedgame.schedgame(esched)
    with pytest.raises(tu.SchedulerException):
        await innerloop.inner_loop(sgame, restricted_game_size=5)
Exemple #5
0
async def test_innerloop_game(base):
    """Test that inner loop works for a game"""
    game = gamegen.samplegame_replace(base)
    sched = gamesched.gamesched(game)
    eqas = await innerloop.inner_loop(schedgame.schedgame(sched))
    verify_dist_thresh(eqas)
    eqag = await innerloop.inner_loop(asyncgame.wrap(game))
    assert utils.allclose_perm(eqas, eqag, atol=1e-3, rtol=1e3)
Exemple #6
0
async def test_random_mean_reg(players, strats):
    """Test that no bootstraps works"""
    game = gamegen.game(players, strats)
    mix = game.random_mixture()
    sched = gamesched.gamesched(game)
    mean, boot = await bootstrap.deviation_payoffs(sched, mix, 20)
    assert mean.shape == (game.num_strats, )
    assert boot.shape == (0, game.num_strats)
Exemple #7
0
async def test_basic_profile(players, strats):
    """Test that basic profile sampling works"""
    game = gamegen.game(players, strats)
    basesched = gamesched.gamesched(game)
    sched = canonsched.canon(basesched)
    assert np.all(sched.num_role_strats > 1)
    pay = await sched.sample_payoffs(sched.random_profile())
    assert pay.size == sched.num_strats
    assert str(sched) == str(basesched)
Exemple #8
0
async def test_basic_profile_aggfn():
    """Test using an action graph game"""
    agame = gamegen.normal_aggfn([4, 3], [3, 4], 5)
    profs = agame.random_profiles(20)

    sched = gamesched.gamesched(agame)
    paylist = await asyncio.gather(*[sched.sample_payoffs(p) for p in profs])
    pays = np.stack(paylist)
    assert np.allclose(pays[profs == 0], 0)
Exemple #9
0
async def test_innerloop_known_eq(eq_prob):
    """Test that inner loop finds known equilibria"""
    game = gamegen.sym_2p2s_known_eq(eq_prob)
    sched = gamesched.gamesched(game)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     devs_by_role=True)
    assert eqa.size, "didn't find equilibrium"
    expected = [eq_prob, 1 - eq_prob]
    assert np.isclose(eqa, expected, atol=1e-3, rtol=1e-3).all(-1).any()
    verify_dist_thresh(eqa)
Exemple #10
0
async def test_basic_profile():
    """Test basic profile"""
    game = gamegen.game([4, 3], [3, 4])
    profs = game.random_profiles(20)

    sched = gamesched.gamesched(game)
    assert rsgame.empty_copy(sched) == rsgame.empty_copy(game)
    paylist = await asyncio.gather(*[sched.sample_payoffs(p) for p in profs])
    pays = np.stack(paylist)
    assert np.allclose(pays[profs == 0], 0)
    assert str(sched) == repr(game)
Exemple #11
0
async def test_backups_used():
    """Test that outerloop uses backups

    Since restricted game size is 1, but the only equilibria has support two,
    this must use backups to find an equilibrium."""
    sgame = gamegen.sym_2p2s_known_eq(0.5)
    sched = gamesched.gamesched(sgame)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     restricted_game_size=1)
    assert eqa.size, "didn't find equilibrium"
    expected = [0.5, 0.5]
    assert np.isclose(eqa, expected, atol=1e-3, rtol=1e-3).all(-1).any()
    verify_dist_thresh(eqa)
Exemple #12
0
async def test_duplicate_prof():
    """Test that duplicate profiles can be scheduled"""
    game = gamegen.game([4, 3], [3, 4])
    profs = game.random_profiles(20)

    sched = gamesched.gamesched(game)
    paylist1 = await asyncio.gather(*[sched.sample_payoffs(p) for p in profs])
    pays1 = np.stack(paylist1)
    paylist2 = await asyncio.gather(*[sched.sample_payoffs(p) for p in profs])
    pays2 = np.stack(paylist2)
    assert np.allclose(pays1[profs == 0], 0)
    assert np.allclose(pays2[profs == 0], 0)
    assert np.allclose(pays1, pays2)
Exemple #13
0
async def test_random_pure_boot_reg(players, strats):
    """Test that bootstrap works for pure mixtures"""
    game = gamegen.game(players, strats)
    sched = gamesched.gamesched(game)
    for mix in game.pure_mixtures():
        devs = game.deviation_payoffs(mix)
        mean, boot = await bootstrap.deviation_payoffs(sched,
                                                       mix,
                                                       20,
                                                       boots=101)
        assert np.allclose(devs, mean)
        assert np.allclose(devs, boot)
        assert mean.shape == (game.num_strats, )
        assert boot.shape == (101, game.num_strats)
Exemple #14
0
async def test_random_boot_reg(players, strats):
    """Test that bootstrap works for random mixtures"""
    game = gamegen.game(players, strats)
    mix = game.random_mixture()
    devs = game.deviation_payoffs(mix)
    sched = gamesched.gamesched(game)
    mean, boot = await bootstrap.deviation_payoffs(sched,
                                                   mix,
                                                   20,
                                                   boots=101,
                                                   chunk_size=5)
    assert mean.shape == (game.num_strats, )
    assert boot.shape == (101, game.num_strats)
    # These aren't guaranteed to be false, but it's incredibly unlikely
    assert not np.allclose(devs, mean)
    assert not np.allclose(devs, boot)