From 6c2ec23c8d74bc42fd7e4a9d67da3adefe8f0332 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Wed, 11 Feb 2026 14:02:18 +0000 Subject: [PATCH] Restrict search space for `enumpoly` to be strictly interior. This shrinks the search space for searching for equilibria on a given support to be in the interior of the simplex (rather than including the boundaries as before). This solves the behaviour noted in #756, in which degenerate situations which required a solution to be on the boundary would be very slow as it tried to approach the solution on the boundary. --- src/solvers/enumpoly/efgpoly.cc | 4 ++-- src/solvers/enumpoly/nfgpoly.cc | 4 ++-- src/solvers/enumpoly/poly.h | 6 +++++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/solvers/enumpoly/efgpoly.cc b/src/solvers/enumpoly/efgpoly.cc index e30210949..ad7ada9c2 100644 --- a/src/solvers/enumpoly/efgpoly.cc +++ b/src/solvers/enumpoly/efgpoly.cc @@ -161,8 +161,8 @@ std::list> SolveSupport(const BehaviorSupportProfil // set up the rectangle of search Vector bottoms(data.space->GetDimension()), tops(data.space->GetDimension()); - bottoms = 0; - tops = 1; + bottoms = 1e-12; + tops = 1 - 1e-12; PolynomialSystemSolver solver(equations); std::list> roots; diff --git a/src/solvers/enumpoly/nfgpoly.cc b/src/solvers/enumpoly/nfgpoly.cc index 3334b7de7..a77d730f5 100644 --- a/src/solvers/enumpoly/nfgpoly.cc +++ b/src/solvers/enumpoly/nfgpoly.cc @@ -111,8 +111,8 @@ EnumPolyStrategySupportSolve(const StrategySupportProfile &support, bool &is_sin const PolynomialSystem equations = ConstructEquations(space, support, strategy_poly); Vector bottoms(space->GetDimension()), tops(space->GetDimension()); - bottoms = 0; - tops = 1; + bottoms = 1e-12; + tops = 1 - 1e-12; PolynomialSystemSolver solver(equations); is_singular = false; std::list> roots; diff --git a/src/solvers/enumpoly/poly.h b/src/solvers/enumpoly/poly.h index 2cc2db670..eb3390c6f 100644 --- a/src/solvers/enumpoly/poly.h +++ b/src/solvers/enumpoly/poly.h @@ -375,7 +375,11 @@ template class Polynomial { }); } [[nodiscard]] const std::vector> &GetTerms() const noexcept { return m_terms; } - bool IsZero() const noexcept { return m_terms.empty(); } + bool IsZero() const noexcept + { + return m_terms.empty() || std::all_of(m_terms.begin(), m_terms.end(), + [](const auto &mono) { return mono.IsZero(); }); + } bool IsConstant() const noexcept { return m_terms.size() == 1 && m_terms.front().TotalDegree() == 0;