FactorSquareFree¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
FactorSquareFree[poly]
writes poly as a product of pairwise-coprime square-free factors, collecting repeated factors into powers.
FactorSquareFree[poly, Extension -> alpha]
performs the decomposition
Notes
Computed via the Yun / Musser square-free decomposition using polynomial GCDs of poly with its derivative; cheaper than full Factor and sufficient when only multiplicities are needed. over Q(alpha) (alpha = Sqrt\[c\], c^(1/n), I, or a list of generators), grouping the irreducible-over-Q(alpha) factors by multiplicity; the default Extension -\> None factors over Q.Examples (12)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (4)¶
In[1]:= FactorSquareFree[x^5 - x^3 - x^2 + 1]
Out[1]= (-1 + x)^2 (1 + 2 x + 2 x^2 + x^3)
In[2]:= FactorSquareFree[x^4 - 9x^3 + 29x^2 - 39x + 18]
Out[2]= (-3 + x)^2 (2 - 3 x + x^2)
In[3]:= FactorSquareFree[x^5 - x^3 y^2 - x^2 y^3 + y^5]
Out[3]= (x - y)^2 (x^3 + 2 x^2 y + 2 x y^2 + y^3)
In[4]:= FactorSquareFree[{(x^2 - 1)(x - 1), (x^4 - 1)(x^2 - 1)}]
Out[4]= {(1 + x) (-1 + x)^2, (1 + x^2) (-1 + x^2)^2}
Worked examples (1)¶
Applications (7)¶
The square-free factor 1 + x + x^2 + x^3 is reducible but is not split
A perfect fourth power found without full factorisation
Multivariate: square-free parts x and y (x + y), the latter squared
A square over Q(Sqrt[2])
The companion list of {factor, multiplicity} pairs
Inexact coefficients are rationalised and restored
Limitation: a rational function is returned unchanged
Implementation notes¶
Algorithm. builtin_factorsquarefree (in src/poly/facpoly_squarefree.inc, compiled into facpoly.c) computes the square-free decomposition p = ∏ p_i^i with each p_i square-free and pairwise coprime, using Yun's algorithm. A trailing Extension -> α (an explicit generator, a list, or Automatic; anything other than None) goes to factor_square_free_over_extension. That routine calls Factor[poly, opts…], the Trager engine over Q(α), and rebuilds the square-free decomposition by grouping irreducible factors of equal multiplicity, so it needs no separate square-free primitive over Q(α). If Factor declines, it falls back to the path over Q. With FLINT, a free-symbol radicand Sqrt[k] goes to flint_parametric_sqrt_factor_squarefree. Any other trailing argument, Modulus included, leaves the call unevaluated. After a Rationalize/Numericalize round-trip for inexact inputs, the dispatcher factor_square_free_dispatcher expands and routes to factor_square_free_poly. FactorSquareFreeList splits the result into {factor, multiplicity} pairs.
factor_square_free_poly works recursively on the variable list. It first extracts the polynomial content (poly_content) and recurses on it; on the primitive part pp it runs Yun's recurrence: set A = pp, B = gcd(A, A'), C = A/B, D = A'/B − C', then iterate P_i = gcd(C, D) (the degree-i square-free factor), C ← C/P_i, D ← D/P_i − (C/P_i)', accumulating P_i^i. Derivatives are computed by the local poly_deriv and GCDs by poly_gcd_internal; exact divisions by exact_poly_div. An F4 "cheap squarefree" pre-check (sqfree_cheap_check, a univariate-substitution probe) short-circuits the expensive gcd(pp, pp') when pp is provably square-free. A final exact_poly_div recovers any leading or missing scalar factor, so the product round-trips to the input. Since v0.458 that division is a soundness check as well. If the computed factors do not divide P exactly, as can happen when the "variables" are transcendental atoms (Log[…], Arg[…]) over a coefficient ring the classical PRS does not model, the routine returns Expand[P] unfactored. Before that change it substituted 1 for the cofactor and returned a product unequal to the input.
Data structures. Expr* polynomials manipulated through the generic evaluator (eval_and_free) and the poly helpers (get_degree_poly, poly_gcd_internal, exact_poly_div); factors collected in a growable Expr** buffer with their multiplicities encoded as Power[P_i, i].
Complexity / limits. Dominated by the GCD chain; the cheap pre-check avoids one full multivariate GCD in the common square-free case. Square-free decomposition is a prerequisite stage for full Factor. Only polynomials are decomposed: a rational function comes back unchanged, and Modulus is not supported. FactorSquareFree is Listable, Protected, and symbolic only.
Listable,Protected.- Automatically threads over lists, as well as equations, inequalities and logic functions.
- Works on both univariate and multivariate polynomials.
- Bigint coefficients (above 2^63) are coefficients, not variables:
FactorSquareFree[Expand[3^45 (1 + t)^2]]gives2954312706550833698643 (1 + t)^2(v0.458; it used to come back unfactored). - Self-checking: if the computed content and square-free factors do not reproduce the input exactly, which can happen when the "variables" are transcendental atoms over a coefficient ring the classical PRS does not model, the input is returned unfactored, never as an unequal product (v0.458).
Extensionruns the decomposition over an algebraic number field Q(alpha). It reduces toFactor[poly, Extension -> alpha](Trager engine) and groups the irreducible-over-Q(alpha) factors by multiplicity, so it also accepts inputs with algebraic-number coefficients, e.g.FactorSquareFree[x^2 - 2 Sqrt[2] x + 2, Extension -> Sqrt[2]]→(-Sqrt[2] + x)^2. Because square-free structure is field-independent for rational inputs, an extension leaves a rational-coefficient answer unchanged; the defaultExtension -> Noneuses the fast over-Q Yun path.- Multivariate inputs use a cheap squarefree pre-check (F4 Stage 1): after content extraction in the main variable,
sqfree_cheap_checksubstitutes integer values from{1, -1, 2, -2, 3, -3, 4}for the other variables and testsgcd(image, image')overZ[x]. If any image is squarefree at an alpha that preserves the leading-x degree, the pre-check provesppis squarefree in x and the expensive multivariategcd(pp, pp')is skipped. Soundness comes from content extraction guaranteeing any repeated factor ofppinvolves the main variable nontrivially. Measured 6.6× speedup on 4-variable squarefree inputs (6.27 s → 0.95 s); non-squarefree inputs fall through to the original Yun loop with negligible overhead. - The cheap pre-check's univariate
gcd(image, image')runs throughzupoly_gcd(subresultant PRS, GMPmpz_tcoefficients). The previous implementation usedpoly_gcd_internal(Knuth-style primitive PRS at the Expr level) which suffers exponential coefficient growth on the intermediate pseudo-remainders; on a degree-31 univariate image (e.g.Factor[Expand[x^2 (z^13 - x^12)(z^4 + 3 x^9 - y^13)(17 - 5 y - z^14)]]) it ran for >120 s. Routing the same gcd through subresultant PRS keeps coefficient sizes polynomially bounded and runs in sub-millisecond time on the same input, bringing the full Factor call to under 1 s.
Attributes: Listable, Protected.
References¶
See also: I
- D. Y. Y. Yun, "On square-free decomposition algorithms", SYMSAC 1976.
- K. O. Geddes, S. R. Czapor, G. Labahn, Algorithms for Computer Algebra (Kluwer, 1992).
- Source:
src/poly/facpoly_squarefree.inc - Specification:
docs/spec/builtins/structural-manipulation.md - Tests:
tests/test_facpoly.c - Tests:
tests/test_factorsquarefreelist.c - Tests:
tests/test_flint_bridge.c - Tests:
tests/test_inexact_dispatch.c
Notes & additional examples¶
Notes¶
FactorSquareFree[poly]writespolyas a product of pairwise coprime, square-free factors raised to their multiplicities. It uses Yun's algorithm, built on GCDs of the polynomial with its derivative. It does not split a square-free factor that is reducible, which makes it cheaper thanFactorwhen only the multiplicities matter.- The grouping of factors is a valid square-free decomposition but not
always the one Mathematica prints:
x (x y + y^2)^2is equal tox y^2 (x + y)^2. - Extension.
Extension -> α(or a list, orAutomatic) decomposes over the number field by way ofFactor's Trager engine. - Soundness. If the computed factors do not reproduce the input exactly, the expanded polynomial is returned unfactored rather than an unequal product.
- Not supported. Rational functions and
Modulusare not handled; such calls stay as they are. Listable,Protected. Symbolic only.- See also:
FactorSquareFreeList,Factor,FactorTerms,PolynomialGCD,D.