2020// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2121//
2222
23- #include < numeric>
24-
2523#include " gambit.h"
2624#include " core/function.h"
2725#include " liap.h"
@@ -63,45 +61,41 @@ class StrategicLyapunovFunction : public FunctionOnSimplices {
6361inline double sum_player_probs (const MixedStrategyProfile<double > &p_profile,
6462 const GamePlayer &p_player)
6563{
66- auto strategies = p_player->GetStrategies ();
67- return std::accumulate (
68- strategies.cbegin (), strategies.cend (), 0.0 ,
69- [p_profile](double t, const GameStrategy &s) { return t + p_profile[s]; });
64+ return sum_function (p_player->GetStrategies (),
65+ [&p_profile](const auto &s) -> double { return p_profile[s]; });
7066}
7167
7268double StrategicLyapunovFunction::Value (const Vector<double > &v) const
7369{
7470 m_profile = v;
7571 double value = 0 ;
76- // Liapunov function proper - should be replaced with call to profile once
77- // the penalty is removed from that implementation.
78- for (auto player : m_profile.GetGame ()->GetPlayers ()) {
79- for (auto strategy : player->GetStrategies ()) {
80- value += sqr (
81- std::max (m_scale * (m_profile.GetPayoff (strategy) - m_profile.GetPayoff (player)), 0.0 ));
82- }
72+ // Liapunov function proper
73+ for (const auto &player : m_profile.GetGame ()->GetPlayers ()) {
74+ const auto payoff = m_profile.GetPayoff (player);
75+ value += sum_function (player->GetStrategies (), [this , &payoff](const auto &s) -> double {
76+ return sqr (std::max (m_scale * (m_profile.GetPayoff (s) - payoff), 0.0 ));
77+ });
8378 }
8479 // Penalty function for non-negativity constraint for each strategy
85- for (auto player : m_profile.GetGame ()->GetPlayers ()) {
86- for (auto strategy : player->GetStrategies ()) {
87- value += m_penalty * sqr (std::min (m_profile[strategy], 0.0 ));
88- }
89- }
80+ value += m_penalty * sum_function (m_profile.GetGame ()->GetStrategies (), [&](const auto &s) {
81+ return sqr (std::min (m_profile[s], 0.0 ));
82+ });
9083 // Penalty function for sum-to-one constraint for each player
91- for (auto player : m_profile.GetGame ()->GetPlayers ()) {
92- value += m_penalty * sqr (sum_player_probs (m_profile, player) - 1.0 );
93- }
84+ value +=
85+ m_penalty * sum_function (m_profile.GetGame ()->GetPlayers (), [this ](const auto &p) -> double {
86+ return sqr (sum_player_probs (m_profile, p) - 1.0 );
87+ });
9488 return value;
9589}
9690
9791double StrategicLyapunovFunction::LiapDerivValue (const MixedStrategyProfile<double > &p_profile,
9892 const GameStrategy &p_wrt_strategy) const
9993{
10094 double deriv = 0.0 ;
101- for (auto player : m_game->GetPlayers ()) {
102- for ( auto strategy : player-> GetStrategies ()) {
103- const double loss =
104- sqr (m_scale) * (p_profile.GetPayoff (strategy) - p_profile. GetPayoff (player) );
95+ for (const auto & player : m_game->GetPlayers ()) {
96+ const auto payoff = p_profile. GetPayoff (player);
97+ for ( const auto &strategy : player-> GetStrategies ()) {
98+ const double loss = sqr (m_scale) * (p_profile.GetPayoff (strategy) - payoff );
10599 if (loss <= 0.0 ) {
106100 continue ;
107101 }
@@ -121,13 +115,9 @@ double StrategicLyapunovFunction::LiapDerivValue(const MixedStrategyProfile<doub
121115bool StrategicLyapunovFunction::Gradient (const Vector<double > &v, Vector<double > &d) const
122116{
123117 m_profile = v;
124- auto element = d.begin ();
125- for (auto player : m_game->GetPlayers ()) {
126- for (auto strategy : player->GetStrategies ()) {
127- *element = LiapDerivValue (m_profile, strategy);
128- ++element;
129- }
130- }
118+ const auto strategies = m_profile.GetGame ()->GetStrategies ();
119+ std::transform (strategies.begin (), strategies.end (), d.begin (),
120+ [&](const auto &s) -> double { return LiapDerivValue (m_profile, s); });
131121 Project (d, m_game->NumStrategies ());
132122 return true ;
133123}
@@ -137,10 +127,8 @@ namespace {
137127MixedStrategyProfile<double > EnforceNonnegativity (const MixedStrategyProfile<double > &p_profile)
138128{
139129 auto profile = p_profile;
140- for (auto player : p_profile.GetGame ()->GetPlayers ()) {
141- for (auto strategy : player->GetStrategies ()) {
142- profile[strategy] = std::max (profile[strategy], 0.0 );
143- }
130+ for (const auto &strategy : p_profile.GetGame ()->GetStrategies ()) {
131+ profile[strategy] = std::max (profile[strategy], 0.0 );
144132 }
145133 return profile.Normalize ();
146134}
0 commit comments