API

ConstrainedStrategicEquilibrium.AsymmetricAfrprogsCSEProblemType
struct AsymmetricAfrprogsCSEProblem <: ConstrainedStrategicEquilibrium.AsymmetricCSEProblem

The asymmetric CSE problem adapted from the Fortran code released by Armantier et al. alongside their paper, "Approximation of Nash equilibria in Bayesian games" [1].

This problem can have either 2 or 4 players. In the case of 4 players, players 1 and 2 must have the same distribution and players 3 and 4 must have the same distribution.

Important: the two player version may not be working correctly and a warning will be printed if you try to run with two players.

Note regarding the solver: cdf does not seem to support dual numbers so you may need to specify a different option for autodiff, e.g. autodiff=AutoFiniteDiff(), instead of the default ForwardDiff().

Parameters can be passed in as keyword arguments or can be omitted to accept the default values.

  • rng::Random.AbstractRNG: Random number generator to use during data generation (default rng is seeded with 642867)

  • mc::Int64: Number of Monte Carlo steps (default is 10000)

  • np::Int64: Number of players, which must be 2 or 4 currently (default is 4)

  • distributions::Vector{Distributions.UnivariateDistribution}: Distributions to use, which should be a Vector of length 2 or 4. With 4 players, the first 2 players and second 2 players must have the same distributions respectively.

  • inin::Int64: Initial value for n (default is 16)

  • maxn::Int64: Maximum value for n (default is 17)

  • knot_refinement_strategy::Symbol: Knot refinement strategy. Can be :steepest_slope, :highest_curvature, :even_spacing, or :double_knot. (default is :steepest_slope)

  • legacy_output::Bool: Write txt and csv files with solution info (default is False, most of this info is included in the solution objects that get return from compute_cse)

  • solver::Union{Nothing, SciMLBase.AbstractNonlinearAlgorithm}: The solver to use (default is to use Broyden(; init_jacobian=Val(:true_jacobian), autodiff=AutoFiniteDiff()))

  • solver_kwargs::NamedTuple: Keyword arguments to pass to the solve command, such as abstol, reltol, maxiters, etc. Add show_trace=Val(true) to output extra info from the solver.

  • solver_initial_guess::Union{Nothing, Vector{Float64}}: Initial guess to pass to the solver, if not provided use a default initial guess (must be length 2 * inin - 1)

  • initial_knots::Union{Nothing, Vector{Float64}}: Initial knot positions to use, if not provided use a default initial guess (must be length inin + 1)

References

  • [1] Armantier et al. Journal of Applied Econometrics, 23 (2008)
source
ConstrainedStrategicEquilibrium.AsymmetricCSESolutionType
mutable struct AsymmetricCSESolution <: ConstrainedStrategicEquilibrium.CSESolution

Contains the solution to the asymmetric CSE problem.

  • cse::DataFrames.DataFrame: A DataFrame containing the CSE and BNE evaluated at the given points

  • resid::Float64: Norm of the derivatives

  • knot::Dict{Symbol, DataFrames.DataFrame}: The knots for both bidders

  • alph_bet::Dict{Symbol, DataFrames.DataFrame}: Alpha and beta values for the piecewise linear functions for both bidders

  • x_f::Dict{Symbol, DataFrames.DataFrame}: x values and derivatives at the final point

  • norm_derivatives::Dict{Symbol, Float64}: Norm of the derivatives for each player

  • success::Bool: Whether the calculation was successful or not

  • nfeval::Int64: Number of function evaluations

  • njacs::Int64: Number of Jacobians created during the solve

  • nfactors::Int64: Number of factorisations of the Jacobian required for the solve

  • nsolve::Int64: Number of linear solves required for the solve

  • nsteps::Int64: Total number of iterations for the nonlinear solver

  • c_1::Dict{Symbol, Float64}: Stop criteria C_1 (comparison of CSE with previous n value) for each player

  • c_2::Float64: Stop criteria C_2 (norm of the residual)

  • problem::ConstrainedStrategicEquilibrium.AsymmetricCSEProblem: The problem that this solution was generated for

  • n::Int64: The value of n used in this solution

  • u::Array{Float64}: The data used in generating the solution

  • solver_solution::Union{Nothing, SciMLBase.NonlinearSolution}: The solution object returned by the solver

