Catalogue of GP/PARI Functions: Polynomials and power series
Author: Nils-Peter Skoruppa
Keywords: PARI, GP, DOC

### Polynomials and power series

#### O(p{`^`}e)

If p is an integer greater than 2, returns a p-adic 0 of precision e. In all other cases, returns a power series zero with precision given by e v, where v is the X-adic valuation of p with respect to its main variable.

The library syntax is `GEN ggrando()`. `GEN zeropadic(GEN p, long e)` for a p-adic and `GEN zeroser(long v, long e)` for a power series zero in variable v.

#### bezoutres(A,B,{v})

Deprecated alias for `polresultantext`

The library syntax is `GEN polresultantext0(GEN A, GEN B, long v = -1)`, where `v` is a variable number.

#### deriv(x,{v})

Derivative of x with respect to the main variable if v is omitted, and with respect to v otherwise. The derivative of a scalar type is zero, and the derivative of a vector or matrix is done componentwise. One can use x' as a shortcut if the derivative is with respect to the main variable of x.

By definition, the main variable of a `t_POLMOD` is the main variable among the coefficients from its two polynomial components (representative and modulus); in other words, assuming a polmod represents an element of R[X]/(T(X)), the variable X is a mute variable and the derivative is taken with respect to the main variable used in the base ring R.

The library syntax is `GEN deriv(GEN x, long v = -1)`, where `v` is a variable number.

#### diffop(x,v,d,{n = 1})

Let v be a vector of variables, and d a vector of the same length, return the image of x by the n-power (1 if n is not given) of the differential operator D that assumes the value `d[i]` on the variable `v[i]`. The value of D on a scalar type is zero, and D applies componentwise to a vector or matrix. When applied to a `t_POLMOD`, if no value is provided for the variable of the modulus, such value is derived using the implicit function theorem.

Some examples: This function can be used to differentiate formal expressions: If E = exp(X^2) then we have E' = 2*X*E. We can derivate X*exp(X^2) as follow:

      ? diffop(E*X,[X,E],[1,2*X*E])
      %1 = (2*X^2 + 1)*E

Let `Sin` and `Cos` be two function such that `Sin`^2+`Cos`^2 = 1 and `Cos`' = -`Sin`. We can differentiate `Sin`/`Cos` as follow, PARI inferring the value of `Sin`' from the equation:

      ? diffop(Mod('Sin/'Cos,'Sin^2+'Cos^2-1),['Cos],[-'Sin])
      %1 = Mod(1/Cos^2, Sin^2 + (Cos^2 - 1))

