From 69d864b4f2f36f7f6ba8eaf0ade9457092fc7f32 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Wed, 17 Dec 2025 12:05:33 +0000 Subject: [PATCH 1/3] Set up explicit cache object in mixedstrategyprofile. --- src/games/game.cc | 31 ++++++++++++++++--------------- src/games/stratmixed.h | 22 +++++++++++++++++----- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/games/game.cc b/src/games/game.cc index fd9b91710..c3109a4d7 100644 --- a/src/games/game.cc +++ b/src/games/game.cc @@ -343,17 +343,18 @@ template MixedStrategyProfile MixedStrategyProfile::ToFullSuppor template void MixedStrategyProfile::ComputePayoffs() const { - if (!m_payoffs.empty()) { - // caches (m_payoffs and m_strategyValues) are valid, - // so don't compute anything, simply return + if (m_cache.m_valid) { return; } + Cache newCache; for (const auto &player : m_rep->m_support.GetPlayers()) { - m_payoffs[player] = GetPayoff(player); + newCache.m_payoffs[player] = GetPayoff(player); for (const auto &strategy : m_rep->m_support.GetStrategies(player)) { - m_strategyValues[player][strategy] = GetPayoff(strategy); + newCache.m_strategyValues[player][strategy] = GetPayoff(strategy); } } + newCache.m_valid = true; + m_cache = std::move(newCache); }; template T MixedStrategyProfile::GetLiapValue() const @@ -362,12 +363,11 @@ template T MixedStrategyProfile::GetLiapValue() const ComputePayoffs(); auto liapValue = static_cast(0); - for (auto p : m_payoffs) { - liapValue += std::transform_reduce( - m_strategyValues.at(p.first).begin(), m_strategyValues.at(p.first).end(), - static_cast(0), std::plus(), [&p](const auto &v) -> T { - return sqr(std::max(v.second - p.second, static_cast(0))); - }); + for (const auto &p : m_cache.m_payoffs) { + const auto &values = m_cache.m_strategyValues.at(p.first); + liapValue += sum_function(values, [&](const auto &v) { + return sqr(std::max(v.second - p.second, static_cast(0))); + }); } return liapValue; } @@ -376,13 +376,14 @@ template T MixedStrategyProfile::GetRegret(const GameStrategy &p_st { CheckVersion(); ComputePayoffs(); + auto player = p_strategy->GetPlayer(); T best_other_payoff = maximize_function( filter_if(player->GetStrategies(), [&](const auto &s) { return s != p_strategy; }), [this, &player](const auto &strategy) -> T { - return m_strategyValues.at(player).at(strategy); + return m_cache.m_strategyValues.at(player).at(strategy); }); - return std::max(best_other_payoff - m_strategyValues.at(player).at(p_strategy), + return std::max(best_other_payoff - m_cache.m_strategyValues.at(player).at(p_strategy), static_cast(0)); } @@ -392,9 +393,9 @@ template T MixedStrategyProfile::GetRegret(const GamePlayer &p_play ComputePayoffs(); auto br_payoff = maximize_function(p_player->GetStrategies(), [this, p_player](const auto &strategy) -> T { - return m_strategyValues.at(p_player).at(strategy); + return m_cache.m_strategyValues.at(p_player).at(strategy); }); - return br_payoff - m_payoffs.at(p_player); + return br_payoff - m_cache.m_payoffs.at(p_player); } template T MixedStrategyProfile::GetMaxRegret() const diff --git a/src/games/stratmixed.h b/src/games/stratmixed.h index 0baf680ac..0fe81a405 100644 --- a/src/games/stratmixed.h +++ b/src/games/stratmixed.h @@ -81,9 +81,21 @@ template class MixedStrategyProfileRep { /// independently chooses from among his strategies with specified /// probabilities. template class MixedStrategyProfile { + struct Cache { + bool m_valid{false}; + std::map m_payoffs; + std::map> m_strategyValues; + + void clear() + { + m_valid = false; + m_payoffs.clear(); + m_strategyValues.clear(); + } + }; + std::unique_ptr> m_rep; - mutable std::map m_payoffs; - mutable std::map> m_strategyValues; + mutable Cache m_cache; /// Check underlying game has not changed; raise exception if it has void CheckVersion() const @@ -98,8 +110,7 @@ template class MixedStrategyProfile { /// Reset cache for payoffs and strategy values void InvalidateCache() const { - m_strategyValues.clear(); - m_payoffs.clear(); + m_cache.clear(); m_rep->InvalidateCache(); } @@ -171,7 +182,7 @@ template class MixedStrategyProfile { T &operator[](const GameStrategy &p_strategy) { CheckVersion(); - InvalidateCache(); // NEW + InvalidateCache(); return m_rep->operator[](p_strategy); } @@ -205,6 +216,7 @@ template class MixedStrategyProfile { void SetCentroid() { CheckVersion(); + InvalidateCache(); m_rep->SetCentroid(); } From 6aa65760cefa683a4446336add0b09464cca4e2e Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Wed, 17 Dec 2025 13:45:49 +0000 Subject: [PATCH 2/3] Be much more careful in not mutating MixedStrategyProfileRep --- src/games/gametree.cc | 11 +++++------ src/games/gametree.h | 4 ++-- src/games/stratmixed.h | 39 ++++++++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/games/gametree.cc b/src/games/gametree.cc index c630c50a2..9f6081d6e 100644 --- a/src/games/gametree.cc +++ b/src/games/gametree.cc @@ -57,21 +57,20 @@ std::unique_ptr> TreeMixedStrategyProfileRep::Copy template void TreeMixedStrategyProfileRep::MakeBehavior() const { - if (mixed_behav_profile_sptr.get() == nullptr) { - mixed_behav_profile_sptr = - std::make_shared>(MixedStrategyProfile(Copy())); + if (m_mixedBehavior == nullptr) { + m_mixedBehavior = std::make_shared>(MixedStrategyProfile(Copy())); } } -template void TreeMixedStrategyProfileRep::InvalidateCache() const +template void TreeMixedStrategyProfileRep::OnProfileChanged() const { - mixed_behav_profile_sptr = nullptr; + m_mixedBehavior = nullptr; } template T TreeMixedStrategyProfileRep::GetPayoff(int pl) const { MakeBehavior(); - return mixed_behav_profile_sptr->GetPayoff(mixed_behav_profile_sptr->GetGame()->GetPlayer(pl)); + return m_mixedBehavior->GetPayoff(m_mixedBehavior->GetGame()->GetPlayer(pl)); } template diff --git a/src/games/gametree.h b/src/games/gametree.h index 9c96939f1..798da92fc 100644 --- a/src/games/gametree.h +++ b/src/games/gametree.h @@ -191,10 +191,10 @@ template class TreeMixedStrategyProfileRep : public MixedStrategyProfi T GetPayoffDeriv(int pl, const GameStrategy &, const GameStrategy &) const override; private: - mutable std::shared_ptr> mixed_behav_profile_sptr; + mutable std::shared_ptr> m_mixedBehavior; void MakeBehavior() const; - void InvalidateCache() const override; + void OnProfileChanged() const override; }; } // namespace Gambit diff --git a/src/games/stratmixed.h b/src/games/stratmixed.h index 0fe81a405..45ab8df02 100644 --- a/src/games/stratmixed.h +++ b/src/games/stratmixed.h @@ -42,6 +42,12 @@ template class MixedStrategyProfileRep { void SetCentroid(); std::unique_ptr Normalize() const; + const T &operator[](int i) const { return m_probs[i]; } + T &operator[](int i) + { + OnProfileChanged(); + return m_probs[i]; + } /// Returns the probability the strategy is played const T &operator[](const GameStrategy &p_strategy) const { @@ -50,7 +56,7 @@ template class MixedStrategyProfileRep { /// Returns the probability the strategy is played T &operator[](const GameStrategy &p_strategy) { - InvalidateCache(); + OnProfileChanged(); return m_probs[m_profileIndex.at(p_strategy)]; } /// Set the strategy of the corresponding player to a pure strategy @@ -60,6 +66,17 @@ template class MixedStrategyProfileRep { (*this)[s] = static_cast(0); } (*this)[p_strategy] = static_cast(1); + OnProfileChanged(); + } + void SetProbVector(const Vector &p_vector) + { + m_probs = p_vector; + OnProfileChanged(); + } + void SetProbConstant(const T &c) + { + m_probs = c; + OnProfileChanged(); } virtual T GetPayoff(int pl) const = 0; @@ -72,7 +89,7 @@ template class MixedStrategyProfileRep { return GetPayoffDeriv(p_strategy->GetPlayer()->GetNumber(), p_strategy); } - virtual void InvalidateCache() const {} + virtual void OnProfileChanged() const {} }; /// \brief A probability distribution over strategies in a game @@ -108,11 +125,7 @@ template class MixedStrategyProfile { void ComputePayoffs() const; /// Reset cache for payoffs and strategy values - void InvalidateCache() const - { - m_cache.clear(); - m_rep->InvalidateCache(); - } + void InvalidateCache() const { m_cache.clear(); } public: /// @name Lifecycle @@ -132,13 +145,13 @@ template class MixedStrategyProfile { MixedStrategyProfile &operator=(const Vector &v) { InvalidateCache(); - m_rep->m_probs = v; + m_rep->SetProbVector(v); return *this; } MixedStrategyProfile &operator=(const T &c) { InvalidateCache(); - m_rep->m_probs = c; + m_rep->SetProbConstant(c); return *this; } //@} @@ -162,28 +175,28 @@ template class MixedStrategyProfile { const T &operator[](int i) const { CheckVersion(); - return m_rep->m_probs[i]; + return (*m_rep)[i]; } /// Vector-style access to probabilities T &operator[](int i) { CheckVersion(); InvalidateCache(); - return m_rep->m_probs[i]; + return (*m_rep)[i]; } /// Returns the probability the strategy is played const T &operator[](const GameStrategy &p_strategy) const { CheckVersion(); - return m_rep->operator[](p_strategy); + return (*m_rep)[p_strategy]; } /// Returns the probability the strategy is played T &operator[](const GameStrategy &p_strategy) { CheckVersion(); InvalidateCache(); - return m_rep->operator[](p_strategy); + return (*m_rep)[p_strategy]; } /// Returns the mixed strategy for the player From 64bcd98b296bfcf904ebe7b956cd351c91da94d1 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Wed, 17 Dec 2025 14:04:32 +0000 Subject: [PATCH 3/3] Be even much more careful in not mutating MixedStrategyProfileRep --- src/games/game.cc | 12 ++++++------ src/games/gametable.cc | 31 ++++++++++++++++------------- src/games/gametable.h | 2 +- src/games/stratmixed.h | 36 +++++++++++++++++++++------------- src/pygambit/gambit.pxd | 2 +- src/pygambit/stratmixed.pxi | 4 ++-- src/solvers/liap/nfgliap.cc | 4 ++-- src/solvers/logit/nfglogit.cc | 13 +++++------- src/solvers/simpdiv/simpdiv.cc | 4 ++-- 9 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/games/game.cc b/src/games/game.cc index c3109a4d7..c471bafdf 100644 --- a/src/games/game.cc +++ b/src/games/game.cc @@ -316,7 +316,7 @@ MixedStrategyProfile &MixedStrategyProfile::operator=(const MixedStrategyP template Vector MixedStrategyProfile::GetStrategy(const GamePlayer &p_player) const { CheckVersion(); - auto strategies = m_rep->m_support.GetStrategies(p_player); + auto strategies = m_rep->GetSupport().GetStrategies(p_player); Vector probs(strategies.size()); std::transform(strategies.begin(), strategies.end(), probs.begin(), [this](const GameStrategy &s) { return (*m_rep)[s]; }); @@ -326,12 +326,12 @@ template Vector MixedStrategyProfile::GetStrategy(const GamePlay template MixedStrategyProfile MixedStrategyProfile::ToFullSupport() const { CheckVersion(); - MixedStrategyProfile full(m_rep->m_support.GetGame()->NewMixedStrategyProfile(T(0))); + MixedStrategyProfile full(m_rep->GetSupport().GetGame()->NewMixedStrategyProfile(T(0))); - for (const auto &player : m_rep->m_support.GetGame()->GetPlayers()) { + for (const auto &player : m_rep->GetSupport().GetGame()->GetPlayers()) { for (const auto &strategy : player->GetStrategies()) { full[strategy] = - (m_rep->m_support.Contains(strategy)) ? (*m_rep)[strategy] : static_cast(0); + (m_rep->GetSupport().Contains(strategy)) ? (*m_rep)[strategy] : static_cast(0); } } return full; @@ -347,9 +347,9 @@ template void MixedStrategyProfile::ComputePayoffs() const return; } Cache newCache; - for (const auto &player : m_rep->m_support.GetPlayers()) { + for (const auto &player : m_rep->GetSupport().GetPlayers()) { newCache.m_payoffs[player] = GetPayoff(player); - for (const auto &strategy : m_rep->m_support.GetStrategies(player)) { + for (const auto &strategy : m_rep->GetSupport().GetStrategies(player)) { newCache.m_strategyValues[player][strategy] = GetPayoff(strategy); } } diff --git a/src/games/gametable.cc b/src/games/gametable.cc index 252e5790e..47d856018 100644 --- a/src/games/gametable.cc +++ b/src/games/gametable.cc @@ -103,7 +103,7 @@ Rational TablePureStrategyProfileRep::GetPayoff(const GamePlayer &p_player) cons Rational TablePureStrategyProfileRep::GetStrategyValue(const GameStrategy &p_strategy) const { const auto &player = p_strategy->GetPlayer(); - GameOutcomeRep *outcome = + const GameOutcomeRep *outcome = dynamic_cast(*m_nfg) .m_results[m_index - m_profile.at(player)->m_offset + p_strategy->m_offset]; if (outcome) { @@ -159,17 +159,18 @@ std::unique_ptr> TableMixedStrategyProfileRep::Cop template T TableMixedStrategyProfileRep::GetPayoff(int pl, int index, int current) const { - if (current > static_cast(this->m_support.GetGame()->NumPlayers())) { - const Game game = this->m_support.GetGame(); + if (current > static_cast(this->GetSupport().GetGame()->NumPlayers())) { + const Game game = this->GetSupport().GetGame(); auto &g = dynamic_cast(*game); if (const auto outcome = g.m_results[index]) { - return outcome->GetPayoff(this->m_support.GetGame()->GetPlayer(pl)); + return outcome->GetPayoff(this->GetSupport().GetGame()->GetPlayer(pl)); } return static_cast(0); } T sum = static_cast(0); - for (auto s : this->m_support.GetStrategies(this->m_support.GetGame()->GetPlayer(current))) { + for (auto s : + this->GetSupport().GetStrategies(this->GetSupport().GetGame()->GetPlayer(current))) { if ((*this)[s] != T(0)) { sum += ((*this)[s] * GetPayoff(pl, index + s->m_offset, current + 1)); } @@ -189,15 +190,16 @@ void TableMixedStrategyProfileRep::GetPayoffDeriv(int pl, int const_pl, int c if (cur_pl == const_pl) { cur_pl++; } - if (cur_pl > static_cast(this->m_support.GetGame()->NumPlayers())) { - const Game game = this->m_support.GetGame(); + if (cur_pl > static_cast(this->GetSupport().GetGame()->NumPlayers())) { + const Game game = this->GetSupport().GetGame(); auto &g = dynamic_cast(*game); if (const auto outcome = g.m_results[index]) { - value += prob * outcome->GetPayoff(this->m_support.GetGame()->GetPlayer(pl)); + value += prob * outcome->GetPayoff(this->GetSupport().GetGame()->GetPlayer(pl)); } } else { - for (auto s : this->m_support.GetStrategies(this->m_support.GetGame()->GetPlayer(cur_pl))) { + for (auto s : + this->GetSupport().GetStrategies(this->GetSupport().GetGame()->GetPlayer(cur_pl))) { if ((*this)[s] > T(0)) { GetPayoffDeriv(pl, const_pl, cur_pl + 1, index + s->m_offset, prob * (*this)[s], value); } @@ -221,15 +223,16 @@ void TableMixedStrategyProfileRep::GetPayoffDeriv(int pl, int const_pl1, int while (cur_pl == const_pl1 || cur_pl == const_pl2) { cur_pl++; } - if (cur_pl > static_cast(this->m_support.GetGame()->NumPlayers())) { - const Game game = this->m_support.GetGame(); + if (cur_pl > static_cast(this->GetSupport().GetGame()->NumPlayers())) { + const Game game = this->GetSupport().GetGame(); auto &g = dynamic_cast(*game); if (const auto outcome = g.m_results[index]) { - value += prob * outcome->GetPayoff(this->m_support.GetGame()->GetPlayer(pl)); + value += prob * outcome->GetPayoff(this->GetSupport().GetGame()->GetPlayer(pl)); } } else { - for (auto s : this->m_support.GetStrategies(this->m_support.GetGame()->GetPlayer(cur_pl))) { + for (auto s : + this->GetSupport().GetStrategies(this->GetSupport().GetGame()->GetPlayer(cur_pl))) { if ((*this)[s] > static_cast(0)) { GetPayoffDeriv(pl, const_pl1, const_pl2, cur_pl + 1, index + s->m_offset, prob * (*this)[s], value); @@ -524,7 +527,7 @@ void GameTableRep::RebuildTable() IndexStrategies(); } -void GameTableRep::IndexStrategies() +void GameTableRep::IndexStrategies() const { long offset = 1L; for (auto player : m_players) { diff --git a/src/games/gametable.h b/src/games/gametable.h index 3aab1dd38..38b3d3a05 100644 --- a/src/games/gametable.h +++ b/src/games/gametable.h @@ -40,7 +40,7 @@ class GameTableRep : public GameExplicitRep { /// @name Private auxiliary functions //@{ - void IndexStrategies(); + void IndexStrategies() const; void RebuildTable(); //@} diff --git a/src/games/stratmixed.h b/src/games/stratmixed.h index 45ab8df02..3190036c3 100644 --- a/src/games/stratmixed.h +++ b/src/games/stratmixed.h @@ -29,17 +29,21 @@ namespace Gambit { template class MixedStrategyProfileRep { -public: +protected: Vector m_probs; StrategySupportProfile m_support; /// The index into the strategy profile for a strategy (-1 if not in support) std::map m_profileIndex; unsigned int m_gameversion; +public: explicit MixedStrategyProfileRep(const StrategySupportProfile &); virtual ~MixedStrategyProfileRep() = default; virtual std::unique_ptr Copy() const = 0; + const StrategySupportProfile &GetSupport() const { return m_support; } + unsigned int GetGameVersion() const { return m_gameversion; } + void SetCentroid(); std::unique_ptr Normalize() const; const T &operator[](int i) const { return m_probs[i]; } @@ -68,6 +72,7 @@ template class MixedStrategyProfileRep { (*this)[p_strategy] = static_cast(1); OnProfileChanged(); } + const Vector &GetProbVector() const { return m_probs; } void SetProbVector(const Vector &p_vector) { m_probs = p_vector; @@ -78,7 +83,10 @@ template class MixedStrategyProfileRep { m_probs = c; OnProfileChanged(); } - + unsigned int GetProfileIndex(const GameStrategy &p_strategy) const + { + return m_profileIndex.at(p_strategy); + } virtual T GetPayoff(int pl) const = 0; virtual T GetPayoffDeriv(int pl, const GameStrategy &) const = 0; virtual T GetPayoffDeriv(int pl, const GameStrategy &, const GameStrategy &) const = 0; @@ -117,7 +125,7 @@ template class MixedStrategyProfile { /// Check underlying game has not changed; raise exception if it has void CheckVersion() const { - if (IsInvalidated()) { + if (HasOutdatedGameVersion()) { throw GameStructureChangedException(); } } @@ -161,14 +169,14 @@ template class MixedStrategyProfile { /// Test for the equality of two profiles bool operator==(const MixedStrategyProfile &p_profile) const { - return (m_rep->m_support == p_profile.m_rep->m_support && - m_rep->m_probs == p_profile.m_rep->m_probs); + return (m_rep->GetSupport() == p_profile.m_rep->GetSupport() && + m_rep->GetProbVector() == p_profile.m_rep->GetProbVector()); } /// Test for the inequality of two profiles bool operator!=(const MixedStrategyProfile &p_profile) const { - return (m_rep->m_support != p_profile.m_rep->m_support || - m_rep->m_probs != p_profile.m_rep->m_probs); + return (m_rep->GetSupport() != p_profile.m_rep->GetSupport() || + m_rep->GetProbVector() != p_profile.m_rep->GetProbVector()); } /// Vector-style access to probabilities @@ -202,27 +210,27 @@ template class MixedStrategyProfile { /// Returns the mixed strategy for the player Vector GetStrategy(const GamePlayer &p_player) const; - explicit operator const Vector &() const + const Vector &GetProbVector() const { CheckVersion(); - return m_rep->m_probs; + return m_rep->GetProbVector(); } //@} /// @name General data access //@{ /// Returns the game on which the profile is defined - Game GetGame() const { return m_rep->m_support.GetGame(); } + Game GetGame() const { return m_rep->GetSupport().GetGame(); } /// Returns the support on which the profile is defined const StrategySupportProfile &GetSupport() const { CheckVersion(); - return m_rep->m_support; + return m_rep->GetSupport(); } /// Returns whether the profile has been invalidated by a subsequent revision to the game - bool IsInvalidated() const + bool HasOutdatedGameVersion() const { - return m_rep->m_gameversion != m_rep->m_support.GetGame()->GetVersion(); + return m_rep->GetGameVersion() != m_rep->GetSupport().GetGame()->GetVersion(); } /// Sets all strategies for each player to equal probabilities @@ -243,7 +251,7 @@ template class MixedStrategyProfile { } /// Returns the total number of strategies in the profile - size_t MixedProfileLength() const { return m_rep->m_probs.size(); } + size_t MixedProfileLength() const { return m_rep->GetProbVector().size(); } /// Converts the profile to one on the full support of the game MixedStrategyProfile ToFullSupport() const; diff --git a/src/pygambit/gambit.pxd b/src/pygambit/gambit.pxd index 0234f7920..9c27b87f7 100644 --- a/src/pygambit/gambit.pxd +++ b/src/pygambit/gambit.pxd @@ -342,7 +342,7 @@ cdef extern from "games/stratmixed.h" namespace "Gambit": bool operator==(c_MixedStrategyProfile[T]) except + bool operator!=(c_MixedStrategyProfile[T]) except + c_Game GetGame() except + - bool IsInvalidated() + bool HasOutdatedGameVersion() int MixedProfileLength() except + c_StrategySupportProfile GetSupport() except + c_MixedStrategyProfile[T] Normalize() # except + doesn't compile diff --git a/src/pygambit/stratmixed.pxi b/src/pygambit/stratmixed.pxi index a69ea96ae..276e8030b 100644 --- a/src/pygambit/stratmixed.pxi +++ b/src/pygambit/stratmixed.pxi @@ -574,7 +574,7 @@ class MixedStrategyProfileDouble(MixedStrategyProfile): return obj def _check_validity(self) -> None: - if deref(self.profile).IsInvalidated(): + if deref(self.profile).HasOutdatedGameVersion(): raise GameStructureChangedError() def __len__(self) -> int: @@ -651,7 +651,7 @@ class MixedStrategyProfileRational(MixedStrategyProfile): return obj def _check_validity(self) -> None: - if deref(self.profile).IsInvalidated(): + if deref(self.profile).HasOutdatedGameVersion(): raise GameStructureChangedError() def __len__(self) -> int: diff --git a/src/solvers/liap/nfgliap.cc b/src/solvers/liap/nfgliap.cc index 58c4b73a1..9cbe0b46a 100644 --- a/src/solvers/liap/nfgliap.cc +++ b/src/solvers/liap/nfgliap.cc @@ -151,10 +151,10 @@ LiapStrategySolve(const MixedStrategyProfile &p_start, double p_maxregre ConjugatePRMinimizer minimizer(p.MixedProfileLength()); Vector gradient(p.MixedProfileLength()), dx(p.MixedProfileLength()); double fval; - minimizer.Set(F, static_cast &>(p), fval, gradient, .001, .00001); + minimizer.Set(F, p.GetProbVector(), fval, gradient, .001, .00001); for (int iter = 1; iter <= p_maxitsN; iter++) { - Vector point(p); + Vector point(p.GetProbVector()); if (!minimizer.Iterate(F, point, fval, gradient, dx)) { break; } diff --git a/src/solvers/logit/nfglogit.cc b/src/solvers/logit/nfglogit.cc index 154673f37..fa5ad0282 100644 --- a/src/solvers/logit/nfglogit.cc +++ b/src/solvers/logit/nfglogit.cc @@ -206,17 +206,15 @@ EstimatorCallbackFunction::EstimatorCallbackFunction(const Game &p_game, MixedStrategyObserverFunctionType p_observer) : m_game(p_game), m_frequencies(p_frequencies), m_observer(p_observer), m_bestProfile(p_game->NewMixedStrategyProfile(0.0), 0.0, - LogLike(p_frequencies, static_cast &>( - p_game->NewMixedStrategyProfile(0.0)))) + LogLike(p_frequencies, p_game->NewMixedStrategyProfile(0.0).GetProbVector())) { } void EstimatorCallbackFunction::EvaluatePoint(const Vector &p_point) { const MixedStrategyProfile profile(PointToProfile(m_game, p_point)); - auto qre = LogitQREMixedStrategyProfile( - profile, p_point.back(), - LogLike(m_frequencies, static_cast &>(profile))); + auto qre = LogitQREMixedStrategyProfile(profile, p_point.back(), + LogLike(m_frequencies, profile.GetProbVector())); m_observer(qre); if (qre.GetLogLike() > m_bestProfile.GetLogLike()) { m_bestProfile = qre; @@ -298,9 +296,8 @@ LogitStrategyEstimate(const MixedStrategyProfile &p_frequencies, double tracer.SetStepsize(p_firstStep); Vector x(ProfileToPoint(start)), restart(x); - const Vector freq_vector(static_cast &>(p_frequencies)); - EstimatorCallbackFunction callback( - start.GetGame(), static_cast &>(p_frequencies), p_observer); + const Vector freq_vector(p_frequencies.GetProbVector()); + EstimatorCallbackFunction callback(start.GetGame(), p_frequencies.GetProbVector(), p_observer); while (true) { tracer.TracePath( [&start](const Vector &p_point, Vector &p_lhs) { diff --git a/src/solvers/simpdiv/simpdiv.cc b/src/solvers/simpdiv/simpdiv.cc index b3710ffa5..3ea164fae 100644 --- a/src/solvers/simpdiv/simpdiv.cc +++ b/src/solvers/simpdiv/simpdiv.cc @@ -145,7 +145,7 @@ Rational NashSimpdivStrategySolver::Simplex(MixedStrategyProfile &y, for (size_t i = 1; i <= v.size(); i++) { v[i] = y[i]; } - besty = static_cast &>(y); + besty = y.GetProbVector(); int i = 0; int j, k, h, jj, hh, ii, kk, tot; Rational maxz; @@ -536,7 +536,7 @@ NashSimpdivStrategySolver::Solve(const MixedStrategyProfile &p_start) throw UndefinedException( "Computing equilibria of games with imperfect recall is not supported."); } - Rational d(Integer(1), find_lcd(static_cast &>(p_start))); + Rational d(Integer(1), find_lcd(p_start.GetProbVector())); const Rational scale = p_start.GetGame()->GetMaxPayoff() - p_start.GetGame()->GetMinPayoff(); MixedStrategyProfile y(p_start);