@@ -51,9 +51,9 @@ Vector<double> ProfileToPoint(const LogitQREMixedStrategyProfile &p_profile)
5151
5252double LogLike (const Vector<double > &p_frequencies, const Vector<double > &p_point)
5353{
54- return std::inner_product (p_frequencies. begin (), p_frequencies. end (), p_point. begin (), 0.0 ,
55- std::plus<>(),
56- [](double freq, double prob) { return freq * std::log (prob); });
54+ return std::inner_product (
55+ p_frequencies. begin (), p_frequencies. end (), p_point. begin (), 0.0 , std::plus<>(),
56+ [](const double freq, const double prob) { return freq * std::log (prob); });
5757}
5858
5959double DiffLogLike (const Vector<double > &p_frequencies, const Vector<double > &p_tangent)
@@ -77,7 +77,9 @@ class Equation {
7777
7878 virtual double Value (const MixedStrategyProfile<double > &p_profile,
7979 const Vector<double > &p_strategyValues, double p_lambda) const = 0;
80- virtual void Gradient (const MixedStrategyProfile<double > &p_profile, double p_lambda,
80+ virtual void Gradient (const MixedStrategyProfile<double > &p_profile,
81+ const Vector<double > &p_strategyValues,
82+ const Matrix<double > &p_strategyDerivs, double p_lambda,
8183 Vector<double > &p_gradient) const = 0;
8284};
8385
@@ -94,6 +96,7 @@ class EquationSystem {
9496 const Game &m_game;
9597 mutable MixedStrategyProfile<double > m_profile;
9698 mutable Vector<double > m_strategyValues;
99+ mutable Matrix<double > m_strategyDerivs;
97100};
98101
99102class SumToOneEquation final : public Equation {
@@ -120,8 +123,9 @@ class SumToOneEquation final : public Equation {
120123 ~SumToOneEquation () override = default ;
121124 double Value (const MixedStrategyProfile<double > &p_profile,
122125 const Vector<double > &p_strategyValues, double p_lambda) const override ;
123- void Gradient (const MixedStrategyProfile<double > &p_profile, double p_lambda,
124- Vector<double > &p_gradient) const override ;
126+ void Gradient (const MixedStrategyProfile<double > &p_profile,
127+ const Vector<double > &p_strategyValues, const Matrix<double > &p_strategyDerivs,
128+ double p_lambda, Vector<double > &p_gradient) const override ;
125129};
126130
127131double SumToOneEquation::Value (const MixedStrategyProfile<double > &p_profile,
@@ -134,7 +138,9 @@ double SumToOneEquation::Value(const MixedStrategyProfile<double> &p_profile,
134138 return value;
135139}
136140
137- void SumToOneEquation::Gradient (const MixedStrategyProfile<double > &p_profile, double p_lambda,
141+ void SumToOneEquation::Gradient (const MixedStrategyProfile<double > &p_profile,
142+ const Vector<double > &p_strategyValues,
143+ const Matrix<double > &p_strategyDerivs, double p_lambda,
138144 Vector<double > &p_gradient) const
139145{
140146 p_gradient = 0.0 ;
@@ -169,8 +175,9 @@ class RatioEquation final : public Equation {
169175 ~RatioEquation () override = default ;
170176 double Value (const MixedStrategyProfile<double > &p_profile,
171177 const Vector<double > &p_strategyValues, double p_lambda) const override ;
172- void Gradient (const MixedStrategyProfile<double > &p_profile, double p_lambda,
173- Vector<double > &p_gradient) const override ;
178+ void Gradient (const MixedStrategyProfile<double > &p_profile,
179+ const Vector<double > &p_strategyValues, const Matrix<double > &p_strategyDerivs,
180+ double p_lambda, Vector<double > &p_gradient) const override ;
174181};
175182
176183double RatioEquation::Value (const MixedStrategyProfile<double > &p_profile,
@@ -180,7 +187,9 @@ double RatioEquation::Value(const MixedStrategyProfile<double> &p_profile,
180187 p_lambda * (p_strategyValues[m_strategyIndex] - p_strategyValues[m_refStrategyIndex]));
181188}
182189
183- void RatioEquation::Gradient (const MixedStrategyProfile<double > &p_profile, double p_lambda,
190+ void RatioEquation::Gradient (const MixedStrategyProfile<double > &p_profile,
191+ const Vector<double > &p_strategyValues,
192+ const Matrix<double > &p_strategyDerivs, double p_lambda,
184193 Vector<double > &p_gradient) const
185194{
186195 int col = 1 ;
@@ -197,20 +206,21 @@ void RatioEquation::Gradient(const MixedStrategyProfile<double> &p_profile, doub
197206 }
198207 else {
199208 p_gradient[col] =
200- -p_lambda * p_profile[strategy] *
201- (p_profile.GetPayoffDeriv (m_player->GetNumber (), m_strategy, strategy) -
202- p_profile.GetPayoffDeriv (m_player->GetNumber (), m_refStrategy, strategy));
209+ -p_lambda * p_profile[col] *
210+ (p_strategyDerivs (m_strategyIndex, col) - p_strategyDerivs (m_refStrategyIndex, col));
203211 }
204212 col++;
205213 }
206214 }
207- p_gradient[col] = (p_profile. GetPayoff (m_refStrategy) - p_profile. GetPayoff (m_strategy)) ;
215+ p_gradient[col] = p_strategyValues[m_refStrategyIndex] - p_strategyValues[m_strategyIndex] ;
208216}
209217
210218EquationSystem::EquationSystem (const Game &p_game)
211219 : m_game(p_game), m_profile(p_game->NewMixedStrategyProfile (0.0 )),
212- m_strategyValues(m_profile.MixedProfileLength())
220+ m_strategyValues(m_profile.MixedProfileLength()),
221+ m_strategyDerivs(m_profile.MixedProfileLength(), m_profile.MixedProfileLength())
213222{
223+ m_equations.reserve (m_profile.MixedProfileLength ());
214224 for (const auto &player : m_game->GetPlayers ()) {
215225 m_equations.push_back (std::make_shared<SumToOneEquation>(player));
216226 auto strategies = player->GetStrategies ();
@@ -237,8 +247,22 @@ void EquationSystem::GetJacobian(const Vector<double> &p_point, Matrix<double> &
237247 PointToProfile (m_profile, p_point);
238248 const double lambda = p_point.back ();
239249 Vector<double > column (p_point.size ());
250+ m_strategyDerivs = 0.0 ;
251+ int row = 1 ;
252+ for (const auto &strategy1 : m_game->GetStrategies ()) {
253+ m_strategyValues[row] = m_profile.GetPayoff (strategy1);
254+ int col = 1 ;
255+ for (const auto &strategy2 : m_game->GetStrategies ()) {
256+ if (strategy1->GetPlayer () != strategy2->GetPlayer ()) {
257+ m_strategyDerivs (row, col) =
258+ m_profile.GetPayoffDeriv (strategy1->GetPlayer ()->GetNumber (), strategy1, strategy2);
259+ }
260+ col++;
261+ }
262+ row++;
263+ }
240264 for (size_t i = 1 ; i <= m_equations.size (); i++) {
241- m_equations[i - 1 ]->Gradient (m_profile, lambda, column);
265+ m_equations[i - 1 ]->Gradient (m_profile, m_strategyValues, m_strategyDerivs, lambda, column);
242266 p_matrix.SetColumn (i, column);
243267 }
244268}
@@ -384,10 +408,10 @@ LogitStrategyEstimate(const MixedStrategyProfile<double> &p_frequencies, double
384408 tracer.SetMaxDecel (p_maxAccel);
385409 tracer.SetStepsize (p_firstStep);
386410
387- const Game game;
411+ const Game game = start. GetGame () ;
388412 Vector<double > x (ProfileToPoint (start)), restart (x);
389413 const Vector<double > freq_vector (p_frequencies.GetProbVector ());
390- EstimatorCallbackFunction callback (start. GetGame () , p_frequencies.GetProbVector (), p_observer);
414+ EstimatorCallbackFunction callback (game , p_frequencies.GetProbVector (), p_observer);
391415 EquationSystem system (game);
392416 while (true ) {
393417 tracer.TracePath (
0 commit comments