1.. _polys-internals: 2 3=============================================== 4Internals of the Polynomial Manipulation Module 5=============================================== 6 7All polynomial manipulations are relative to a *ground domain*. For 8example, when factoring a polynomial like `x^{10} - 1`, one has to decide what 9ring the coefficients are supposed to belong to, or less trivially, what 10coefficients are allowed to appear in the factorization. This choice of 11coefficients is called a ground domain. Typical choices include the integers 12`\mathbb{Z}`, the rational numbers `\mathbb{Q}` or various related rings and 13fields. But it is perfectly legitimate (although in this case uninteresting) 14to factorize over polynomial rings such as `k[Y]`, where `k` is some fixed 15field. 16 17Thus the polynomial manipulation algorithms (both 18complicated ones like factoring, and simpler ones like addition or 19multiplication) have to rely on other code to manipulate the coefficients. 20In the polynomial manipulation module, such code is encapsulated in so-called 21:mod:`~diofant.domains`. A domain is basically a factory object: it takes various 22representations of data, and converts them into objects with unified interface. 23Every object created by a domain has to implement the arithmetic operations 24`+`, `-` and `\times`. Other operations are accessed through the domain, e.g. 25as in ``ZZ.quo(ZZ(4), ZZ(2))``. 26 27Manipulation of sparse, distributed polynomials 28=============================================== 29 30Dense representations quickly require infeasible amounts of storage and 31computation time if the number of variables increases. For this reason, 32there is code to manipulate polynomials in a *sparse* representation. 33 34.. currentmodule:: diofant.polys.rings 35 36Sparse polynomials are represented as dictionaries. 37 38.. autofunction:: ring 39 40.. autoclass:: PolyElement 41 :members: 42 :special-members: 43 44.. currentmodule:: diofant.polys.univar 45 46.. autoclass:: UnivarPolyElement 47 :members: 48 49Polynomial factorization algorithms 50=================================== 51 52Many variants of Euclid's algorithm: 53 54.. module:: diofant.polys.euclidtools 55 56Classical remainder sequence 57---------------------------- 58 59Let `K` be a field, and consider the ring `K[X]` of polynomials in a single 60indeterminate `X` with coefficients in `K`. Given two elements `f` and `g` 61of `K[X]` with `g\neq 0` there are unique polynomials `q` and `r` such that 62`f = qg + r` and `\deg(r) < \deg(g)` or `r = 0`. 63They are denoted by `\mathrm{quo}(f,g)` 64(*quotient*) and `\mathrm{rem}(f,g)` (*remainder*), so we have 65the *division identity* 66 67.. math:: 68 69 f = \mathrm{quo}(f,g)g + \mathrm{rem}(f,g). 70 71It follows that every ideal `I` of `K[X]` is a principal ideal, generated by 72any element `\neq 0` of minimum degree (assuming `I` non-zero). In fact, 73if `g` is such a polynomial and `f` is any element of `I`, 74`\mathrm{rem}(f,g)` belongs to `I` as a linear combination of `f` and `g`, 75hence must be zero; therefore `f` is a multiple of `g`. 76 77Using this result it is possible to find a `greatest common 78divisor <https://en.wikipedia.org/wiki/Greatest_common_divisor>`_ 79(gcd) of any polynomials `f,g,\ldots` in `K[X]`. 80If `I` is the ideal formed by all linear combinations of the given polynomials 81with coefficients in `K[X]`, and `d` is its generator, 82then every common divisor of the polynomials also divides `d`. 83On the other hand, the given polynomials are multiples of the generator `d`; 84hence `d` is a gcd of the polynomials, denoted `\mathrm{gcd}(f,g,\ldots)`. 85 86An algorithm for the gcd of two polynomials `f` and `g` in `K[X]` can 87now be obtained as follows. 88By the division identity, `r = \mathrm{rem}(f,g)` is in the ideal generated 89by `f` and `g`, as well as `f` is in the ideal generated by `g` and `r`. 90Hence the ideals generated by the pairs `(f,g)` and `(g,r)` are the same. 91Set `f_0 = f`, `f_1 = g`, and define recursively 92`f_i = \mathrm{rem}(f_{i-2},f_{i-1})` for `i\ge 2`. 93The recursion ends after a finite number of steps with `f_{k+1}=0`, 94since the degrees of the polynomials are strictly decreasing. 95By the above remark, all the pairs `(f_{i-1},f_i)` generate the same ideal. 96In particular, the ideal generated by `f` and `g` is generated by `f_k` 97alone as `f_{k+1} = 0`. Hence `d = f_k` is a gcd of `f` and `g`. 98 99The sequence of polynomials `f_0`, `f_1,\ldots, f_k` is called the 100*Euclidean polynomial remainder sequence* determined by `(f,g)` because 101of the analogy with the classical `Euclidean algorithm 102<https://en.wikipedia.org/wiki/Euclidean_algorithm>`_ for the gcd of 103natural numbers. 104 105The algorithm may be extended to obtain an expression for `d` in terms of 106`f` and `g` by using the full division identities 107to write recursively each `f_i` as a linear combination of `f` and `g`. 108This leads to an equation 109 110.. math:: 111 112 d = uf + vg\qquad (u,v \in K[X]) 113 114analogous to `Bézout's identity 115<https://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity>`_ 116in the case of integers. 117 118Simplified remainder sequences 119------------------------------ 120 121Assume, as is usual, that the coefficient field `K` is 122the field of fractions of an integral domain `A`. 123In this case the coefficients (numerators and denominators) 124of the polynomials in the Euclidean remainder sequence 125tend to grow very fast. 126 127If `A` is a unique factorization domain, the coefficients may be 128reduced by cancelling common factors of numerators and denominators. 129Further reduction is possible noting that a gcd of polynomials in 130`K[X]` is not unique: 131it may be multiplied by any (non-zero) constant factor. 132 133Any polynomial `f` in `K[X]` can be simplified by extracting 134the denominators and common factors of the numerators of its coefficients. 135This yields the representation `f = cF` where `c\in K` is 136the *content* of `f` and `F` is a *primitive* polynomial, i.e., 137a polynomial in `A[X]` with coprime coefficients. 138 139It is possible to start the algorithm by replacing the given polynomials 140`f` and `g` with their primitive parts. This will only modify 141`\mathrm{rem}(f,g)` by a constant factor. 142Replacing it with its primitive part and continuing recursively 143we obtain all the primitive parts of the polynomials in 144the Euclidean remainder sequence, including the primitive 145`\mathrm{gcd}(f,g)`. 146 147This sequence is the *primitive polynomial remainder sequence*. 148It is an example of *general polynomial remainder sequences* where 149the computed remainders are modified by constant multipliers (or divisors) 150in order to simplify the results. 151 152Subresultant sequence 153--------------------- 154 155The coefficients of the primitive polynomial sequence do not grow 156exceedingly, but the computation of the primitive parts requires 157extra processing effort. Besides, the method only works with fraction fields 158of unique factorization domains, excluding, for example, the general number 159fields. 160 161Collins :cite:`Collins1967subr` realized that the so-called *subresultant polynomials* 162of a pair of polynomials also form a generalized remainder sequence. 163The coefficients of these polynomials 164are expressible as determinants in the coefficients of the given 165polynomials. Hence (the logarithm of) their size only grows linearly. 166In addition, if the coefficients of the given polynomials 167are in the subdomain `A`, so are those 168of the subresultant polynomials. This means that the subresultant 169sequence is comparable to the primitive remainder sequence without 170relying on unique factorization in `A`. 171 172To see how subresultants are associated with remainder sequences 173recall that all polynomials `h` in the sequence are linear combinations of 174the given polynomials `f` and `g` 175 176.. math:: 177 178 h = uf+vg 179 180with polynomials `u` and `v` in `K[X]`. Moreover, as is seen from the 181extended Euclidean algorithm, the degrees of `u` and `v` are relatively 182low, with limited growth from step to step. 183 184Let `n = \deg(f)`, and `m = \deg(g)`, and assume `n\ge m`. 185If `\deg(h) = j < m`, the coefficients of the powers `X^k` (`k > j`) 186in the products `uf` and `vg` cancel each other. In particular, the 187products must have the same degree, say, `l`. 188Then `\deg(u) = l - n` and `\deg(v) = l - m` with a total of `2l -n - m + 2` 189coefficients to be determined. 190 191On the other hand, the equality `h = uf + vg` implies that `l - j` 192linear combinations of the coefficients are zero, those associated with 193the powers `X^i` (`j < i \leq l`), and one has a given non-zero value, 194namely the leading coefficient of `h`. 195 196To satisfy these `l - j + 1` linear equations the total number of 197coefficients to be determined cannot be lower than `l - j + 1`, in general. 198This leads to the inequality `l \ge n + m - j - 1`. 199Taking `l = n + m - j - 1`, we obtain `\deg(u) = m - j - 1` and 200`\deg(v) = n - j - 1`. 201 202In the case `j = 0` the matrix of the resulting system of linear equations 203is the `Sylvester matrix <https://en.wikipedia.org/wiki/Sylvester_matrix>`_ 204`S(f,g)` associated to `f` and `g`, 205an `(n+m)\times (n+m)` matrix with coefficients of `f` and `g` as entries. 206Its determinant is the `resultant <https://en.wikipedia.org/wiki/Resultant>`_ 207`\mathrm{res}(f,g)` of the pair `(f,g)`. 208It is non-zero if and only if `f` and `g` are relatively prime. 209 210For any `j` in the interval from `0` to `m` the matrix of the linear system is 211an `(n+m-2j)\times (n+m-2j)` submatrix of the Sylvester matrix. 212Its determinant `s_j(f,g)` 213is called the `j` th *scalar subresultant* of `f` and `g`. 214 215If `s_j(f,g)` is not zero, the associated equation `h = uf + vg` has 216a unique solution where `\deg(h) = j` and the leading coefficient 217of `h` has any given value; the one with leading coefficient 218`s_j(f,g)` is the `j` th *subresultant polynomial* or, briefly, 219*subresultant* of the pair `(f,g)`, and denoted `S_j(f,g)`. 220This choice guarantees that the remainining coefficients 221are also certain subdeterminants of the Sylvester matrix. 222In particular, if `f` and `g` are in `A[X]`, so is `S_j(f,g)` as well. 223This construction of subresultants applies to any `j` between 224`0` and `m` regardless of the value of `s_j(f,g)`; if it is zero, then 225`\deg(S_j(f,g)) < j`. 226 227The properties of subresultants are as follows. Let `n_0 = \deg(f)`, 228`n_1 = \deg(g)`, `n_2, \ldots, n_k` be the decreasing sequence of 229degrees of polynomials in a remainder sequence. 230Let `0 \le j \le n_1`; then 231 232- `s_j(f,g)\ne 0` if and only if `j = n_i` for some `i`. 233 234- `S_j(f,g)\ne 0` if and only if `j = n_i` or `j = n_i - 1` for some `i`. 235 236Normally, `n_{i-1} - n_i = 1` for `1 < i \le k`. If `n_{i-1} - n_i > 1` 237for some `i` (the *abnormal* case), then `S_{n_{i-1}-1}(f,g)` and 238`S_{n_i}(f,g)` are constant multiples of each other. 239Hence either one could be included in the polynomial remainder sequence. 240The former is given by smaller determinants, 241so it is expected to have smaller coefficients. 242 243Collins defined the *subresultant remainder sequence* by setting 244 245.. math:: 246 247 f_i = S_{n_{i-1}-1}(f,g) \qquad (2\le i \le k). 248 249In the normal case, these are the same as the `S_{n_i}(f,g)`. He also 250derived expressions for the constants `\gamma_i` in the remainder 251formulas 252 253.. math:: 254 255 \gamma_i f_i = \mathrm{rem}(f_{i-2},f_{i-1}) 256 257in terms of the leading coefficients of `f_1,\ldots,f_{i-1}`, working 258in the field `K`. 259 260Brown and Traub :cite:`Brown1971subres` later developed a recursive procedure 261for computing the coefficients `\gamma_i`. Their algorithm deals with elements 262of the domain `A` exclusively (assuming `f,g\in A[X]`). However, in the 263abnormal case there was a problem, a division in `A` 264which could only be conjectured to be exact. 265 266This was subsequently justified by Brown :cite:`Brown1978prs` who showed that 267the result of the division is, in fact, a scalar subresultant. 268More specifically, the constant appearing in the computation of `f_i` is 269`s_{n_{i-2}}(f,g)` (Theorem 3). 270The implication of this discovery is that the scalar subresultants 271are computed as by-products of the algorithm, all but `s_{n_k}(f,g)` 272which is not needed after finding `f_{k+1} = 0`. 273Completing the last step we obtain all non-zero scalar subresultants, 274including the last one which is the resultant if this does not vanish. 275 276Polynomial factorization in characteristic zero: 277 278.. automodule:: diofant.polys.factortools 279 :members: 280 281Gröbner basis algorithms 282======================== 283 284Gröbner bases can be used to answer many problems in computational 285commutative algebra. Their computation in rather complicated, and very 286performance-sensitive. We present here various low-level implementations of 287Gröbner basis computation algorithms; please see the previous section of the 288manual for usage. 289 290.. automodule:: diofant.polys.groebnertools 291 :members: 292 293Algebraic number fields 294======================= 295 296.. currentmodule:: diofant.polys.numberfields 297.. autofunction:: minpoly_groebner 298 299Factorization over algebraic number fields 300========================================== 301 302.. automodule:: diofant.polys.factorization_alg_field 303 :members: 304 :private-members: 305 306Modular GCD 307=========== 308 309.. automodule:: diofant.polys.modulargcd 310 :members: 311 :private-members: 312 313Heuristic GCD 314============= 315 316.. automethod:: diofant.polys.euclidtools._GCD._zz_heu_gcd 317 318Further tools 319============= 320 321.. automodule:: diofant.polys.rootisolation 322 :members: 323 324.. automodule:: diofant.polys.sqfreetools 325 :members: 326 327Undocumented 328============ 329 330Many parts of the polys module are still undocumented, and even where there is 331documentation it is scarce. Please contribute! 332 333.. automodule:: diofant.polys.polyoptions 334 :members: 335 336.. automodule:: diofant.polys.polyerrors 337 :members: 338 339.. currentmodule:: diofant.polys.fields 340.. autoclass:: FracElement 341 :members: 342