Skip to content

Commit

Permalink
Use mvn sampler (#40)
Browse files Browse the repository at this point in the history
* FEAT: Add rng::AbstractRNG option to random_game and covariance_game

FIX: Use MVNSampler instead of MvNormal

* TEST: Add test for corner values of rho

* FIX: Removing dependency on Distributions.jl

* FIX: Change the notation to keep consistent with MVNSampler

* FIX: Correct a typo

* FIX: Correct a typo

* FIX: Correct another typo
  • Loading branch information
QBatista authored and oyamad committed Aug 16, 2017
1 parent 2c9e317 commit 5960bfe
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
1 change: 0 additions & 1 deletion src/Games.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module Games
using Clp
using MathProgBase
using QuantEcon
using Distributions

# Geometry packages
using Polyhedra
Expand Down
32 changes: 21 additions & 11 deletions src/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,44 @@ Authors: Daisuke Oyama, Zejin Shi
# Random Games Generating
#
"""
random_game{N}(nums_actions::NTuple{N,Int})
random_game{N}([rng::AbstractRNG], nums_actions::NTuple{N,Int})
Return a random N-player NormalFormGame instance where the
payoffs are drawn independently from the uniform distribution
on [0, 1).
# Arguements
* `rng::AbstractRNG=GLOBAL_RNG`: Random number generator used.
* `nums_actions::NTuple{N,Int}`: Tuple of the numbers of actions,
one for each player.
# Returns
* `::NormalFormGame`: The generated random N-player NormalFormGame.
"""
function random_game{N}(nums_actions::NTuple{N,Int})
function random_game{N}(rng::AbstractRNG, nums_actions::NTuple{N,Int})
if N == 0
throw(ArgumentError("nums_actions must be non-empty"))
end

players::NTuple{N,Player{N,Float64}} =
ntuple(i -> Player(rand(tuple(nums_actions[i:end]...,
ntuple(i -> Player(rand(rng, tuple(nums_actions[i:end]...,
nums_actions[1:i-1]...))),
N)

return NormalFormGame(players)
end

random_game{N}(nums_actions::NTuple{N,Int}) =
random_game(Base.GLOBAL_RNG, nums_actions)

#
# Covariance Games Generating
#
"""
covariance_game{N}(nums_actions::NTuple{N,Int}, rho::Real)
covariance_game{N}([rng::AbstractRNG], nums_actions::NTuple{N,Int},
rho::Real)
Return a random N-player NormalFormGame instance with N>=2 where
the payoff profiles are drawn independently from the standard
Expand All @@ -49,6 +54,7 @@ multi-normal with the covariance of any pair of payoffs equal to
# Arguements
* `rng::AbstractRNG=GLOBAL_RNG`: Random number generator used.
* `nums_actions::NTuple{N,Int}`: Tuple of the numbers of actions,
one for each player.
* `rho::T`: Covariance of a pair of payoff values. Must be in
Expand All @@ -64,25 +70,29 @@ multi-normal with the covariance of any pair of payoffs equal to
Nash Equilibria in Random Games," Games and Economic Behavior
(2000), 274-293.
"""
function covariance_game{N}(nums_actions::NTuple{N,Int}, rho::Real)
function covariance_game{N}(rng::AbstractRNG, nums_actions::NTuple{N,Int},
rho::Real)
if N <= 1
throw(ArgumentError("length of nums_actions must be at least 2"))
end

if !(-1 / (N - 1) < rho < 1)
if !(-1 / (N - 1) <= rho <= 1)
lb = (N == 2) ? "-1" : "-1/$(N-1)"
throw(ArgumentError("rho must be in ($lb, 1)"))
throw(ArgumentError("rho must be in [$lb, 1]"))
end

mu = zeros(N)
C = fill(rho, (N, N))
C[diagind(C)] = ones(N)
Sigma = fill(rho, (N, N))
Sigma[diagind(Sigma)] = ones(N)

d = MvNormal(mu, C)
x = rand(d, prod(nums_actions))
d = MVNSampler(mu, Sigma)
x = rand(rng, d, prod(nums_actions))

payoff_profile_array =
reshape(transpose(x), (nums_actions..., N))

return NormalFormGame(payoff_profile_array)
end

covariance_game{N}(nums_actions::NTuple{N,Int}, rho::Real) =
covariance_game(Base.GLOBAL_RNG, nums_actions, rho)
17 changes: 17 additions & 0 deletions test/test_random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,28 @@

@testset "test covariance game" begin
nums_actions = (2, 3, 4)
N = length(nums_actions)

rho = 0.5
g = covariance_game(nums_actions, rho)
@test g.nums_actions == nums_actions

rho = 1
g = covariance_game(nums_actions, rho)
for a in CartesianRange(nums_actions)
payoff_profile = g[a]
for i in 1:(N-1)
@test payoff_profile[i] payoff_profile[end]
end
end

rho = -1/(N-1)
g = covariance_game(nums_actions, rho)
for a in CartesianRange(nums_actions)
payoff_profile = g[a]
@test sum(payoff_profile) 0 atol=1e-10
end

end

@testset "test random game value error" begin
Expand Down

0 comments on commit 5960bfe

Please sign in to comment.