Skip to content

Commit

Permalink
Further work on agent QRE estimation in Python
Browse files Browse the repository at this point in the history
  • Loading branch information
tturocy committed Apr 11, 2024
1 parent 4844289 commit 94b29b1
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/pygambit/gambit.pxd
Expand Up @@ -498,10 +498,13 @@ cdef extern from "nash.h":
shared_ptr[c_LogitQREMixedBehaviorProfile] LogitBehaviorEstimateHelper(
shared_ptr[c_MixedBehaviorProfileDouble], double, double
) except +
shared_ptr[c_LogitQREMixedBehaviorProfile] LogitBehaviorAtLambdaHelper(
c_Game, double, double, double
) except +
shared_ptr[c_LogitQREMixedStrategyProfile] LogitStrategyEstimateHelper(
shared_ptr[c_MixedStrategyProfileDouble], double, double
) except +
shared_ptr[c_LogitQREMixedStrategyProfile] _logit_atlambda "logit_atlambda"(
shared_ptr[c_LogitQREMixedStrategyProfile] LogitStrategyAtLambdaHelper(
c_Game, double, double, double
) except +
c_List[c_LogitQREMixedStrategyProfile] _logit_principal_branch "logit_principal_branch"(
Expand Down
21 changes: 19 additions & 2 deletions src/pygambit/nash.h
Expand Up @@ -40,6 +40,21 @@ LogitBehaviorEstimateHelper(std::shared_ptr<MixedBehaviorProfile<double>> p_freq
LogitBehaviorEstimate(*p_frequencies, p_firstStep, p_maxAccel));
}

std::shared_ptr<LogitQREMixedBehaviorProfile> LogitBehaviorAtLambdaHelper(const Game &p_game,
double p_lambda,
double p_firstStep,
double p_maxAccel)
{
LogitQREMixedBehaviorProfile start(p_game);
AgentQREPathTracer alg;
alg.SetMaxDecel(p_maxAccel);
alg.SetStepsize(p_firstStep);
// NullBuffer null_buffer;
// std::ostream null_stream(&null_buffer);
return make_shared<LogitQREMixedBehaviorProfile>(
alg.SolveAtLambda(start, std::cout, p_lambda, 1.0));
}

std::shared_ptr<LogitQREMixedStrategyProfile>
LogitStrategyEstimateHelper(std::shared_ptr<MixedStrategyProfile<double>> p_frequencies,
double p_firstStep, double p_maxAccel)
Expand All @@ -48,8 +63,10 @@ LogitStrategyEstimateHelper(std::shared_ptr<MixedStrategyProfile<double>> p_freq
LogitStrategyEstimate(*p_frequencies, p_firstStep, p_maxAccel));
}

std::shared_ptr<LogitQREMixedStrategyProfile> logit_atlambda(const Game &p_game, double p_lambda,
double p_firstStep, double p_maxAccel)
std::shared_ptr<LogitQREMixedStrategyProfile> LogitStrategyAtLambdaHelper(const Game &p_game,
double p_lambda,
double p_firstStep,
double p_maxAccel)
{
LogitQREMixedStrategyProfile start(p_game);
StrategicQREPathTracer alg;
Expand Down
26 changes: 19 additions & 7 deletions src/pygambit/nash.pxi
Expand Up @@ -251,15 +251,15 @@ def _logit_strategy_estimate(profile: MixedStrategyProfileDouble,
return ret


def logit_atlambda(game: Game,
lam: float,
first_step: float = .03,
max_accel: float = 1.1) -> LogitQREMixedStrategyProfile:
"""Compute the first QRE along the principal branch with the given
lambda parameter.
def logit_strategy_atlambda(game: Game,
lam: float,
first_step: float = .03,
max_accel: float = 1.1) -> LogitQREMixedStrategyProfile:
"""Compute the first QRE encountered along the principal branch of the strategic
game corresponding to lambda value `lam`.
"""
ret = LogitQREMixedStrategyProfile()
ret.thisptr = _logit_atlambda(game.game, lam, first_step, max_accel)
ret.thisptr = LogitStrategyAtLambdaHelper(game.game, lam, first_step, max_accel)
return ret


Expand Down Expand Up @@ -328,3 +328,15 @@ def _logit_behavior_estimate(profile: MixedBehaviorProfileDouble,
ret = LogitQREMixedBehaviorProfile(profile.game)
ret.thisptr = LogitBehaviorEstimateHelper(profile.profile, first_step, max_accel)
return ret


def logit_behavior_atlambda(game: Game,
lam: float,
first_step: float = .03,
max_accel: float = 1.1) -> LogitQREMixedBehaviorProfile:
"""Compute the first QRE encountered along the principal branch of the extensive
game corresponding to lambda value `lam`.
"""
ret = LogitQREMixedBehaviorProfile()
ret.thisptr = LogitBehaviorAtLambdaHelper(game.game, lam, first_step, max_accel)
return ret
3 changes: 2 additions & 1 deletion src/pygambit/nash.py
Expand Up @@ -587,5 +587,6 @@ def logit_solve(
)


logit_atlambda = libgbt.logit_atlambda
logit_behavior_atlambda = libgbt.logit_behavior_atlambda
logit_strategy_atlambda = libgbt.logit_strategy_atlambda
logit_principal_branch = libgbt.logit_principal_branch
4 changes: 2 additions & 2 deletions src/pygambit/qre.py
Expand Up @@ -379,7 +379,7 @@ def fit_strategy_fixedpoint(
as a structural model for estimation: The missing manual.
SSRN working paper 4425515.
"""
res = libgbt.logit_strategy_estimate(data)
res = libgbt._logit_strategy_estimate(data)
return LogitQREMixedStrategyFitResult(
data, "fixedpoint", res.lam, res.profile, res.log_like
)
Expand Down Expand Up @@ -517,7 +517,7 @@ def fit_behavior_fixedpoint(
as a structural model for estimation: The missing manual.
SSRN working paper 4425515.
"""
res = libgbt.logit_behavior_estimate(data)
res = libgbt._logit_behavior_estimate(data)
return LogitQREMixedBehaviorFitResult(
data, "fixedpoint", res.lam, res.profile, res.log_like
)
3 changes: 2 additions & 1 deletion src/solvers/logit/efglogit.h
Expand Up @@ -38,6 +38,7 @@ class LogitQREMixedBehaviorProfile {
}
double GetLambda() const { return m_lambda; }
const MixedBehaviorProfile<double> &GetProfile() const { return m_profile; }
double GetLogLike() const { return m_logLike; }

Game GetGame() const { return m_profile.GetGame(); }
size_t BehaviorProfileLength() const { return m_profile.BehaviorProfileLength(); }
Expand Down Expand Up @@ -100,7 +101,7 @@ LogitBehaviorEstimate(const MixedBehaviorProfile<double> &p_frequencies, double
alg.SetMaxDecel(p_maxAccel);
alg.SetStepsize(p_firstStep);
std::ostringstream ostream;
return alg.Estimate(start, p_frequencies, ostream, 1000000.0, 1.0);
return alg.Estimate(start, p_frequencies, ostream, 1.0, 1.0);
}

inline List<MixedBehaviorProfile<double>> LogitBehaviorSolve(const Game &p_game, double p_epsilon,
Expand Down

0 comments on commit 94b29b1

Please sign in to comment.