Repository navigation
The square-free part is taken where the coefficients are polynomials - #1054
Merged
Merged
Conversation
`MathS.Polynomials.SquareFreePart` refused every polynomial in more than one
variable, for the same reason `Factor` did: it was written against a
representation whose coefficients are rational numbers.
`p / gcd(p, dp/dx)` is the square-free part whatever ring the coefficients live
in -- a repeated factor appears in the derivative one time fewer than in the
polynomial, so dividing by the common part leaves each distinct factor exactly
once. Nothing about that is univariate, and the multivariate representation has
all three operations already: `DerivativeIn`, the recursive `PolynomialGcd` that
`Gcd` is built from, and exact division.
SquareFreePart("(x - y) ^ 2 * (x + y)", "x") null -> x ^ 2 - y ^ 2
SquareFreePart("(x - y) ^ 3", "x") null -> x - y
SquareFreePart("(x + a) ^ 2 * (x + b)", "x") null -> (x + a) * (x + b)
SquareFreePart("x ^ 2 * y ^ 2", "x") null -> x
SquareFreePart("y", "x") null -> null
The last two are worth saying out loud. The content is dropped, as it always
was: `SquareFreePart("4 * x ^ 2", "x")` is `x` and not `4 * x`, because the
univariate path takes the primitive part first -- so `x ^ 2 * y ^ 2` is `x` with
`y ^ 2` as the content, which is the existing convention applied to a wider ring
rather than a new one. That was checked against the univariate path rather than
assumed; the expectation written first was the wrong one.
Reached only where the rational path declined, so nothing that already answered
can change. Tests compare numerically at twenty points per case rather than as
strings, for the reason #1053 records.
Suite 8569/0.
Part of #746 tier 1, item 43.
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.
Part of #746 tier 1, item 43. Follows #1053, which did the same for
Factor's content.What was wrong
MathS.Polynomials.SquareFreePartrefused every polynomial in more than one variable — not becausethe mathematics is univariate, but because the code was written against a representation whose
coefficients are rational numbers.
p / gcd(p, dp/dx)is the square-free part whatever ring the coefficients live in: a repeated factorappears in the derivative one time fewer than in the polynomial, so dividing by the common part
leaves each distinct factor exactly once. The multivariate representation already has all three
operations —
DerivativeIn, the recursivePolynomialGcdthatMathS.Polynomials.Gcdis builtfrom, and exact division.
SquareFreePart("(x - y) ^ 2 * (x + y)", "x")nullx ^ 2 - y ^ 2SquareFreePart("(x - y) ^ 3", "x")nullx - ySquareFreePart("(x + a) ^ 2 * (x + b)", "x")nulla * b + a * x + b * x + x ^ 2SquareFreePart("y ^ 2 * x ^ 2 * (x + 1)", "x")nullx ^ 2 + xSquareFreePart("x ^ 2 * y ^ 2", "x")nullxSquareFreePart("y", "x")nullnullSquareFreePart("sin(y) * x ^ 2", "x")nullnullThe two that look wrong and are not
x ^ 2 * y ^ 2givesx, notx * y ^ 2. The content has always been dropped: the univariatepath takes the primitive part first, so
SquareFreePart("4 * x ^ 2", "x")isxrather than4 * x.y ^ 2is the content here for exactly the same reason. That is the existing conventionapplied to a wider ring, not a new one — and it was checked against the univariate path rather than
assumed. The expectation I wrote first was the wrong one, which is why the test says so explicitly.
yis still refused: it is constant inx, and the univariate path refuses that too.Scope
The multivariate path is reached only where the rational path declined, so nothing that already
answered can change.
Verification
Tests compare numerically at twenty random points per case rather than as strings, for the reason
recorded on #1053 —
Simplifydoes not prove two arrangements of a product equal, and a stringcomparison reports a defect that is not one.
Suite: 8569 passed, 0 failed, 14 skipped.