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