diff --git a/src/solvers/logit/path.cc b/src/solvers/logit/path.cc index 2541ec51f..267d8f914 100644 --- a/src/solvers/logit/path.cc +++ b/src/solvers/logit/path.cc @@ -125,11 +125,12 @@ void NewtonStep(Matrix &q, Matrix &b, Vector &u, Vector< // bifurcation point that the tracing gets stuck there as it is not possible // to find a small enough step size to avoid stepping over the bifurcation // point. -void PathTracer::TracePath( - std::function &, Vector &)> p_function, - std::function &, Matrix &)> p_jacobian, Vector &x, - double &p_omega, TerminationFunctionType p_terminate, CallbackFunctionType p_callback, - CriterionFunctionType p_criterion, CriterionBracketFunctionType p_criterionBracket) const +TracePathResult +PathTracer::TracePath(std::function &, Vector &)> p_function, + std::function &, Matrix &)> p_jacobian, + Vector &x, double &p_omega, TerminationFunctionType p_terminate, + CallbackFunctionType p_callback, CriterionFunctionType p_criterion, + CriterionBracketFunctionType p_criterionBracket) const { const double c_tol = 1.0e-4; // tolerance for corrector iteration const double c_maxDist = 0.4; // maximal distance to curve @@ -161,7 +162,7 @@ void PathTracer::TracePath( bool accept = true; if (fabs(h) <= c_hmin) { - return; + return {x, false, "Stepsize fell below minimum threshold."}; } // Predictor step @@ -204,7 +205,7 @@ void PathTracer::TracePath( disto = dist; iter++; if (iter > c_maxIter) { - return; + return {x, false, "Maximum iterations exceeded."}; } } @@ -226,7 +227,7 @@ void PathTracer::TracePath( if (!accept) { h /= m_maxDecel; // PC not accepted; change stepsize and retry if (fabs(h) <= c_hmin) { - return; + return {x, false, "Stepsize fell below minimum threshold."}; } continue; } @@ -268,6 +269,7 @@ void PathTracer::TracePath( } } } + return {x, true, "Path tracing terminated successfully."}; } } // end namespace Gambit diff --git a/src/solvers/logit/path.h b/src/solvers/logit/path.h index 3951539f2..655194e42 100644 --- a/src/solvers/logit/path.h +++ b/src/solvers/logit/path.h @@ -58,6 +58,12 @@ using CallbackFunctionType = std::function &)>; inline void NullCallbackFunction(const Vector &) {} +struct TracePathResult { + Vector final_point; + bool status; // true if path tracing terminated successfully, false if it terminated due to error + std::string message; // error message if status is false +}; + // // This class implements a generic path-following algorithm for smooth curves. // It is based on the ideas and codes presented in Allgower and Georg's @@ -74,7 +80,7 @@ class PathTracer { void SetStepsize(double p_hStart) { m_hStart = p_hStart; } double GetStepsize() const { return m_hStart; } - void + TracePathResult TracePath(std::function &, Vector &)> p_function, std::function &, Matrix &)> p_jacobian, Vector &p_x, double &p_omega, TerminationFunctionType p_terminate,