source
ConstrainedStrategicEquilibrium.SymmetricAfrprogsCSEProblemType
struct SymmetricAfrprogsCSEProblem <: ConstrainedStrategicEquilibrium.SymmetricCSEProblem

The symmetric CSE problem adapted from the Fortran code released by Armantier et al. alongside their paper, "Approximation of Nash equilibria in Bayesian games" [1].

Parameters can be passed in as keyword arguments or can be omitted to accept the default values.

  • rng::Random.AbstractRNG: Random number generator to use during data generation (default rng is seeded with 642867)

  • mc::Int64: Number of Monte Carlo steps (default is 10000)

  • np::Int64: Number of players (default is 2)

  • distribution::Distributions.UnivariateDistribution: Distribution to use (default is Beta(3, 3))

  • inin::Int64: Initial value for n (default is 2)

  • maxn::Int64: Maximum value for n (default is 16)

  • knot_refinement_strategy::Symbol: Knot refinement strategy. Can be :highest_curvature or :even_spacing. (default is :highest_curvature)

  • legacy_output::Bool: Write txt and csv files with solution info

  • solver::Union{Nothing, SciMLBase.AbstractNonlinearAlgorithm}: The solver to use (default is to use the default solver from NonlinearSolve.jl)

  • solver_kwargs::NamedTuple: Keyword arguments to pass to the solve command, such as abstol, reltol, maxiters, etc.

  • solver_initial_guess::Union{Nothing, Vector{Float64}}: Initial guess to pass to the solver, if not provided use a default initial guess (must be length inin)

  • initial_knots::Union{Nothing, Vector{Float64}}: Initial knot positions to use (must be length inin + 1, start with 0.0, and end with 1.0)

Examples

julia> prob = SymmetricAfrprogsCSEProblem()
SymmetricAfrprogsCSEProblem(np=4, mc=10000, n=2..16, Distributions.Beta{Float64}(α=3.0, β=3.0))

julia> prob = SymmetricAfrprogsCSEProblem(mc = 1000, maxn = 12, distribution = Beta(3, 4))
SymmetricAfrprogsCSEProblem(np=4, mc=1000, n=2..12, Distributions.Beta{Float64}(α=3.0, β=4.0))

References

  • [1] Armantier et al. Journal of Applied Econometrics, 23 (2008)
source
ConstrainedStrategicEquilibrium.SymmetricCSESolutionType
mutable struct SymmetricCSESolution <: ConstrainedStrategicEquilibrium.CSESolution

Contains the solution to the CSE problem.

  • cse::DataFrames.DataFrame: A DataFrame containing the CSE and BNE evaluated at the given points. Columns names are x, CSE(x) and BNE(x).

  • mse::Float64: Mean squared error of the CSE compared to the BNE

  • resid::Float64: Norm of the derivatives

  • knot::DataFrames.DataFrame

  • alph_bet::DataFrames.DataFrame

  • x_f::DataFrames.DataFrame

  • success::Bool: Whether the calculation was successful or not

  • c_1::Float64: Stop criteria C_1 (comparison of the CSE at the current value of n with the CSE at the previous value of n)

  • c_2::Float64: Stop criteria C_2 (norm of the residual)

  • problem::ConstrainedStrategicEquilibrium.SymmetricCSEProblem: The problem that this solution was generated for

  • n::Int64: The value of n used in this solution

  • u::Array{Float64}: The data used in generating the solution

  • solver_solution::Union{Nothing, SciMLBase.NonlinearSolution}: The solution object returned by the solver

source
ConstrainedStrategicEquilibrium.SymmetricJaePoly1CSEProblemType
struct SymmetricJaePoly1CSEProblem <: ConstrainedStrategicEquilibrium.SymmetricCSEProblem

