Skip to content

A polynomial system is not answered with some of its solutions missing - #2127

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
fglm-records-the-combination-a-reduced-row-stands-for
Oct 26, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
fglm-records-the-combination-a-reduced-row-stands-for

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Two polynomial systems over Q, each with only rational solutions, lost some of them, on 2.6.0 and on master:

2.6.0 this branch
x*y, x + y^2 - 1 [[1, 0]] [[1, 0], [0, 1], [0, -1]]
x*y + 3*x - 5*y - 15, x^2 - 3*x - 4*y - 10 [[1, -3], [2, -3]] [[5, 0], [1, -3], [2, -3]]

The Gröbner path should answer both, but it declined them, and the eliminator answered instead. That solves x*y = 0 for y as 0 alone, and loses solutions. There were two defects:

  • FGLM recorded the wrong combination for a reduced row. Each new row of its echelon form is stored as the monomial's normal form less the rows that reduced it, but its combination was recorded as the monomial alone. Every lexicographic element read off through that row got the wrong coefficients. For the first system the element for x came out x + y^2 instead of x + y^2 - 1, and its root (0, 0) failed the check against the system. The combination is now the monomial less the combination of the rows that reduced it.
  • Back-substitution did not cancel a term a root made worth nothing. A basis that is not in shape position has elements whose leading coefficient vanishes at a root. In the second system, at y = -3, x y + 3 x - 5 y - 15 stayed x * (-3) + 3 * x after one InnerSimplified pass. It still mentioned x, so it was taken as the equation for x, and it solved to every number. Each equation left is now read as a polynomial over Q in the variables still to be assigned, where its coefficients are rational. A zero drops out, and a nonzero number ends the branch.

Measured with a generated check: random systems where each equation is a product of two linear forms, one of them vanishing at a known integer point, sent to the Gröbner path alone. How many it answered, out of 1,000:

master FGLM fixed both fixed
3 unknowns 2 185 830
2 unknowns 174 516 821

No arm answered without the known point. Of the systems in three unknowns still declined, 165 have no univariate equation, and in the ones I read that is because they have a line of solutions. 4 decline on degree, and 1 on quotient dimension.

Cost: none measured. The five-unknown system with 120 solutions in GroebnerSystemTest takes 190–200 ms on master and 172–192 ms here, and the systems in SolveIsBoundedEndToEndTest are level.

Tests in GroebnerSystemTest: the lexicographic basis of the first system, element by element, and each system's solutions, all of them.

Not in this PR: Fglm.StandardMonomials stops walking where a monomial no longer fits the packing. A system with a line of solutions can therefore pass the quotient-dimension check with a truncated staircase, and is declined only later, at back-substitution. That decline is sound, since every element FGLM finds is in the ideal, but it does work that the check exists to skip.

Fixes #2126

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

Two polynomial systems over Q, each with only rational solutions, lost some of them:
  x*y; x + y^2 - 1                          [[1, 0]]             -> [[1, 0], [0, 1], [0, -1]]
  x*y + 3x - 5y - 15; x^2 - 3x - 4y - 10    [[1, -3], [2, -3]]   -> [[5, 0], [1, -3], [2, -3]]
The Gröbner path should answer both, but it declined them, and the eliminator answered instead.
That solves x*y = 0 for y as 0 alone, and loses solutions. There were two defects.

FGLM stored each new row of its echelon form as the monomial's normal form less the rows that
reduced it, but recorded the combination as the monomial alone. Every lexicographic element read
off through such a row got the wrong coefficients. For the first system the element for x came out
x + y^2 instead of x + y^2 - 1, its root (0, 0) failed the check against the system, and the path
declined. The combination is now the monomial less the combination of the rows that reduced it.

Back-substitution read what was left after a root with one InnerSimplified pass, which does not
cancel a term the root has made worth nothing. A basis that is not in shape position has elements
whose leading coefficient vanishes at a root. In the second system x y + 3 x - 5 y - 15 at y = -3
stayed x * (-3) + 3 * x, still mentioned x, was taken as the equation for x, and solved to every
number. Each equation left is now read as a polynomial over Q in the variables still to be
assigned, where its coefficients are rational. A zero drops out, and a nonzero number ends the
branch.

Measured with a generated check: random systems where each equation is a product of two linear
forms, one of them vanishing at a known integer point, sent to the Gröbner path alone.
                      master    FGLM fixed    both fixed
  3 unknowns, 1000       2         185           830
  2 unknowns, 1000     174         516           821
No arm answered without the known point. Of the systems still declined in three unknowns, 165
have no univariate equation, and in those read that is a line of solutions. 4 decline on degree
and 1 on quotient dimension.

Cost: none measured. The five-unknown system with 120 solutions in GroebnerSystemTest takes
190-200 ms on master and 172-192 ms here, and the bounded-solve systems are level.

Fixes #2126

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Rafael-SOWNet Rafael-SOWNet added this to the 2.7.0 milestone Oct 26, 2026
@Rafael-SOWNet
Rafael-SOWNet merged commit 4b0a97e into master Oct 26, 2026
34 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in AngouriMath Oct 26, 2026
Rafael-SOWNet added a commit that referenced this pull request Oct 26, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
Rafael-SOWNet added a commit that referenced this pull request Oct 26, 2026
* A system with a product equation is solved branch by branch

The eliminator solved x * y = 0 for y as 0, which is the answer only where x is not zero, and in a
system the triangularisation does not take nothing followed the branch where x is. Each row that
came back satisfied the system, so the answer read as all of the solutions:
  x*y; sin(x) + y - 1        missing (0, 1)
  (x - 1)*(y - 2); e^x - y   missing (1, e)
  x*e^y; x^2*y               [[0, 0]], where every (0, t) is a solution

A system with a product in more than one of its unknowns is now solved once for each way of
choosing a factor of each such product, up to 64 systems, and its solutions are theirs together.
A product whose factors all mention the same unknowns is left alone, since solving it reads every
factor. A branch that answers null is taken to have no solutions, which is what Solve says of it.

Every row of the union is put back into the system as written, because a factor can be zero
where another is not defined: the branch x = 0 of x ln(y), x - y is (0, 0), where ln(0) is no
number. A row whose residual has no symbol left and is not a finite number is now dropped, on the
square path too, as a root of one equation is.

A branch can leave an unknown that no equation mentions, and the eliminator had no equation to
take it from and answered nothing. Such a system goes to the non-square solver, which makes the
unknown a parameter: x - 1, x^2 - 1 in x, y was null and is [[1, t_1]]. SolveSystem.TestTrigSystem4
pinned null for a - 1, b * 0, where b * 0 is zero for every b; it now expects the one family
(1, t_1).

Measured with the generated check from #2126 on 1190 square systems in x and y built from a known
integer solution: the known solution missing 22 times on master and 13 here, with no other
change in its findings and no wrong row on either. The 13 left are roots found by Newton's method,
one of several, and systems with abs.

Fixes #2128

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

* Put the #2128 entry first in Unreleased, now that #2127 has merged

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet deleted the fglm-records-the-combination-a-reduced-row-stands-for branch October 26, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

A polynomial system with rational solutions loses some of them: two defects in the Gröbner path

1 participant