Repository navigation
Factor a polynomial in any number of variables (#746 item 43) - #1058
Merged
Rafael-SOWNet merged 1 commit intoAug 25, 2026
Merged
Conversation
Kronecker's substitution was written for two variables because that is the case #746 item 43 names, but nothing in it is about two. The exponent pair (i, j) was being packed as i + s*j, which is a two-digit numeral in radix s -- and an exponent vector of any length is a numeral in mixed radix, with radices d_i + 1 and place values s_0 = 1, s_(i+1) = s_i * (d_i + 1). A factor has degree at most d_i in each variable because it divides the polynomial, so the map is injective on every monomial that can appear in the polynomial or in any of its factors, whatever the number of variables. So the class is now KroneckerFactorization rather than BivariateFactorization, the encoding and the decoding are loops over the variables instead of two statements, and the caller no longer refuses a third one. x ^ 2 - (y + z) ^ 2 -> (x + y + z) * (x - y - z) x ^ 2 + 2 * x * y + y ^ 2 - z ^ 2 -> (x + y + z) * (x + y - z) (x + y) * (x + z) * (x + w) -> (x + y) * (w + x) * (x + z) What changes with the number of variables is the ceiling, and it changes sharply: the image has degree the product of the radices less one, not their sum, so three variables of degree 2 fit within the one-variable factoriser's 32 and four do not. That is a refusal and never a wrong answer -- every candidate is still checked by exact division and the assembled factors are still divided back into the input -- and a test now pins three shapes that factor mathematically and are declined. BREAKING-CHANGES had two entries disagreeing about x ^ 2 - y ^ 2, the second having overtaken the first; the earlier one now points at the later instead of contradicting it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjumi5K7fg8yx6UK1mZTQd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#1055 factored a polynomial in two variables by Kronecker's substitution, because two is the case #746 item 43 names. Nothing in the method is about two.
The exponent pair
(i, j)was packed asi + s·j— a two-digit numeral in radixs. An exponent vector of any length is a numeral in mixed radix: radicesd_i + 1, place valuess_0 = 1,s_(i+1) = s_i · (d_i + 1). A factor has degree at mostd_iin each variable because it divides the polynomial, so the map stays injective on every monomial that can appear in the polynomial or in any of its factors, whatever the number of variables.So the encoding and decoding become loops over the variables instead of two statements, the class is
KroneckerFactorizationrather thanBivariateFactorization, and the caller stops refusing a third variable.What it answers now
Factor("x ^ 2 - (y + z) ^ 2", "x")null(x + y + z) * (x - y - z)Factor("x ^ 2 + 2 * x * y + y ^ 2 - z ^ 2", "x")null(x + y + z) * (x + y - z)Factor("x * y - x - y + 1", "x")null(y - 1) * (x - 1)Factor("(x + y) * (x + z + w)", "x")null(w + x + z) * (x + y)Factor("(x + y) * (x + z) * (x + w)", "x")null(x + y) * (w + x) * (x + z)Everything two-variable answers exactly as before.
The ceiling moves sharply, and it is still a refusal
The image has degree
Π (d_i + 1) - 1— a product, not a sum — against the one-variable factoriser'sMaxDegreeof 32. Three variables of degree 2 fit (27); four do not (81). A new test pins three shapes that factor mathematically and are declined:A wrong answer is still not among the things this can do. Every candidate is checked by exact division before it is kept, and the assembled factors are divided back into the input. Lifting the ceiling is Hensel lifting with an evaluation homomorphism, which is a different piece of work and stays open on item 43.
Also
BREAKING-CHANGES.mdheld two entries disagreeing aboutx ^ 2 - y ^ 2— #1053's said it isnulland needs factorisation over ℚ(y), #1055's said it is(x + y) * (x - y). The second had overtaken the first without the first being updated. The earlier entry now points at the later one instead of contradicting it.Full suite:
Failed: 0, Passed: 8583, Skipped: 14, Total: 8597.🤖 Generated with Claude Code
https://claude.ai/code/session_01Bjumi5K7fg8yx6UK1mZTQd