The jae_poly_1 symmetric CSE problem from Computer_Code_CSE based on the paper by Armantier et al., "Approximation of Nash equilibria in Bayesian games" [1].

Parameters can be passed in as keyword arguments or can be omitted to accept the default values.

  • rng::Random.AbstractRNG: Random number generator to use during data generation (default rng is seeded with 642867)

  • mc::Int64: Number of Monte Carlo steps (default is 10000)

  • np::Int64: Number of players (default is 4)

  • distribution::Distributions.UnivariateDistribution: Distribution to use (default is Kumaraswamy(2.5, 3.5))

  • inin::Int64: Initial value for n (default is 1)

  • maxn::Int64: Maximum value for n (default is 12)

  • legacy_output::Bool: Write txt and csv files with solution info (default is false)

  • solver::Union{Nothing, SciMLBase.AbstractNonlinearAlgorithm}: The solver to use (default is to use the default set by NonlinearSolve.jl)

  • solver_kwargs::NamedTuple: Keyword arguments to pass to the solve command, such as abstol, reltol, maxiters, etc.

  • solver_initial_guess::Union{Nothing, Vector{Float64}}: Initial guess to pass to the solver, if not provided use a default initial guess (must be length inin)

Examples

julia> prob = SymmetricJaePoly1CSEProblem()
SymmetricJaePoly1CSEProblem(np=4, mc=10000, n=1..12, Distributions.Kumaraswamy{Float64}(a=2.5, b=3.5))

julia> prob = SymmetricJaePoly1CSEProblem(np=2, mc=1000, maxn=8, distribution=Beta(3, 4))
SymmetricJaePoly1CSEProblem(np=2, mc=1000, n=1..8, Distributions.Beta{Float64}(α=3.0, β=4.0))

References

  • [1] Armantier et al. Journal of Applied Econometrics, 23 (2008)
source
ConstrainedStrategicEquilibrium.compute_cseMethod
compute_cse(
    cse_problem::AsymmetricAfrprogsCSEProblem,
    u::Array{Float64}
) -> Vector{ConstrainedStrategicEquilibrium.AsymmetricCSESolution}

Specific implementation of compute_cse for the afr-progs asymmetric case.

Call this function if you have already manually validated the problem and generated the data. The data must have shape (cse_problem.mc, cse_problem.np).

source
ConstrainedStrategicEquilibrium.compute_cseMethod
compute_cse(
    cse_problem::ConstrainedStrategicEquilibrium.CSEProblem
) -> Union{Vector{ConstrainedStrategicEquilibrium.AsymmetricCSESolution}, Vector{ConstrainedStrategicEquilibrium.SymmetricCSESolution}}

Solve the given CSE problem.

This is a wrapper function that will first validate the problem and generate the data before solving the CSE problem and returning the vector of solutions.

Examples

julia> prob = SymmetricJaePoly1CSEProblem()
SymmetricJaePoly1CSEProblem(np=4, mc=10000, n=1..12, Distributions.Kumaraswamy{Float64}(a=2.5, b=3.5))