Compute the Bell polynomials (both complete and partial) via the Faa di Bruno formula:

      Bell(k,n=-1)=
      {
        my(var(i)=eval(Str("X",i)));
        my(x,v,dv);
        v=vector(k,i,if(i==1,'E,var(i-1)));
        dv=vector(k,i,if(i==1,'X*var(1)*'E,var(i)));
        x=diffop('E,v,dv,k)/'E;
        if(n<0,subst(x,'X,1),polcoeff(x,n,'X))
      }

The library syntax is `GEN diffop0(GEN x, GEN v, GEN d, long n)`.

For n = 1, the function `GEN diffop(GEN x, GEN v, GEN d)` is also available.

#### eval(x)

Replaces in x the formal variables by the values that have been assigned to them after the creation of x. This is mainly useful in GP, and not in library mode. Do not confuse this with substitution (see `subst`).

If x is a character string, `eval(x)` executes x as a GP command, as if directly input from the keyboard, and returns its output.

      ? x1 = "one"; x2 = "two";
      ? n = 1; eval(Str("x", n))
      %2 = "one"
      ? f = "exp"; v = 1;
      ? eval(Str(f, "(", v, ")"))
      %4 = 2.7182818284590452353602874713526624978

Note that the first construct could be implemented in a simpler way by using a vector `x = ["one","two"]; x[n]`, and the second by using a closure `f = exp; f(v)`. The final example is more interesting:

      ? genmat(u,v) = matrix(u,v,i,j, eval( Str("x",i,j) ));
      ? genmat(2,3)   \\ generic 2 x 3 matrix
      %2 =
      [x11 x12 x13]

      [x21 x22 x23]

A syntax error in the evaluation expression raises an `e_SYNTAX` exception, which can be trapped as usual:

      ? 1a
       ***   unused characters: 1a
       ***                       ^-
      ? E(expr) =
        {
          iferr(eval(expr),
                e, print("syntax error"),
                errname(e) == "e_SYNTAX");
        }
      ? E("1+1")
      %1 = 2
      ? E("1a")
      syntax error

The library syntax is `geval(GEN x)`.

#### factorpadic(pol,p,r)

p-adic factorization of the polynomial pol to precision r, the result being a two-column matrix as in `factor`. Note that this is not the same as a factorization over Z/p^rZ (polynomials over that ring do not form a unique factorization domain, anyway), but approximations in Q/p^rZ of the true factorization in Q_p[X].

      ? factorpadic(x^2 + 9, 3,5)
      %1 =
      [(1 + O(3^5))*x^2 + O(3^5)*x + (3^2 + O(3^5)) 1]
      ? factorpadic(x^2 + 1, 5,3)
      %2 =
      [  (1 + O(5^3))*x + (2 + 5 + 2*5^2 + O(5^3)) 1]

      [(1 + O(5^3))*x + (3 + 3*5 + 2*5^2 + O(5^3)) 1]

The factors are normalized so that their leading coefficient is a power of p. The method used is a modified version of the round 4 algorithm of Zassenhaus.

If pol has inexact `t_PADIC` coefficients, this is not always well-defined; in this case, the polynomial is first made integral by dividing out the p-adic content, then lifted to Z using `truncate` coefficientwise. Hence we actually factor exactly a polynomial which is only p-adically close to the input. To avoid pitfalls, we advise to only factor polynomials with exact rational coefficients.

The library syntax is `factorpadic(GEN f,GEN p, long r)` . The function `factorpadic0` is deprecated, provided for backward compatibility.

#### intformal(x,{v})

formal integration of x with respect to the variable v (wrt. the main variable if v is omitted). Since PARI cannot represent logarithmic or arctangent terms, any such term in the result will yield an error:

       ? intformal(x^2)
       %1 = 1/3*x^3
       ? intformal(x^2, y)
       %2 = y*x^2
       ? intformal(1/x)
         ***   at top-level: intformal(1/x)
         ***                 ^--------------
         *** intformal: domain error in intformal: residue(series, pole) != 0

The argument x can be of any type. When x is a rational function, we assume that the base ring is an integral domain of characteristic zero.

By definition, the main variable of a `t_POLMOD` is the main variable among the coefficients from its two polynomial components (representative and modulus); in other words, assuming a polmod represents an element of R[X]/(T(X)), the variable X is a mute variable and the integral is taken with respect to the main variable used in the base ring R. In particular, it is meaningless to integrate with respect to the main variable of `x.mod`:

      ? intformal(Mod(1,x^2+1), 'x)
      *** intformal: incorrect priority in intformal: variable x = x

The library syntax is `GEN integ(GEN x, long v = -1)`, where `v` is a variable number.

#### padicappr(pol,a)

Vector of p-adic roots of the polynomial pol congruent to the p-adic number a modulo p, and with the same p-adic precision as a. The number a can be an ordinary p-adic number (type `t_PADIC`, i.e. an element of Z_p) or can be an integral element of a finite extension of Q_p, given as a `t_POLMOD` at least one of whose coefficients is a `t_PADIC`. In this case, the result is the vector of roots belonging to the same extension of Q_p as a.

The library syntax is `GEN padicappr(GEN pol, GEN a)`. Also available is `GEN Zp_appr(GEN f, GEN a)` when a is a `t_PADIC`.

#### padicfields(p, N, {flag = 0})

Returns a vector of polynomials generating all the extensions of degree N of the field Q_p of p-adic rational numbers; N is allowed to be a 2-component vector [n,d], in which case we return the extensions of degree n and discriminant p^d.

The list is minimal in the sense that two different polynomials generate non-isomorphic extensions; in particular, the number of polynomials is the number of classes of non-isomorphic extensions. If P is a polynomial in this list, alpha is any root of P and K = Q_p(alpha), then alpha is the sum of a uniformizer and a (lift of a) generator of the residue field of K; in particular, the powers of alpha generate the ring of p-adic integers of K.

If flag = 1, replace each polynomial P by a vector [P, e, f, d, c] where e is the ramification index, f the residual degree, d the valuation of the discriminant, and c the number of conjugate fields. If flag = 2, only return the number of extensions in a fixed algebraic closure (Krasner's formula), which is much faster.

The library syntax is `GEN padicfields0(GEN p, GEN N, long flag)`. Also available is `GEN padicfields(GEN p, long n, long d, long flag)`, which computes extensions of Q_p of degree n and discriminant p^d.

#### polchebyshev(n,{flag = 1},{a = 'x})

Returns the n-th Chebyshev polynomial of the first kind T_n (flag = 1) or the second kind U_n (flag = 2), evaluated at a (`'x` by default). Both series of polynomials satisfy the 3-term relation P_{n+1} = 2xP_n - P_{n-1}, and are determined by the initial conditions U_0 = T_0 = 1, T_1 = x, U_1 = 2x. In fact T_n' = n U_{n-1} and, for all complex numbers z, we have T_n(cos z) = cos (nz) and U_{n-1}(cos z) = sin(nz)/sin z. If n `>=` 0, then these polynomials have degree n. For n < 0, T_n is equal to T_{-n} and U_n is equal to -U_{-2-n}. In particular, U_{-1} = 0.

The library syntax is `GEN polchebyshev_eval(long n, long flag, GEN a = NULL)`. Also available are `GEN polchebyshev(long n, long flag, long v)`, `GEN polchebyshev1(long n, long v)` and `GEN polchebyshev2(long n, long v)` for T_n and U_n respectively.

#### polcoeff(x,n,{v})

Coefficient of degree n of the polynomial x, with respect to the main variable if v is omitted, with respect to v otherwise. If n is greater than the degree, the result is zero.

Naturally applies to scalars (polynomial of degree 0), as well as to rational functions whose denominator is a monomial. It also applies to power series: if n is less than the valuation, the result is zero. If it is greater than the largest significant degree, then an error message is issued.

For greater flexibility, x can be a vector or matrix type and the function then returns `component(x,n)`.

The library syntax is `GEN polcoeff0(GEN x, long n, long v = -1)`, where `v` is a variable number.

#### polcyclo(n,{a = 'x})

n-th cyclotomic polynomial, evaluated at a (`'x` by default). The integer n must be positive.

Algorithm used: reduce to the case where n is squarefree; to compute the cyclotomic polynomial, use Phi_{np}(x) = Phi_n(x^p)/Phi(x); to compute it evaluated, use Phi_n(x) = prod_{d | n} (x^d-1)^{mu(n/d)}. In the evaluated case, the algorithm assumes that a^d - 1 is either 0 or invertible, for all d | n. If this is not the case (the base ring has zero divisors), use `subst(polcyclo(n),x,a)`.

The library syntax is `GEN polcyclo_eval(long n, GEN a = NULL)`. The variant `GEN polcyclo(long n, long v)` returns the n-th cyclotomic polynomial in variable v.

#### polcyclofactors(f)

Returns a vector of polynomials, whose product is the product of distinct cyclotomic polynomials dividing f.

      ? f = x^10+5*x^8-x^7+8*x^6-4*x^5+8*x^4-3*x^3+7*x^2+3;
      ? v = polcyclofactors(f)
      %2 = [x^2 + 1, x^2 + x + 1, x^4 - x^3 + x^2 - x + 1]
      ? apply(poliscycloprod, v)
      %3 = [1, 1, 1]
      ? apply(poliscyclo, v)
      %4 = [4, 3, 10]

In general, the poynomials are products of cyclotomic polynomials and not themselves irreducible:

      ? g = x^8+2*x^7+6*x^6+9*x^5+12*x^4+11*x^3+10*x^2+6*x+3;
      ? polcyclofactors(g)
      %2 = [x^6 + 2*x^5 + 3*x^4 + 3*x^3 + 3*x^2 + 2*x + 1]
      ? factor(%[1])
      %3 =
      [            x^2 + x + 1 1]

      [x^4 + x^3 + x^2 + x + 1 1]

The library syntax is `GEN polcyclofactors(GEN f)`.

#### poldegree(x,{v})

Degree of the polynomial x in the main variable if v is omitted, in the variable v otherwise.

The degree of 0 is a fixed negative number, whose exact value should not be used. The degree of a non-zero scalar is 0. Finally, when x is a non-zero polynomial or rational function, returns the ordinary degree of x. Raise an error otherwise.

The library syntax is `long poldegree(GEN x, long v = -1)`, where `v` is a variable number.

#### poldisc(pol,{v})

Discriminant of the polynomial pol in the main variable if v is omitted, in v otherwise. The algorithm used is the subresultant algorithm.

The library syntax is `GEN poldisc0(GEN pol, long v = -1)`, where `v` is a variable number.

#### poldiscreduced(f)

Reduced discriminant vector of the (integral, monic) polynomial f. This is the vector of elementary divisors of Z[alpha]/f'(alpha)Z[alpha], where alpha is a root of the polynomial f. The components of the result are all positive, and their product is equal to the absolute value of the discriminant of f.

The library syntax is `GEN reduceddiscsmith(GEN f)`.

#### polgraeffe(f)

Returns the Graeffe transform g of f, such that g(x^2) = f(x) f(-x).

The library syntax is `GEN polgraeffe(GEN f)`.

#### polhensellift(A, B, p, e)

Given a prime p, an integral polynomial A whose leading coefficient is a p-unit, a vector B of integral polynomials that are monic and pairwise relatively prime modulo p, and whose product is congruent to A/{lc}(A) modulo p, lift the elements of B to polynomials whose product is congruent to A modulo p^e.

More generally, if T is an integral polynomial irreducible mod p, and B is a factorization of A over the finite field F_p[t]/(T), you can lift it to Z_p[t]/(T, p^e) by replacing the p argument with [p,T]:

      ? { T = t^3 - 2; p = 7; A = x^2 + t + 1;
          B = [x + (3*t^2 + t + 1), x + (4*t^2 + 6*t + 6)];
          r = polhensellift(A, B, [p, T], 6) }
      %1 = [x + (20191*t^2 + 50604*t + 75783), x + (97458*t^2 + 67045*t + 41866)]
      ? liftall( r[1] * r[2] * Mod(Mod(1,p^6),T) )
      %2 = x^2 + (t + 1)

The library syntax is `GEN polhensellift(GEN A, GEN B, GEN p, long e)`.

#### polhermite(n,{a = 'x})

n-th Hermite polynomial H_n evaluated at a (`'x` by default), i.e. H_n(x) = (-1)^n e^{x^2} (d^n)/(dx^n)e^{-x^2}.

The library syntax is `GEN polhermite_eval(long n, GEN a = NULL)`. The variant `GEN polhermite(long n, long v)` returns the n-th Hermite polynomial in variable v.

#### polinterpolate(X,{Y},{x},{&e})

Given the data vectors X and Y of the same length n (X containing the x-coordinates, and Y the corresponding y-coordinates), this function finds the interpolating polynomial passing through these points and evaluates it at x. If Y is omitted, return the polynomial interpolating the (i,X[i]). If present, e will contain an error estimate on the returned value.

The library syntax is `GEN polint(GEN X, GEN Y = NULL, GEN x = NULL, GEN *e = NULL)`.

#### poliscyclo(f)

Returns 0 if f is not a cyclotomic polynomial, and n > 0 if f = Phi_n, the n-th cyclotomic polynomial.

      ? poliscyclo(x^4-x^2+1)
      %1 = 12
      ? polcyclo(12)
      %2 = x^4 - x^2 + 1
      ? poliscyclo(x^4-x^2-1)
      %3 = 0

The library syntax is `long poliscyclo(GEN f)`.

#### poliscycloprod(f)

Returns 1 if f is a product of cyclotomic polynomial, and 0 otherwise.

      ? f = x^6+x^5-x^3+x+1;
      ? poliscycloprod(f)
      %2 = 1
      ? factor(f)
      %3 =
      [  x^2 + x + 1 1]

      [x^4 - x^2 + 1 1]
      ? [ poliscyclo(T) | T <- %[,1] ]
      %4 = [3, 12]
      ? polcyclo(3) * polcyclo(12)
      %5 = x^6 + x^5 - x^3 + x + 1

The library syntax is `long poliscycloprod(GEN f)`.

#### polisirreducible(pol)

pol being a polynomial (univariate in the present version 2.7.0), returns 1 if pol is non-constant and irreducible, 0 otherwise. Irreducibility is checked over the smallest base field over which pol seems to be defined.

The library syntax is `long isirreducible(GEN pol)`.

#### pollead(x,{v})

Leading coefficient of the polynomial or power series x. This is computed with respect to the main variable of x if v is omitted, with respect to the variable v otherwise.

The library syntax is `GEN pollead(GEN x, long v = -1)`, where `v` is a variable number.

#### pollegendre(n,{a = 'x})

n-th Legendre polynomial evaluated at a (`'x` by default).

The library syntax is `GEN pollegendre_eval(long n, GEN a = NULL)`. To obtain the n-th Legendre polynomial in variable v, use `GEN pollegendre(long n, long v)`.

#### polrecip(pol)

Reciprocal polynomial of pol, i.e. the coefficients are in reverse order. pol must be a polynomial.

The library syntax is `GEN polrecip(GEN pol)`.

#### polresultant(x,y,{v},{flag = 0})

Resultant of the two polynomials x and y with exact entries, with respect to the main variables of x and y if v is omitted, with respect to the variable v otherwise. The algorithm assumes the base ring is a domain. If you also need the u and v such that x*u + y*v = {Res}(x,y), use the `polresultantext` function.

If flag = 0 (default), uses the the algorithm best suited to the inputs, either the subresultant algorithm (Lazard/Ducos variant, generic case), a modular algorithm (inputs in Q[X]) or Sylvester's matrix (inexact inputs).

If flag = 1, uses the determinant of Sylvester's matrix instead; this should always be slower than the default.

The library syntax is `GEN polresultant0(GEN x, GEN y, long v = -1, long flag)`, where `v` is a variable number.

#### polresultantext(A,B,{v})

Finds polynomials U and V such that A*U + B*V = R, where R is the resultant of U and V with respect to the main variables of A and B if v is omitted, and with respect to v otherwise. Returns the row vector [U,V,R]. The algorithm used (subresultant) assumes that the base ring is a domain.

      ? A = x*y; B = (x+y)^2;
      ? [U,V,R] = polresultantext(A, B)
      %2 = [-y*x - 2*y^2, y^2, y^4]
      ? A*U + B*V
      %3 = y^4
      ? [U,V,R] = polresultantext(A, B, y)
      %4 = [-2*x^2 - y*x, x^2, x^4]
      ? A*U+B*V
      %5 = x^4

The library syntax is `GEN polresultantext0(GEN A, GEN B, long v = -1)`, where `v` is a variable number. Also available is `GEN polresultantext(GEN x, GEN y)`.

#### polroots(x)

Complex roots of the polynomial pol, given as a column vector where each root is repeated according to its multiplicity. The precision is given as for transcendental functions: in GP it is kept in the variable `realprecision` and is transparent to the user, but it must be explicitly given as a second argument in library mode.

The algorithm used is a modification of A. Sch¨nhage's root-finding algorithm, due to and originally implemented by X. Gourdon. Barring bugs, it is guaranteed to converge and to give the roots to the required accuracy.

The library syntax is `GEN roots(GEN x, long prec)`.

#### polrootsmod(pol,p,{flag = 0})

Row vector of roots modulo p of the polynomial pol. Multiple roots are not repeated.

      ? polrootsmod(x^2-1,2)
      %1 = [Mod(1, 2)]~

If p is very small, you may set flag = 1, which uses a naive search.

The library syntax is `GEN rootmod0(GEN pol, GEN p, long flag)`.

#### polrootspadic(x,p,r)

Vector of p-adic roots of the polynomial pol, given to p-adic precision r p is assumed to be a prime. Multiple roots are not repeated. Note that this is not the same as the roots in Z/p^rZ, rather it gives approximations in Z/p^rZ of the true roots living in Q_p.

      ? polrootspadic(x^3 - x^2 + 64, 2, 5)
      %1 = [2^3 + O(2^5), 2^3 + 2^4 + O(2^5), 1 + O(2^5)]~

If pol has inexact `t_PADIC` coefficients, this is not always well-defined; in this case, the polynomial is first made integral by dividing out the p-adic content, then lifted to Z using `truncate` coefficientwise. Hence the roots given are approximations of the roots of an exact polynomial which is p-adically close to the input. To avoid pitfalls, we advise to only factor polynomials with eact rational coefficients.

The library syntax is `GEN rootpadic(GEN x, GEN p, long r)`.

#### polsturm(pol,{a},{b})

Number of real roots of the real squarefree polynomial pol in the interval ]a,b], using Sturm's algorithm. a (resp. b) is taken to be - oo (resp. + oo ) if omitted.

The library syntax is `long sturmpart(GEN pol, GEN a = NULL, GEN b = NULL)`. Also available is `long sturm(GEN pol)` (total number of real roots).

#### polsubcyclo(n,d,{v = 'x})

Gives polynomials (in variable v) defining the sub-Abelian extensions of degree d of the cyclotomic field Q(zeta_n), where d | phi(n).

If there is exactly one such extension the output is a polynomial, else it is a vector of polynomials, possibly empty. To get a vector in all cases, use `concat([], polsubcyclo(n,d))`.

The function `galoissubcyclo` allows to specify exactly which sub-Abelian extension should be computed.

The library syntax is `GEN polsubcyclo(long n, long d, long v = -1)`, where `v` is a variable number.

#### polsylvestermatrix(x,y)

Forms the Sylvester matrix corresponding to the two polynomials x and y, where the coefficients of the polynomials are put in the columns of the matrix (which is the natural direction for solving equations afterwards). The use of this matrix can be essential when dealing with polynomials with inexact entries, since polynomial Euclidean division doesn't make much sense in this case.

The library syntax is `GEN sylvestermatrix(GEN x, GEN y)`.

#### polsym(x,n)

Creates the column vector of the symmetric powers of the roots of the polynomial x up to power n, using Newton's formula.

The library syntax is `GEN polsym(GEN x, long n)`.

#### poltchebi(n,{v = 'x})

Deprecated alias for `polchebyshev`

The library syntax is `GEN polchebyshev1(long n, long v = -1)`, where `v` is a variable number.

#### polzagier(n,m)

Creates Zagier's polynomial P_n^{(m)} used in the functions `sumalt` and `sumpos` (with flag = 1). One must have m\le n. The exact definition can be found in "Convergence acceleration of alternating series", Cohen et al., Experiment. Math., vol. 9, 2000, pp. 3--12.

The library syntax is `GEN polzag(long n, long m)`.

#### serconvol(x,y)

Convolution (or Hadamard product) of the two power series x and y; in other words if x = sum a_k*X^k and y = sum b_k*X^k then `serconvol`(x,y) = sum a_k*b_k*X^k.

The library syntax is `GEN convol(GEN x, GEN y)`.

#### serlaplace(x)

x must be a power series with non-negative exponents. If x = sum (a_k/k!)*X^k then the result is sum a_k*X^k.

The library syntax is `GEN laplace(GEN x)`.

#### serreverse(s)

Reverse power series of s, i.e. the series t such that t(s) = x; s must be a power series whose valuation is exactly equal to one.

      ? \ps 8
      ? t = serreverse(tan(x))
      %2 = x - 1/3*x^3 + 1/5*x^5 - 1/7*x^7 + O(x^8)
      ? tan(t)
      %3 = x + O(x^8)

The library syntax is `GEN serreverse(GEN s)`.

#### subst(x,y,z)

Replace the simple variable y by the argument z in the "polynomial" expression x. Every type is allowed for x, but if it is not a genuine polynomial (or power series, or rational function), the substitution will be done as if the scalar components were polynomials of degree zero. In particular, beware that:

      ? subst(1, x, [1,2; 3,4])
      %1 =
      [1 0]

      [0 1]

      ? subst(1, x, Mat([0,1]))
        ***   at top-level: subst(1,x,Mat([0,1])
        ***                 ^--------------------
        *** subst: forbidden substitution by a non square matrix.

If x is a power series, z must be either a polynomial, a power series, or a rational function. Finally, if x is a vector, matrix or list, the substitution is applied to each individual entry.

Use the function `substvec` to replace several variables at once, or the function `substpol` to replace a polynomial expression.

The library syntax is `GEN gsubst(GEN x, long y, GEN z)`, where `y` is a variable number.

#### substpol(x,y,z)

Replace the "variable" y by the argument z in the "polynomial" expression x. Every type is allowed for x, but the same behavior as `subst` above apply.

The difference with `subst` is that y is allowed to be any polynomial here. The substitution is done moding out all components of x (recursively) by y - t, where t is a new free variable of lowest priority. Then substituting t by z in the resulting expression. For instance

      ? substpol(x^4 + x^2 + 1, x^2, y)
      %1 = y^2 + y + 1
      ? substpol(x^4 + x^2 + 1, x^3, y)
      %2 = x^2 + y*x + 1
      ? substpol(x^4 + x^2 + 1, (x+1)^2, y)
      %3 = (-4*y - 6)*x + (y^2 + 3*y - 3)

The library syntax is `GEN gsubstpol(GEN x, GEN y, GEN z)`. Further, `GEN gdeflate(GEN T, long v, long d)` attempts to write T(x) in the form t(x^d), where x = `pol_x`(v), and returns `NULL` if the substitution fails (for instance in the example `%2` above).

#### substvec(x,v,w)

v being a vector of monomials of degree 1 (variables), w a vector of expressions of the same length, replace in the expression x all occurrences of v_i by w_i. The substitutions are done simultaneously; more precisely, the v_i are first replaced by new variables in x, then these are replaced by the w_i:

      ? substvec([x,y], [x,y], [y,x])
      %1 = [y, x]
      ? substvec([x,y], [x,y], [y,x+y])
      %2 = [y, x + y]     \\ not [y, 2*y]

The library syntax is `GEN gsubstvec(GEN x, GEN v, GEN w)`.

#### sumformal(f,{v})

formal sum of the polynomial expression f with respect to the main variable if v is omitted, with respect to the variable v otherwise; it is assumed that the base ring has characteristic zero. In other words, considering f as a polynomial function in the variable v, returns F, a polynomial in v vanishing at 0, such that F(b) - F(a) = sum_{v = a+1}^b f(v):

      ? sumformal(n)  \\ 1 + ... + n
      %1 = 1/2*n^2 + 1/2*n
      ? f(n) = n^3+n^2+1;
      ? F = sumformal(f(n))  \\ f(1) + ... + f(n)
      %3 = 1/4*n^4 + 5/6*n^3 + 3/4*n^2 + 7/6*n
      ? sum(n = 1, 2000, f(n)) == subst(F, n, 2000)
      %4 = 1
      ? sum(n = 1001, 2000, f(n)) == subst(F, n, 2000) - subst(F, n, 1000)
      %5 = 1
      ? sumformal(x^2 + x*y + y^2, y)
      %6 = y*x^2 + (1/2*y^2 + 1/2*y)*x + (1/3*y^3 + 1/2*y^2 + 1/6*y)
      ? x^2 * y + x * sumformal(y) + sumformal(y^2) == %
      %7 = 1

The library syntax is `GEN sumformal(GEN f, long v = -1)`, where `v` is a variable number.

#### taylor(x,t,{d = seriesprecision})

Taylor expansion around 0 of x with respect to the simple variable t. x can be of any reasonable type, for example a rational function. Contrary to `Ser`, which takes the valuation into account, this function adds O(t^d) to all components of x.

      ? taylor(x/(1+y), y, 5)
      %1 = (y^4 - y^3 + y^2 - y + 1)*x + O(y^5)
      ? Ser(x/(1+y), y, 5)
       ***   at top-level: Ser(x/(1+y),y,5)
       ***                 ^----------------
       *** Ser: main variable must have higher priority in gtoser.

The library syntax is `GEN tayl(GEN x, long t, long precdl)`, where `t` is a variable number.

#### thue(tnf,a,{sol})

Returns all solutions of the equation P(x,y) = a in integers x and y, where tnf was created with `thueinit`(P). If present, sol must contain the solutions of Norm(x) = a modulo units of positive norm in the number field defined by P (as computed by `bnfisintnorm`). If there are infinitely many solutions, an error will be issued.

It is allowed to input directly the polynomial P instead of a tnf, in which case, the function first performs `thueinit(P,0)`. This is very wasteful if more than one value of a is required.

If tnf was computed without assuming GRH (flag 1 in `thueinit`), then the result is unconditional. Otherwise, it depends in principle of the truth of the GRH, but may still be unconditionally correct in some favourable cases. The result is conditional on the GRH if a != ± 1 and, P has a single irreducible rational factor, whose associated tentative class number h and regulator R (as computed assuming the GRH) satisfy

* h > 1,

* R/0.2 > 1.5.

Here's how to solve the Thue equation x^{13} - 5y^{13} = - 4:

      ? tnf = thueinit(x^13 - 5);
      ? thue(tnf, -4)
      %1 = [[1, 1]]

In this case, one checks that `bnfinit(x^13 -5).no` is 1. Hence, the only solution is (x,y) = (1,1), and the result is unconditional. On the other hand:

      ? P = x^3-2*x^2+3*x-17; tnf = thueinit(P);
      ? thue(tnf, -15)
      %2 = [[1, 1]]  \\ a priori conditional on the GRH.
      ? K = bnfinit(P); K.no
      %3 = 3
      ? K.reg
      %4 = 2.8682185139262873674706034475498755834

This time the result is conditional. All results computed using this particular tnf are likewise conditional, except for a right-hand side of ± 1. The above result is in fact correct, so we did not just disprove the GRH:

      ? tnf = thueinit(x^3-2*x^2+3*x-17, 1 /*unconditional*/);
      ? thue(tnf, -15)
      %4 = [[1, 1]]

Note that reducible or non-monic polynomials are allowed:

      ? tnf = thueinit((2*x+1)^5 * (4*x^3-2*x^2+3*x-17), 1);
      ? thue(tnf, 128)
      %2 = [[-1, 0], [1, 0]]

Reducible polynomials are in fact much easier to handle.

The library syntax is `GEN thue(GEN tnf, GEN a, GEN sol = NULL)`.

#### thueinit(P,{flag = 0})

Initializes the tnf corresponding to P, a univariate polynomial with integer coefficients. The result is meant to be used in conjunction with `thue` to solve Thue equations P(X / Y)Y^{deg P} = a, where a is an integer.

If flag is non-zero, certify results unconditionally. Otherwise, assume GRH, this being much faster of course. In the latter case, the result may still be unconditionally correct, see `thue`. For instance in most cases where P is reducible (not a pure power of an irreducible), or conditional computed class groups are trivial or the right hand side is ±1, then results are always unconditional.

The library syntax is `GEN thueinit(GEN P, long flag, long prec)`.