julia> solutions = compute_cse(prob)
[ Info: mean and std player 1: 0.4957361972625512, 0.18748491448182267
[ Info: mean and std player 2: 0.5000858627485552, 0.18774978658869976
[ Info: mean and std player 3: 0.496651263173003, 0.18645006296589822
[ Info: mean and std player 4: 0.5021607262564288, 0.18574470364076182
[ Info: Computing: SymmetricJaePoly1CSEProblem(np=4, mc=10000, n=1..12, Kumaraswamy(a=2.5, b=3.5))
[ Info: SymmetricCSESolution(n=01, MSE=1.63e-03, C_1=NaN, C_2=9.48e-16)
[ Info: SymmetricCSESolution(n=02, MSE=6.62e-04, C_1=5.80e-03, C_2=1.91e-16)
[ Info: SymmetricCSESolution(n=03, MSE=9.80e-05, C_1=3.45e-03, C_2=1.15e-13)
[ Info: SymmetricCSESolution(n=04, MSE=1.75e-05, C_1=5.70e-04, C_2=4.09e-14)
[ Info: SymmetricCSESolution(n=05, MSE=7.30e-05, C_1=1.24e-03, C_2=1.00e-16)
[ Info: SymmetricCSESolution(n=06, MSE=6.51e-05, C_1=1.64e-03, C_2=1.70e-14)
[ Info: SymmetricCSESolution(n=07, MSE=1.95e-05, C_1=1.23e-03, C_2=4.07e-16)
[ Info: SymmetricCSESolution(n=08, MSE=1.94e-06, C_1=5.75e-04, C_2=2.06e-14)
[ Info: SymmetricCSESolution(n=09, MSE=2.59e-07, C_1=8.99e-05, C_2=2.10e-13)
[ Info: SymmetricCSESolution(n=10, MSE=1.17e-06, C_1=1.53e-04, C_2=6.20e-14)
[ Info: SymmetricCSESolution(n=11, MSE=1.53e-06, C_1=1.58e-05, C_2=3.61e-13)
[ Info: SymmetricCSESolution(n=12, MSE=5.77e-07, C_1=4.83e-05, C_2=8.63e-14)
12-element Vector{ConstrainedStrategicEquilibrium.SymmetricCSESolution}:
 SymmetricCSESolution(n=01, MSE=1.63e-03, C_1=NaN, C_2=9.48e-16)
 SymmetricCSESolution(n=02, MSE=6.62e-04, C_1=5.80e-03, C_2=1.91e-16)
 SymmetricCSESolution(n=03, MSE=9.80e-05, C_1=3.45e-03, C_2=1.15e-13)
 SymmetricCSESolution(n=04, MSE=1.75e-05, C_1=5.70e-04, C_2=4.09e-14)
 SymmetricCSESolution(n=05, MSE=7.30e-05, C_1=1.24e-03, C_2=1.00e-16)
 SymmetricCSESolution(n=06, MSE=6.51e-05, C_1=1.64e-03, C_2=1.70e-14)
 SymmetricCSESolution(n=07, MSE=1.95e-05, C_1=1.23e-03, C_2=4.07e-16)
 SymmetricCSESolution(n=08, MSE=1.94e-06, C_1=5.75e-04, C_2=2.06e-14)
 SymmetricCSESolution(n=09, MSE=2.59e-07, C_1=8.99e-05, C_2=2.10e-13)
 SymmetricCSESolution(n=10, MSE=1.17e-06, C_1=1.53e-04, C_2=6.20e-14)
 SymmetricCSESolution(n=11, MSE=1.53e-06, C_1=1.58e-05, C_2=3.61e-13)
 SymmetricCSESolution(n=12, MSE=5.77e-07, C_1=4.83e-05, C_2=8.63e-14)
source
ConstrainedStrategicEquilibrium.compute_cseMethod
compute_cse(
    cse_problem::SymmetricAfrprogsCSEProblem,
    u::Array{Float64}
) -> Vector{ConstrainedStrategicEquilibrium.SymmetricCSESolution}

Specific implementation of compute_cse for the afr-progs symmetric case.

Call this function if you have already manually validated the problem and generated the data. The data must have shape (cse_problem.mc, cse_problem.np).

source
ConstrainedStrategicEquilibrium.compute_cseMethod
compute_cse(
    cse_problem::SymmetricJaePoly1CSEProblem,
    u::Array{Float64}
) -> Vector{ConstrainedStrategicEquilibrium.SymmetricCSESolution}

Specific implementation of compute_cse for the "jae_poly_1" symmetric case.

Call this function if you have already manually validated the problem and generated the data. The data must have shape (cse_problem.mc, cse_problem.np).

source
ConstrainedStrategicEquilibrium.cseplotFunction
cseplot(sol::CSESolution; kwargs...)

Plot the given CSESolution. Some additional keyword arguments are available (in addition to the standard plotting options, such as dpi, title, etc.).

When sol is a SymmetricCSESolution these are (default values shown):

  • cse_label::String = "CSE" - the label for the CSE line
  • cse_colour::Symbol = :1 - the colour for the CSE line
  • add_knots::Bool = true - whether or not to show the knot points on the graph
  • knots_label::String = "Knots" - the label for the knot points
  • add_bne::Bool = true - whether or not to show the BNE on the graph
  • bne_label::String = "BNE" - the label for the BNE line
  • bne_colour::Symbol = :2 - the colour for the BNE line

When sol is an AsymmetricCSESolution the extra options are (default values shown):

  • cse_label::Dict{Symbol, String} = Dict(:bidder1 => "CSE (1), :bidder2 => "CSE (2)") - the labels
  • cse_colour::Dict{Symbol, Symbol} = Dict(:bidder1 => :1, :bidder2 => :2 - the colours for the CSE lines for each bidder (the keys in the dictionary must be as shown)
  • add_knots::Bool = true - whether or not to show the knot points on the graph
  • knots_label::Dict{Symbol, String} = Dict(:bidder1 => "Knots (1)", :bidder2 => "Knots (2)") - the labels for the knot points for each bidder (the keys in the dictionary must be as shown)

In addition to the above options, cseplot will set a default title and xlabel and ylabel, however these can be overriden with keyword arguments.

source
ConstrainedStrategicEquilibrium.run_solverMethod
run_solver(
    cse_problem::ConstrainedStrategicEquilibrium.CSEProblem,
    cse_solution::ConstrainedStrategicEquilibrium.CSESolution,
    objective_function::Function,
    objective_function_params::ConstrainedStrategicEquilibrium.CSESolverParams,
    x::AbstractVector{Float64},
    fvec::AbstractVector{Float64},
    previous_solution::Union{Missing, ConstrainedStrategicEquilibrium.CSESolution}
) -> Any

Helper function to call the solver and attach output/stats to the solution

source
ConstrainedStrategicEquilibrium.validate_cse_problemMethod
validate_cse_problem(
    cse_problem::AsymmetricAfrprogsCSEProblem
)

Check that cse_problem is a valid definition for an asymmetric CSE problem.

This function will throw an error if the problem is not valid, otherwise will return silently.

Examples

julia> prob = AsymmetricAfrprogsCSEProblem();
julia> validate_cse_problem(prob)

julia> prob = AsymmetricAfrprogsCSEProblem(np = 6);
julia> validate_cse_problem(prob)
ERROR: "Only 2 or 4 players are supported currently"
[...]

julia> prob = AsymmetricAfrprogsCSEProblem(maxn = 1);
julia> validate_cse_problem(prob)
ERROR: "Initial value of n cannot be bigger than maximum value of n"
[...]

References

  • [1] Armantier et al. Journal of Applied Econometrics, 23 (2008)
source
ConstrainedStrategicEquilibrium.validate_cse_problemMethod
validate_cse_problem(
    cse_problem::SymmetricAfrprogsCSEProblem
)

Check that cse_problem is a valid definition for a CSE problem.

This function will throw an error if the problem is not valid, otherwise will return silently.

Examples

julia> prob = SymmetricAfrprogsCSEProblem();
julia> validate_cse_problem(prob)

julia> prob = SymmetricAfrprogsCSEProblem(maxn = 1);
julia> validate_cse_problem(prob)
ERROR: "Initial value of n cannot be bigger than maximum value of n"
[...]
source
ConstrainedStrategicEquilibrium.validate_cse_problemMethod
validate_cse_problem(
    cse_problem::SymmetricJaePoly1CSEProblem
)

Check that cse_problem is a valid definition for a CSE problem.

This function will throw an error if the problem is not valid, otherwise will return silently.

Examples

julia> prob = SymmetricJaePoly1CSEProblem();
julia> validate_cse_problem(prob)

julia> prob = SymmetricJaePoly1CSEProblem(maxn = 0);
julia> validate_cse_problem(prob)
ERROR: "Initial value of n cannot be bigger than maximum value of n"
[...]
source