Sage class for PARI’s GEN type

See the PariInstance class for documentation and examples.

AUTHORS:

  • William Stein (2006-03-01): updated to work with PARI 2.2.12-beta
  • William Stein (2006-03-06): added newtonpoly
  • Justin Walker: contributed some of the function definitions
  • Gonzalo Tornaria: improvements to conversions; much better error handling.
  • Robert Bradshaw, Jeroen Demeyer, William Stein (2010-08-15): Upgrade to PARI 2.4.3 (trac ticket #9343)
  • Jeroen Demeyer (2011-11-12): rewrite various conversion routines (trac ticket #11611, trac ticket #11854, trac ticket #11952)
  • Peter Bruin (2013-11-17): move PariInstance to a separate file (trac ticket #15185)
  • Jeroen Demeyer (2014-02-09): upgrade to PARI 2.7 (trac ticket #15767)
  • Martin von Gagern (2014-12-17): Added some Galois functions (trac ticket #17519)
  • Jeroen Demeyer (2015-01-12): upgrade to PARI 2.8 (trac ticket #16997)
  • Jeroen Demeyer (2015-03-17): automatically generate methods from pari.desc (trac ticket #17631 and trac ticket #17860)
class sage.libs.pari.gen.gen

Bases: sage.libs.pari.gen.gen_auto

Cython extension class that models the PARI GEN type.

Col(x, n=0)

Transform the object x into a column vector with minimal size |n|.

INPUT:

  • x – gen
  • n – Make the column vector of minimal length |n|. If n > 0, append zeros; if n < 0, prepend zeros.

OUTPUT:

A PARI column vector (type t_COL)

EXAMPLES:

sage: pari(1.5).Col()
[1.50000000000000]~
sage: pari([1,2,3,4]).Col()
[1, 2, 3, 4]~
sage: pari('[1,2; 3,4]').Col()
[[1, 2], [3, 4]]~
sage: pari('"Sage"').Col()
["S", "a", "g", "e"]~
sage: pari('x + 3*x^3').Col()
[3, 0, 1, 0]~
sage: pari('x + 3*x^3 + O(x^5)').Col()
[1, 0, 3, 0]~

We demonstate the n argument:

sage: pari([1,2,3,4]).Col(2)
[1, 2, 3, 4]~
sage: pari([1,2,3,4]).Col(-2)
[1, 2, 3, 4]~
sage: pari([1,2,3,4]).Col(6)
[1, 2, 3, 4, 0, 0]~
sage: pari([1,2,3,4]).Col(-6)
[0, 0, 1, 2, 3, 4]~

See also Vec() (create a row vector) for more examples and Colrev() (create a column in reversed order).

Colrev(x, n=0)

Transform the object x into a column vector with minimal size |n|. The order of the resulting vector is reversed compared to Col().

INPUT:

  • x – gen
  • n – Make the vector of minimal length |n|. If n > 0, prepend zeros; if n < 0, append zeros.

OUTPUT:

A PARI column vector (type t_COL)

EXAMPLES:

sage: pari(1.5).Colrev()
[1.50000000000000]~
sage: pari([1,2,3,4]).Colrev()
[4, 3, 2, 1]~
sage: pari('[1,2; 3,4]').Colrev()
[[3, 4], [1, 2]]~
sage: pari('x + 3*x^3').Colrev()
[0, 1, 0, 3]~

We demonstate the n argument:

sage: pari([1,2,3,4]).Colrev(2)
[4, 3, 2, 1]~
sage: pari([1,2,3,4]).Colrev(-2)
[4, 3, 2, 1]~
sage: pari([1,2,3,4]).Colrev(6)
[0, 0, 4, 3, 2, 1]~
sage: pari([1,2,3,4]).Colrev(-6)
[4, 3, 2, 1, 0, 0]~
List(x)

List(x): transforms the PARI vector or list x into a list.

EXAMPLES:

sage: v = pari([1,2,3])
sage: v
[1, 2, 3]
sage: v.type()
't_VEC'
sage: w = v.List()
sage: w
List([1, 2, 3])
sage: w.type()
't_LIST'
Mat(x)

Mat(x): Returns the matrix defined by x.

  • If x is already a matrix, a copy of x is created and returned.
  • If x is not a vector or a matrix, this function returns a 1x1 matrix.
  • If x is a row (resp. column) vector, this functions returns a 1-row (resp. 1-column) matrix, unless all elements are column (resp. row) vectors of the same length, in which case the vectors are concatenated sideways and the associated big matrix is returned.

INPUT:

  • x - gen

OUTPUT:

  • gen - a PARI matrix

EXAMPLES:

sage: x = pari(5)
sage: x.type()
't_INT'
sage: y = x.Mat()
sage: y
Mat(5)
sage: y.type()
't_MAT'
sage: x = pari('[1,2;3,4]')
sage: x.type()
't_MAT'
sage: x = pari('[1,2,3,4]')
sage: x.type()
't_VEC'
sage: y = x.Mat()
sage: y
Mat([1, 2, 3, 4])
sage: y.type()
't_MAT'
sage: v = pari('[1,2;3,4]').Vec(); v
[[1, 3]~, [2, 4]~]
sage: v.Mat()
[1, 2; 3, 4]
sage: v = pari('[1,2;3,4]').Col(); v
[[1, 2], [3, 4]]~
sage: v.Mat()
[1, 2; 3, 4]
Mod(x, y)

Mod(x, y): Returns the object x modulo y, denoted Mod(x, y).

The input y must be a an integer or a polynomial:

  • If y is an INTEGER, x must also be an integer, a rational number, or a p-adic number compatible with the modulus y.
  • If y is a POLYNOMIAL, x must be a scalar (which is not a polmod), a polynomial, a rational function, or a power series.

Warning

This function is not the same as x % y which is an integer or a polynomial.

INPUT:

  • x - gen
  • y - integer or polynomial

OUTPUT:

  • gen - intmod or polmod

EXAMPLES:

sage: z = pari(3)
sage: x = z.Mod(pari(7))
sage: x
Mod(3, 7)
sage: x^2
Mod(2, 7)
sage: x^100
Mod(4, 7)
sage: x.type()
't_INTMOD'
sage: f = pari("x^2 + x + 1")
sage: g = pari("x")
sage: a = g.Mod(f)
sage: a
Mod(x, x^2 + x + 1)
sage: a*a
Mod(-x - 1, x^2 + x + 1)
sage: a.type()
't_POLMOD'
Pol(v=-1)

Pol(x, v): convert x into a polynomial with main variable v and return the result.

  • If x is a scalar, returns a constant polynomial.
  • If x is a power series, the effect is identical to truncate, i.e. it chops off the O(X^k).
  • If x is a vector, this function creates the polynomial whose coefficients are given in x, with x[0] being the leading coefficient (which can be zero).

Warning

This is not a substitution function. It will not transform an object containing variables of higher priority than v:

sage: pari('x+y').Pol('y')
Traceback (most recent call last):
...
PariError: incorrect priority in gtopoly: variable x < y

INPUT:

  • x - gen
  • v - (optional) which variable, defaults to ‘x’

OUTPUT:

  • gen - a polynomial

EXAMPLES:

sage: v = pari("[1,2,3,4]")
sage: f = v.Pol()
sage: f
x^3 + 2*x^2 + 3*x + 4
sage: f*f
x^6 + 4*x^5 + 10*x^4 + 20*x^3 + 25*x^2 + 24*x + 16
sage: v = pari("[1,2;3,4]")
sage: v.Pol()
[1, 3]~*x + [2, 4]~
Polrev(v=-1)

Polrev(x, v): Convert x into a polynomial with main variable v and return the result. This is the reverse of Pol if x is a vector, otherwise it is identical to Pol. By “reverse” we mean that the coefficients are reversed.

INPUT:

  • x - gen

OUTPUT:

  • gen - a polynomial

EXAMPLES:

sage: v = pari("[1,2,3,4]")
sage: f = v.Polrev()
sage: f
4*x^3 + 3*x^2 + 2*x + 1
sage: v.Pol()
x^3 + 2*x^2 + 3*x + 4
sage: v.Polrev('y')
4*y^3 + 3*y^2 + 2*y + 1

Note that Polrev does not reverse the coefficients of a polynomial!

sage: f
4*x^3 + 3*x^2 + 2*x + 1
sage: f.Polrev()
4*x^3 + 3*x^2 + 2*x + 1
sage: v = pari("[1,2;3,4]")
sage: v.Polrev()
[2, 4]~*x + [1, 3]~
Qfb(a, b, c, D=0, precision=0)

Qfb(a,b,c,D=0.): Returns the binary quadratic form

ax^2 + bxy + cy^2.

The optional D is 0 by default and initializes Shank’s distance if b^2 - 4ac > 0. The discriminant of the quadratic form must not be a perfect square.

Note

Negative definite forms are not implemented, so use their positive definite counterparts instead. (I.e., if f is a negative definite quadratic form, then -f is positive definite.)

INPUT:

  • a - gen
  • b - gen
  • c - gen
  • D - gen (optional, defaults to 0)

OUTPUT:

  • gen - binary quadratic form

EXAMPLES:

sage: pari(3).Qfb(7, 1)
Qfb(3, 7, 1, 0.E-19)
sage: pari(3).Qfb(7, 2)  # discriminant is 25
Traceback (most recent call last):
...
PariError: domain error in Qfb: issquare(disc) = 1
Ser(f, v=-1, precision=-1)

Return a power series or Laurent series in the variable v constructed from the object f.

INPUT:

  • f – PARI gen
  • v – PARI variable (default: x)
  • precision – the desired relative precision (default: the value returned by pari.get_series_precision()). This is the absolute precision minus the v-adic valuation.

OUTPUT:

  • PARI object of type t_SER

The series is constructed from f in the following way:

  • If f is a scalar, a constant power series is returned.
  • If f is a polynomial, it is converted into a power series in the obvious way.
  • If f is a rational function, it will be expanded in a Laurent series around v = 0.
  • If f is a vector, its coefficients become the coefficients of the power series, starting from the constant term. This is the convention used by the function Polrev(), and the reverse of that used by Pol().

Warning

This function will not transform objects containing variables of higher priority than v.

EXAMPLES:

sage: pari(2).Ser()
2 + O(x^16)
sage: pari(Mod(0, 7)).Ser()
Mod(0, 7)*x^15 + O(x^16)

sage: x = pari([1, 2, 3, 4, 5])
sage: x.Ser()
1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 + O(x^16)
sage: f = x.Ser('v'); print f
1 + 2*v + 3*v^2 + 4*v^3 + 5*v^4 + O(v^16)
sage: pari(1)/f
1 - 2*v + v^2 + 6*v^5 - 17*v^6 + 16*v^7 - 5*v^8 + 36*v^10 - 132*v^11 + 181*v^12 - 110*v^13 + 25*v^14 + 216*v^15 + O(v^16)

sage: pari('x^5').Ser(precision=20)
x^5 + O(x^25)
sage: pari('1/x').Ser(precision=1)
x^-1 + O(x^0)
Set(x)

Set(x): convert x into a set, i.e. a row vector of strings in increasing lexicographic order.

INPUT:

  • x - gen

OUTPUT:

  • gen - a vector of strings in increasing lexicographic order.

EXAMPLES:

sage: pari([1,5,2]).Set()
[1, 2, 5]
sage: pari([]).Set()     # the empty set
[]
sage: pari([1,1,-1,-1,3,3]).Set()
[-1, 1, 3]
sage: pari(1).Set()
[1]
sage: pari('1/(x*y)').Set()
[1/(y*x)]
sage: pari('["bc","ab","bc"]').Set()
["ab", "bc"]
Str()

Str(self): Return the print representation of self as a PARI object.

INPUT:

  • self - gen

OUTPUT:

  • gen - a PARI gen of type t_STR, i.e., a PARI string

EXAMPLES:

sage: pari([1,2,['abc',1]]).Str()
"[1, 2, [abc, 1]]"
sage: pari([1,1, 1.54]).Str()
"[1, 1, 1.54000000000000]"
sage: pari(1).Str()       # 1 is automatically converted to string rep
"1"
sage: x = pari('x')       # PARI variable "x"
sage: x.Str()             # is converted to string rep.
"x"
sage: x.Str().type()
't_STR'
Strchr(x)

Strchr(x): converts x to a string, translating each integer into a character (in ASCII).

Note

Vecsmall() is (essentially) the inverse to Strchr().

INPUT:

  • x - PARI vector of integers

OUTPUT:

  • gen - a PARI string

EXAMPLES:

sage: pari([65,66,123]).Strchr()
"AB{"
sage: pari('"Sage"').Vecsmall()   # pari('"Sage"') --> PARI t_STR
Vecsmall([83, 97, 103, 101])
sage: _.Strchr()
"Sage"
sage: pari([83, 97, 103, 101]).Strchr()
"Sage"
Strexpand(x)

Concatenate the entries of the vector x into a single string, then perform tilde expansion and environment variable expansion similar to shells.

INPUT:

  • x – PARI gen. Either a vector or an element which is then treated like [x].

OUTPUT:

  • PARI string (type t_STR)

EXAMPLES:

sage: pari('"~/subdir"').Strexpand()     # random
"/home/johndoe/subdir"
sage: pari('"$SAGE_LOCAL"').Strexpand()  # random
"/usr/local/sage/local"

TESTS:

sage: a = pari('"$HOME"')
sage: a.Strexpand() != a
True
Strtex(x)

Strtex(x): Translates the vector x of PARI gens to TeX format and returns the resulting concatenated strings as a PARI t_STR.

INPUT:

  • x – PARI gen. Either a vector or an element which is then treated like [x].

OUTPUT:

  • PARI string (type t_STR)

EXAMPLES:

sage: v=pari('x^2')
sage: v.Strtex()
"x^2"
sage: v=pari(['1/x^2','x'])
sage: v.Strtex()
"\\frac{1}{x^2}x"
sage: v=pari(['1 + 1/x + 1/(y+1)','x-1'])
sage: v.Strtex()
"\\frac{ \\left(y\n + 2\\right) \\*x\n + \\left(y\n + 1\\right) }{ \\left(y\n + 1\\right) \\*x}x\n - 1"
Vec(x, n=0)

Transform the object x into a vector with minimal size |n|.

INPUT:

  • x – gen
  • n – Make the vector of minimal length |n|. If n > 0, append zeros; if n < 0, prepend zeros.

OUTPUT:

A PARI vector (type t_VEC)

EXAMPLES:

sage: pari(1).Vec()
[1]
sage: pari('x^3').Vec()
[1, 0, 0, 0]
sage: pari('x^3 + 3*x - 2').Vec()
[1, 0, 3, -2]
sage: pari([1,2,3]).Vec()
[1, 2, 3]
sage: pari('[1, 2; 3, 4]').Vec()
[[1, 3]~, [2, 4]~]
sage: pari('"Sage"').Vec()
["S", "a", "g", "e"]
sage: pari('2*x^2 + 3*x^3 + O(x^5)').Vec()
[2, 3, 0]
sage: pari('2*x^-2 + 3*x^3 + O(x^5)').Vec()
[2, 0, 0, 0, 0, 3, 0]

Note the different term ordering for polynomials and series:

sage: pari('1 + x + 3*x^3 + O(x^5)').Vec()
[1, 1, 0, 3, 0]
sage: pari('1 + x + 3*x^3').Vec()
[3, 0, 1, 1]

We demonstate the n argument:

sage: pari([1,2,3,4]).Vec(2)
[1, 2, 3, 4]
sage: pari([1,2,3,4]).Vec(-2)
[1, 2, 3, 4]
sage: pari([1,2,3,4]).Vec(6)
[1, 2, 3, 4, 0, 0]
sage: pari([1,2,3,4]).Vec(-6)
[0, 0, 1, 2, 3, 4]

See also Col() (create a column vector) and Vecrev() (create a vector in reversed order).

Vecrev(x, n=0)

Transform the object x into a vector with minimal size |n|. The order of the resulting vector is reversed compared to Vec().

INPUT:

  • x – gen
  • n – Make the vector of minimal length |n|. If n > 0, prepend zeros; if n < 0, append zeros.

OUTPUT:

A PARI vector (type t_VEC)

EXAMPLES:

sage: pari(1).Vecrev()
[1]
sage: pari('x^3').Vecrev()
[0, 0, 0, 1]
sage: pari('x^3 + 3*x - 2').Vecrev()
[-2, 3, 0, 1]
sage: pari([1, 2, 3]).Vecrev()
[3, 2, 1]
sage: pari('Col([1, 2, 3])').Vecrev()
[3, 2, 1]
sage: pari('[1, 2; 3, 4]').Vecrev()
[[2, 4]~, [1, 3]~]
sage: pari('"Sage"').Vecrev()
["e", "g", "a", "S"]

We demonstate the n argument:

sage: pari([1,2,3,4]).Vecrev(2)
[4, 3, 2, 1]
sage: pari([1,2,3,4]).Vecrev(-2)
[4, 3, 2, 1]
sage: pari([1,2,3,4]).Vecrev(6)
[0, 0, 4, 3, 2, 1]
sage: pari([1,2,3,4]).Vecrev(-6)
[4, 3, 2, 1, 0, 0]
Vecsmall(x, n=0)

Transform the object x into a t_VECSMALL with minimal size |n|.

INPUT:

  • x – gen
  • n – Make the vector of minimal length |n|. If n > 0, append zeros; if n < 0, prepend zeros.

OUTPUT:

A PARI vector of small integers (type t_VECSMALL)

EXAMPLES:

sage: pari([1,2,3]).Vecsmall()
Vecsmall([1, 2, 3])
sage: pari('"Sage"').Vecsmall()
Vecsmall([83, 97, 103, 101])
sage: pari(1234).Vecsmall()
Vecsmall([1234])
sage: pari('x^2 + 2*x + 3').Vecsmall()
Vecsmall([1, 2, 3])

We demonstate the n argument:

sage: pari([1,2,3]).Vecsmall(2)
Vecsmall([1, 2, 3])
sage: pari([1,2,3]).Vecsmall(-2)
Vecsmall([1, 2, 3])
sage: pari([1,2,3]).Vecsmall(6)
Vecsmall([1, 2, 3, 0, 0, 0])
sage: pari([1,2,3]).Vecsmall(-6)
Vecsmall([0, 0, 0, 1, 2, 3])
Zn_issquare(n)

Return True if self is a square modulo n, False if not.

INPUT:

  • self – integer
  • n – integer or factorisation matrix

EXAMPLES:

sage: pari(3).Zn_issquare(4)
False
sage: pari(4).Zn_issquare(30.factor())
True
Zn_sqrt(n)

Return a square root of self modulo n, if such a square root exists; otherwise, raise a ValueError.

INPUT:

  • self – integer
  • n – integer or factorisation matrix

EXAMPLES:

sage: pari(3).Zn_sqrt(4)
Traceback (most recent call last):
...
ValueError: 3 is not a square modulo 4
sage: pari(4).Zn_sqrt(30.factor())
22
abs(x, precision=0)

Returns the absolute value of x (its modulus, if x is complex). Rational functions are not allowed. Contrary to most transcendental functions, an exact argument is not converted to a real number before applying abs and an exact result is returned if possible.

EXAMPLES:

sage: x = pari("-27.1")
sage: x.abs()
27.1000000000000
sage: pari('1 + I').abs(precision=128).sage()
1.4142135623730950488016887242096980786

If x is a polynomial, returns -x if the leading coefficient is real and negative else returns x. For a power series, the constant coefficient is considered instead.

EXAMPLES:

sage: pari('x-1.2*x^2').abs()
1.20000000000000*x^2 - x
sage: pari('-2 + t + O(t^2)').abs()
2 - t + O(t^2)
acos(x, precision=0)

The principal branch of \cos^{-1}(x), so that \RR e(\mathrm{acos}(x)) belongs to [0,Pi]. If x is real and |x| > 1, then \mathrm{acos}(x) is complex.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(0.5).acos()
1.04719755119660
sage: pari(1/2).acos()
1.04719755119660
sage: pari(1.1).acos()
0.443568254385115*I
sage: C.<i> = ComplexField()
sage: pari(1.1+i).acos()
0.849343054245252 - 1.09770986682533*I
acosh(x, precision=0)

The principal branch of \cosh^{-1}(x), so that \Im(\mathrm{acosh}(x)) belongs to [0,Pi]. If x is real and x < 1, then \mathrm{acosh}(x) is complex.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).acosh()
1.31695789692482
sage: pari(0).acosh()
1.57079632679490*I
sage: C.<i> = ComplexField()
sage: pari(i).acosh()
0.881373587019543 + 1.57079632679490*I
agm(x, y, precision=0)

The arithmetic-geometric mean of x and y. In the case of complex or negative numbers, the principal square root is always chosen. p-adic or power series arguments are also allowed. Note that a p-adic AGM exists only if x/y is congruent to 1 modulo p (modulo 16 for p=2). x and y cannot both be vectors or matrices.

If any of x or y is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their two precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).agm(2)
2.00000000000000
sage: pari(0).agm(1)
0
sage: pari(1).agm(2)
1.45679103104691
sage: C.<i> = ComplexField()
sage: pari(1+i).agm(-3)
-0.964731722290876 + 1.15700282952632*I
algdep(n)

EXAMPLES:

sage: n = pari.set_real_precision(210)
sage: w1 = pari('z1=2-sqrt(26); (z1+I)/(z1-I)')
sage: f = w1.algdep(12); f
545*x^11 - 297*x^10 - 281*x^9 + 48*x^8 - 168*x^7 + 690*x^6 - 168*x^5 + 48*x^4 - 281*x^3 - 297*x^2 + 545*x
sage: f(w1).abs() < 1.0e-200
True
sage: f.factor()
[x, 1; x + 1, 2; x^2 + 1, 1; x^2 + x + 1, 1; 545*x^4 - 1932*x^3 + 2790*x^2 - 1932*x + 545, 1]
sage: pari.set_real_precision(n)
210
arg(x, precision=0)

arg(x): argument of x,such that -\pi < \arg(x) \leq \pi.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: C.<i> = ComplexField()
sage: pari(2+i).arg()
0.463647609000806
asin(x, precision=0)

The principal branch of \sin^{-1}(x), so that \RR e(\mathrm{asin}(x)) belongs to [-\pi/2,\pi/2]. If x is real and |x| > 1 then \mathrm{asin}(x) is complex.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(pari(0.5).sin()).asin()
0.500000000000000
sage: pari(2).asin()
1.57079632679490 - 1.31695789692482*I
asinh(x, precision=0)

The principal branch of \sinh^{-1}(x), so that \Im(\mathrm{asinh}(x)) belongs to [-\pi/2,\pi/2].

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).asinh()
1.44363547517881
sage: C.<i> = ComplexField()
sage: pari(2+i).asinh()
1.52857091948100 + 0.427078586392476*I
atan(x, precision=0)

The principal branch of \tan^{-1}(x), so that \RR e(\mathrm{atan}(x)) belongs to ]-\pi/2, \pi/2[.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).atan()
0.785398163397448
sage: C.<i> = ComplexField()
sage: pari(1.5+i).atan()
1.10714871779409 + 0.255412811882995*I
atanh(x, precision=0)

The principal branch of \tanh^{-1}(x), so that \Im(\mathrm{atanh}(x)) belongs to ]-\pi/2,\pi/2]. If x is real and |x| > 1 then \mathrm{atanh}(x) is complex.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(0).atanh()
0.E-19
sage: pari(2).atanh()
0.549306144334055 - 1.57079632679490*I
bernfrac(x)

The Bernoulli number B_x, where B_0 = 1, B_1 = -1/2, B_2 = 1/6,\ldots, expressed as a rational number. The argument x should be of type integer.

EXAMPLES:

sage: pari(18).bernfrac()
43867/798
sage: [pari(n).bernfrac() for n in range(10)]
[1, -1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0]
bernreal(x, precision=0)

The Bernoulli number B_x, as for the function bernfrac, but B_x is returned as a real number (with the current precision).

EXAMPLES:

sage: pari(18).bernreal()
54.9711779448622
sage: pari(18).bernreal(precision=192).sage()
54.9711779448621553884711779448621553884711779448621553885
bernvec(x)

Creates a vector containing, as rational numbers, the Bernoulli numbers B_0, B_2,\ldots, B_{2x}. This routine is obsolete. Use bernfrac instead each time you need a Bernoulli number in exact form.

Note: this routine is implemented using repeated independent calls to bernfrac, which is faster than the standard recursion in exact arithmetic.

EXAMPLES:

sage: pari(8).bernvec()
doctest:...: DeprecationWarning: bernvec() is deprecated, use repeated calls to bernfrac() instead
See http://trac.sagemath.org/15767 for details.
[1, 1/6, -1/30, 1/42, -1/30, 5/66, -691/2730, 7/6, -3617/510]
sage: [pari(2*n).bernfrac() for n in range(9)]
[1, 1/6, -1/30, 1/42, -1/30, 5/66, -691/2730, 7/6, -3617/510]
besselh1(nu, x, precision=0)

The H^1-Bessel function of index \nu and argument x.

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).besselh1(3)
0.486091260585891 - 0.160400393484924*I
besselh2(nu, x, precision=0)

The H^2-Bessel function of index \nu and argument x.

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).besselh2(3)
0.486091260585891 + 0.160400393484924*I
besseli(nu, x, precision=0)

Bessel I function (Bessel function of the second kind), with index \nu and argument x. If x converts to a power series, the initial factor (x/2)^{\nu}/\Gamma(\nu+1) is omitted (since it cannot be represented in PARI when \nu is not integral).

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).besseli(3)
2.24521244092995
sage: C.<i> = ComplexField()
sage: pari(2).besseli(3+i)
1.12539407613913 + 2.08313822670661*I
besselj(nu, x, precision=0)

Bessel J function (Bessel function of the first kind), with index \nu and argument x. If x converts to a power series, the initial factor (x/2)^{\nu}/\Gamma(\nu+1) is omitted (since it cannot be represented in PARI when \nu is not integral).

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).besselj(3)
0.486091260585891
besseljh(nu, x, precision=0)

J-Bessel function of half integral index (Spherical Bessel function of the first kind). More precisely, besseljh(n,x) computes J_{n+1/2}(x) where n must an integer, and x is any complex value. In the current implementation (PARI, version 2.2.11), this function is not very accurate when x is small.

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).besseljh(3)
0.412710032209716
besselk(nu, x, flag=0, precision=0)

nu.besselk(x, flag=0): K-Bessel function (modified Bessel function of the second kind) of index nu, which can be complex, and argument x.

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

INPUT:

  • nu - a complex number
  • x - real number (positive or negative)
  • flag - default: 0 or 1: use hyperu (hyperu is much slower for small x, and doesn’t work for negative x).

EXAMPLES:

sage: C.<i> = ComplexField()
sage: pari(2+i).besselk(3)
0.0455907718407551 + 0.0289192946582081*I
sage: pari(2+i).besselk(-3)
-4.34870874986752 - 5.38744882697109*I
sage: pari(2+i).besselk(300, flag=1)
3.74224603319728 E-132 + 2.49071062641525 E-134*I
besseln(nu, x, precision=0)

nu.besseln(x): Bessel N function (Spherical Bessel function of the second kind) of index nu and argument x.

If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: C.<i> = ComplexField()
sage: pari(2+i).besseln(3)
-0.280775566958244 - 0.486708533223726*I
bezout(x, y)
bezoutres(*args, **kwds)

Deprecated: Use polresultantext() instead. See trac ticket #18203 for details.

bid_get_cyc()

Returns the structure of the group (O_K/I)^*, where I is the ideal represented by self.

NOTE: self must be a “big ideal” (bid) as returned by idealstar for example.

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: J = pari(K).idealstar(K.ideal(4*i + 2))
sage: J.bid_get_cyc()
[4, 2]
bid_get_gen()

Returns a vector of generators of the group (O_K/I)^*, where I is the ideal represented by self.

NOTE: self must be a “big ideal” (bid) with generators, as returned by idealstar with flag = 2.

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: J = pari(K).idealstar(K.ideal(4*i + 2), 2)
sage: J.bid_get_gen()
[7, [-2, -1]~]

We get an exception if we do not supply flag = 2 to idealstar:

sage: J = pari(K).idealstar(K.ideal(3))
sage: J.bid_get_gen()
Traceback (most recent call last):
...
PariError: missing bid generators. Use idealstar(,,2)
binary(x)

binary(x): gives the vector formed by the binary digits of abs(x), where x is of type t_INT.

INPUT:

  • x - gen of type t_INT

OUTPUT:

  • gen - of type t_VEC

EXAMPLES:

sage: pari(0).binary()
[]
sage: pari(-5).binary()
[1, 0, 1]
sage: pari(5).binary()
[1, 0, 1]
sage: pari(2005).binary()
[1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1]
sage: pari('"2"').binary()
Traceback (most recent call last):
...
TypeError: x (="2") must be of type t_INT, but is of type t_STR.
binomial(x, k)

binomial(x, k): return the binomial coefficient “x choose k”.

INPUT:

  • x - any PARI object (gen)
  • k - integer

EXAMPLES:

sage: pari(6).binomial(2)
15
sage: pari('x+1').binomial(3)
1/6*x^3 - 1/6*x
sage: pari('2+x+O(x^2)').binomial(3)
1/3*x + O(x^2)
bitand(x, y)

bitand(x,y): Bitwise and of two integers x and y. Negative numbers behave as if modulo some large power of 2.

INPUT:

  • x - gen (of type t_INT)
  • y - coercible to gen (of type t_INT)

OUTPUT:

  • gen - of type type t_INT

EXAMPLES:

sage: pari(8).bitand(4)
0
sage: pari(8).bitand(8)
8
sage: pari(6).binary()
[1, 1, 0]
sage: pari(7).binary()
[1, 1, 1]
sage: pari(6).bitand(7)
6
sage: pari(19).bitand(-1)
19
sage: pari(-1).bitand(-1)
-1
bitneg(x, n=-1)

bitneg(x,n=-1): Bitwise negation of the integer x truncated to n bits. n=-1 (the default) represents an infinite sequence of the bit 1. Negative numbers behave as if modulo some large power of 2.

With n=-1, this function returns -n-1. With n = 0, it returns a number a such that a\cong -n-1 \pmod{2^n}.

INPUT:

  • x - gen (t_INT)
  • n - long, default = -1

OUTPUT:

  • gen - t_INT

EXAMPLES:

sage: pari(10).bitneg()
-11
sage: pari(1).bitneg()
-2
sage: pari(-2).bitneg()
1
sage: pari(-1).bitneg()
0
sage: pari(569).bitneg()
-570
sage: pari(569).bitneg(10)
454
sage: 454 % 2^10
454
sage: -570 % 2^10
454
bitnegimply(x, y)

bitnegimply(x,y): Bitwise negated imply of two integers x and y, in other words, x BITAND BITNEG(y). Negative numbers behave as if modulo big power of 2.

INPUT:

  • x - gen (of type t_INT)
  • y - coercible to gen (of type t_INT)

OUTPUT:

  • gen - of type type t_INT

EXAMPLES:

sage: pari(14).bitnegimply(0)
14
sage: pari(8).bitnegimply(8)
0
sage: pari(8+4).bitnegimply(8)
4
bitor(x, y)

bitor(x,y): Bitwise or of two integers x and y. Negative numbers behave as if modulo big power of 2.

INPUT:

  • x - gen (of type t_INT)
  • y - coercible to gen (of type t_INT)

OUTPUT:

  • gen - of type type t_INT

EXAMPLES:

sage: pari(14).bitor(0)
14
sage: pari(8).bitor(4)
12
sage: pari(12).bitor(1)
13
sage: pari(13).bitor(1)
13
bittest(x, n)

bittest(x, long n): Returns bit number n (coefficient of 2^n in binary) of the integer x. Negative numbers behave as if modulo a big power of 2.

INPUT:

  • x - gen (pari integer)

OUTPUT:

  • bool - a Python bool

EXAMPLES:

sage: x = pari(6)
sage: x.bittest(0)
False
sage: x.bittest(1)
True
sage: x.bittest(2)
True
sage: x.bittest(3)
False
sage: pari(-3).bittest(0)
True
sage: pari(-3).bittest(1)
False
sage: [pari(-3).bittest(n) for n in range(10)]
[True, False, True, True, True, True, True, True, True, True]
bitxor(x, y)

bitxor(x,y): Bitwise exclusive or of two integers x and y. Negative numbers behave as if modulo big power of 2.

INPUT:

  • x - gen (of type t_INT)
  • y - coercible to gen (of type t_INT)

OUTPUT:

  • gen - of type type t_INT

EXAMPLES:

sage: pari(6).bitxor(4)
2
sage: pari(0).bitxor(4)
4
sage: pari(6).bitxor(0)
6
bnf_get_cyc()

Returns the structure of the class group of this number field as a vector of SNF invariants.

NOTE: self must be a “big number field” (bnf).

EXAMPLES:

sage: K.<a> = QuadraticField(-65)
sage: K.pari_bnf().bnf_get_cyc()
[4, 2]
bnf_get_gen()

Returns a vector of generators of the class group of this number field.

NOTE: self must be a “big number field” (bnf).

EXAMPLES:

sage: K.<a> = QuadraticField(-65)
sage: G = K.pari_bnf().bnf_get_gen(); G
[[3, 2; 0, 1], [2, 1; 0, 1]]
sage: map(lambda J: K.ideal(J), G)
[Fractional ideal (3, a + 2), Fractional ideal (2, a + 1)]
bnf_get_no()

Returns the class number of self, a “big number field” (bnf).

EXAMPLES:

sage: K.<a> = QuadraticField(-65)
sage: K.pari_bnf().bnf_get_no()
8
bnf_get_reg()

Returns the regulator of this number field.

NOTE: self must be a “big number field” (bnf).

EXAMPLES:

sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
sage: K.pari_bnf().bnf_get_reg()
2.66089858019037...
bnfcertify()

bnf being as output by bnfinit, checks whether the result is correct, i.e. whether the calculation of the contents of self are correct without assuming the Generalized Riemann Hypothesis. If it is correct, the answer is 1. If not, the program may output some error message or loop indefinitely.

For more information about PARI and the Generalized Riemann Hypothesis, see [PariUsers], page 120.

REFERENCES:

[PariUsers]User’s Guide to PARI/GP, http://pari.math.u-bordeaux.fr/pub/pari/manuals/2.7.0/users.pdf
bnfunit()
bnrclassno(I)

Return the order of the ray class group of self modulo I.

INPUT:

  • self: a pari “BNF” object representing a number field
  • I: a pari “BID” object representing an ideal of self

OUTPUT: integer

TESTS:

sage: K.<z> = QuadraticField(-23)
sage: p = K.primes_above(3)[0]
sage: K.pari_bnf().bnrclassno(p._pari_bid_())
3
ceil(x)

For real x: return the smallest integer = x. For rational functions: the quotient of numerator by denominator. For lists: apply componentwise.

INPUT:

  • x - gen

OUTPUT:

  • gen - depends on type of x

EXAMPLES:

sage: pari(1.4).ceil()
2
sage: pari(-1.4).ceil()
-1
sage: pari(3/4).ceil()
1
sage: pari(x).ceil()
x
sage: pari((x^2+x+1)/x).ceil()
x + 1

This may be unexpected: but it is correct, treating the argument as a rational function in RR(x).

sage: pari(x^2+5*x+2.5).ceil()
x^2 + 5*x + 2.50000000000000
centerlift(x, v=-1)

centerlift(x,v): Centered lift of x. This function returns exactly the same thing as lift, except if x is an integer mod.

INPUT:

  • x - gen
  • v - var (default: x)

OUTPUT: gen

EXAMPLES:

sage: x = pari(-2).Mod(5)
sage: x.centerlift()
-2
sage: x.lift()
3
sage: f = pari('x-1').Mod('x^2 + 1')
sage: f.centerlift()
x - 1
sage: f.lift()
x - 1
sage: f = pari('x-y').Mod('x^2+1')
sage: f
Mod(x - y, x^2 + 1)
sage: f.centerlift('x')
x - y
sage: f.centerlift('y')
Mod(x - y, x^2 + 1)
change_variable_name(var)

In self, which must be a t_POL or t_SER, set the variable to var. If the variable of self is already var, then return self.

Warning

You should be careful with variable priorities when applying this on a polynomial or series of which the coefficients have polynomial components. To be safe, only use this function on polynomials with integer or rational coefficients. For a safer alternative, use subst().

EXAMPLES:

sage: f = pari('x^3 + 17*x + 3')
sage: f.change_variable_name("y")
y^3 + 17*y + 3
sage: f = pari('1 + 2*y + O(y^10)')
sage: f.change_variable_name("q")
1 + 2*q + O(q^10)
sage: f.change_variable_name("y") is f
True

In PARI, I refers to the square root of -1, so it cannot be used as variable name. Note the difference with subst():

sage: f = pari('x^2 + 1')
sage: f.change_variable_name("I")
Traceback (most recent call last):
...
PariError: I already exists with incompatible valence
sage: f.subst("x", "I")
0
component(x, n)

component(x, long n): Return n’th component of the internal representation of x. This function is 1-based instead of 0-based.

Note

For vectors or matrices, it is simpler to use x[n-1]. For list objects such as is output by nfinit, it is easier to use member functions.

INPUT:

  • x - gen
  • n - C long (coercible to)

OUTPUT: gen

EXAMPLES:

sage: pari([0,1,2,3,4]).component(1)
0
sage: pari([0,1,2,3,4]).component(2)
1
sage: pari([0,1,2,3,4]).component(4)
3
sage: pari('x^3 + 2').component(1)
2
sage: pari('x^3 + 2').component(2)
0
sage: pari('x^3 + 2').component(4)
1
sage: pari('x').component(0)
Traceback (most recent call last):
...
PariError: non-existent component: index < 1
conj(x)

conj(x): Return the algebraic conjugate of x.

INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari('x+1').conj()
x + 1
sage: pari('x+I').conj()
x - I
sage: pari('1/(2*x+3*I)').conj()
1/(2*x - 3*I)
sage: pari([1,2,'2-I','Mod(x,x^2+1)', 'Mod(x,x^2-2)']).conj()
[1, 2, 2 + I, Mod(-x, x^2 + 1), Mod(-x, x^2 - 2)]
sage: pari('Mod(x,x^2-2)').conj()
Mod(-x, x^2 - 2)
sage: pari('Mod(x,x^3-3)').conj()
Traceback (most recent call last):
...
PariError: incorrect type in gconj (t_POLMOD)
conjvec(x, precision=0)

conjvec(x): Returns the vector of all conjugates of the algebraic number x. An algebraic number is a polynomial over Q modulo an irreducible polynomial.

INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari('Mod(1+x,x^2-2)').conjvec()
[-0.414213562373095, 2.41421356237310]~
sage: pari('Mod(x,x^3-3)').conjvec()
[1.44224957030741, -0.721124785153704 - 1.24902476648341*I, -0.721124785153704 + 1.24902476648341*I]~
sage: pari('Mod(1+x,x^2-2)').conjvec(precision=192)[0].sage()
-0.414213562373095048801688724209698078569671875376948073177
content()

Greatest common divisor of all the components of self.

EXAMPLES:

sage: R.<x> = PolynomialRing(ZZ)
sage: pari(2*x^2 + 2).content()
2
sage: pari("4*x^3 - 2*x/3 + 2/5").content()
2/15
cos(x, precision=0)

The cosine function.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1.5).cos()
0.0707372016677029
sage: C.<i> = ComplexField()
sage: pari(1+i).cos()
0.833730025131149 - 0.988897705762865*I
sage: pari('x+O(x^8)').cos()
1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 + O(x^9)
cosh(x, precision=0)

The hyperbolic cosine function.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1.5).cosh()
2.35240961524325
sage: C.<i> = ComplexField()
sage: pari(1+i).cosh()
0.833730025131149 + 0.988897705762865*I
sage: pari('x+O(x^8)').cosh()
1 + 1/2*x^2 + 1/24*x^4 + 1/720*x^6 + O(x^8)
cotan(x, precision=0)

The cotangent of x.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(5).cotan()
-0.295812915532746

Computing the cotangent of \pi doesn’t raise an error, but instead just returns a very large (positive or negative) number.

sage: x = RR(pi)
sage: pari(x).cotan()         # random
-8.17674825 E15
debug(depth=-1)

Show the internal structure of self (like the \x command in gp).

EXAMPLE:

sage: pari('[1/2, 1.0*I]').debug()  # random addresses
[&=0000000004c5f010] VEC(lg=3):2200000000000003 0000000004c5eff8 0000000004c5efb0
  1st component = [&=0000000004c5eff8] FRAC(lg=3):0800000000000003 0000000004c5efe0 0000000004c5efc8
    num = [&=0000000004c5efe0] INT(lg=3):0200000000000003 (+,lgefint=3):4000000000000003 0000000000000001
    den = [&=0000000004c5efc8] INT(lg=3):0200000000000003 (+,lgefint=3):4000000000000003 0000000000000002
  2nd component = [&=0000000004c5efb0] COMPLEX(lg=3):0c00000000000003 00007fae8a2eb840 0000000004c5ef90
    real = gen_0
    imag = [&=0000000004c5ef90] REAL(lg=4):0400000000000004 (+,expo=0):6000000000000000 8000000000000000 0000000000000000
denominator(x)

denominator(x): Return the denominator of x. When x is a vector, this is the least common multiple of the denominators of the components of x.

what about poly? INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari('5/9').denominator()
9
sage: pari('(x+1)/(x-2)').denominator()
x - 2
sage: pari('2/3 + 5/8*x + 7/3*x^2 + 1/5*y').denominator()
1
sage: pari('2/3*x').denominator()
1
sage: pari('[2/3, 5/8, 7/3, 1/5]').denominator()
120
dilog(x, precision=0)

The principal branch of the dilogarithm of x, i.e. the analytic continuation of the power series \log_2(x) = \sum_{n>=1} x^n/n^2.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).dilog()
1.64493406684823
sage: C.<i> = ComplexField()
sage: pari(1+i).dilog()
0.616850275068085 + 1.46036211675312*I
disc()

e.disc(): return the discriminant of the elliptic curve e.

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: e.disc()
-161051
sage: _.factor()
[-1, 1; 11, 5]
eint1(x, n=0, precision=0)

x.eint1(n): exponential integral E1(x):

\int_{x}^{\infty} \frac{e^{-t}}{t} dt

If n is present, output the vector [eint1(x), eint1(2*x), ..., eint1(n*x)]. This is faster than repeatedly calling eint1(i*x).

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

REFERENCE:

  • See page 262, Prop 5.6.12, of Cohen’s book “A Course in Computational Algebraic Number Theory”.

EXAMPLES:

elementval(x, p)
elladd(z0, z1)

e.elladd(z0, z1): return the sum of the points z0 and z1 on this elliptic curve.

INPUT:

  • e - elliptic curve E
  • z0 - point on E
  • z1 - point on E

OUTPUT: point on E

EXAMPLES:

First we create an elliptic curve:

sage: e = pari([0, 1, 1, -2, 0]).ellinit()

Next we add two points on the elliptic curve. Notice that the Python lists are automatically converted to PARI objects so you don’t have to do that explicitly in your code.

sage: e.elladd([1,0], [-1,1])
[-3/4, -15/8]
ellak(n)

e.ellak(n): Returns the coefficient a_n of the L-function of the elliptic curve e, i.e. the n-th Fourier coefficient of the weight 2 newform associated to e (according to Shimura-Taniyama).

The curve e must be a medium or long vector of the type given by ellinit. For this function to work for every n and not just those prime to the conductor, e must be a minimal Weierstrass equation. If this is not the case, use the function ellminimalmodel first before using ellak (or you will get INCORRECT RESULTS!)

INPUT:

  • e - a PARI elliptic curve.
  • n - integer.

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: e.ellak(6)
2
sage: e.ellak(2005)
2
sage: e.ellak(-1)
0
sage: e.ellak(0)
0
ellan(n, python_ints=False)

Return the first n Fourier coefficients of the modular form attached to this elliptic curve. See ellak for more details.

INPUT:

  • n - a long integer
  • python_ints - bool (default is False); if True, return a list of Python ints instead of a PARI gen wrapper.

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: e.ellan(3)
[1, -2, -1]
sage: e.ellan(20)
[1, -2, -1, 2, 1, 2, -2, 0, -2, -2, 1, -2, 4, 4, -1, -4, -2, 4, 0, 2]
sage: e.ellan(-1)
[]
sage: v = e.ellan(10, python_ints=True); v
[1, -2, -1, 2, 1, 2, -2, 0, -2, -2]
sage: type(v)
<type 'list'>
sage: type(v[0])
<type 'int'>
ellanalyticrank(precision=0)

Returns a 2-component vector with the order of vanishing at s = 1 of the L-function of the elliptic curve and the value of the first non-zero derivative.

EXAMPLE:

sage: E = EllipticCurve('389a1')
sage: pari(E).ellanalyticrank()
[2, 1.51863300057685]
ellap(p)

e.ellap(p): Returns the prime-indexed coefficient a_p of the L-function of the elliptic curve e, i.e. the p-th Fourier coefficient of the newform attached to e.

The computation uses the Shanks–Mestre method, or the SEA algorithm.

Warning

For this function to work for every n and not just those prime to the conductor, e must be a minimal Weierstrass equation. If this is not the case, use the function ellminimalmodel first before using ellap (or you will get INCORRECT RESULTS!)

INPUT:

  • e - a PARI elliptic curve.
  • p - prime integer

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: e.ellap(2)
-2
sage: e.ellap(2003)
4
sage: e.ellak(-1)
0
ellaplist(n, python_ints=False)

e.ellaplist(n): Returns a PARI list of all the prime-indexed coefficients a_p (up to n) of the L-function of the elliptic curve e, i.e. the Fourier coefficients of the newform attached to e.

INPUT:

  • self – an elliptic curve
  • n – a long integer
  • python_ints – bool (default is False); if True, return a list of Python ints instead of a PARI gen wrapper.

Warning

The curve e must be a medium or long vector of the type given by ellinit. For this function to work for every n and not just those prime to the conductor, e must be a minimal Weierstrass equation. If this is not the case, use the function ellminimalmodel first before using ellaplist (or you will get INCORRECT RESULTS!)

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: v = e.ellaplist(10); v
[-2, -1, 1, -2]
sage: type(v)
<type 'sage.libs.pari.gen.gen'>
sage: v.type()
't_VEC'
sage: e.ellan(10)
[1, -2, -1, 2, 1, 2, -2, 0, -2, -2]
sage: v = e.ellaplist(10, python_ints=True); v
[-2, -1, 1, -2]
sage: type(v)
<type 'list'>
sage: type(v[0])
<type 'int'>

TESTS:

sage: v = e.ellaplist(1)
sage: print v, type(v)
[] <type 'sage.libs.pari.gen.gen'>
sage: v = e.ellaplist(1, python_ints=True)
sage: print v, type(v)
[] <type 'list'>
ellbil(*args, **kwds)

Deprecated: Use ellheight() instead. See trac ticket #18203 for details.

ellchangecurve(ch)

e.ellchangecurve(ch): return the new model (equation) for the elliptic curve e given by the change of coordinates ch.

The change of coordinates is specified by a vector ch=[u,r,s,t]; if x' and y' are the new coordinates, then x = u^2 x' + r and y = u^3 y' + su^2 x' + t.

INPUT:

  • e - elliptic curve
  • ch - change of coordinates vector with 4 entries

EXAMPLES:

sage: e = pari([1,2,3,4,5]).ellinit()
sage: e.ellglobalred()
[10351, [1, -1, 0, -1], 1, [11, 1; 941, 1], [[1, 5, 0, 1], [1, 5, 0, 1]]]
sage: f = e.ellchangecurve([1,-1,0,-1])
sage: f[:5]
[1, -1, 0, 4, 3]
ellchangepoint(y)

self.ellchangepoint(y): change data on point or vector of points self on an elliptic curve according to y=[u,r,s,t]

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit()
sage: x = pari([1,0])
sage: e.ellisoncurve([1,4])
False
sage: e.ellisoncurve(x)
True
sage: f = e.ellchangecurve([1,2,3,-1])
sage: f[:5]   # show only first five entries
[6, -2, -1, 17, 8]
sage: x.ellchangepoint([1,2,3,-1])
[-1, 4]
sage: f.ellisoncurve([-1,4])
True
elleisnum(k, flag=0, precision=0)

om.elleisnum(k, flag=0): om=[om1,om2] being a 2-component vector giving a basis of a lattice L and k an even positive integer, computes the numerical value of the Eisenstein series of weight k. When flag is non-zero and k=4 or 6, this gives g2 or g3 with the correct normalization.

INPUT:

  • om - gen, 2-component vector giving a basis of a lattice L
  • k - int (even positive)
  • flag - int (default 0)

OUTPUT:

  • gen - numerical value of E_k

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit()
sage: om = e.omega()
sage: om
[2.49021256085506, -1.97173770155165*I]
sage: om.elleisnum(2)
10.0672605281120
sage: om.elleisnum(4)
112.000000000000
sage: om.elleisnum(100)
2.15314248576078 E50
elleta(precision=0)

e.elleta(): return the vector [eta1,eta2] of quasi-periods associated with the period lattice e.omega() of the elliptic curve e.

EXAMPLES:

sage: e = pari([0,0,0,-82,0]).ellinit()
sage: e.elleta()
[3.60546360143265, 3.60546360143265*I]
sage: w1, w2 = e.omega()
sage: eta1, eta2 = e.elleta()
sage: w1*eta2 - w2*eta1
6.28318530717959*I
ellglobalred()

Return information related to the global minimal model of the elliptic curve e.

INPUT:

  • e – elliptic curve (returned by ellinit)

OUTPUT: A vector [N, [u,r,s,t], c, faN, L] with

  • N - the (arithmetic) conductor of e

  • [u,r,s,t] - a vector giving the coordinate change over

    Q from e to its minimal integral model (see also ellminimalmodel)

  • c - the product of the local Tamagawa numbers of e.

  • faN is the factorization of N

  • L[i] is elllocalred(E, faN[i,1])

EXAMPLES:

sage: e = pari([0, 5, 2, -1, 1]).ellinit()
sage: e.ellglobalred()
[20144, [1, -2, 0, -1], 1, [2, 4; 1259, 1], [[4, 2, 0, 1], [1, 5, 0, 1]]]
sage: e = pari(EllipticCurve('17a').a_invariants()).ellinit()
sage: e.ellglobalred()
[17, [1, 0, 0, 0], 4, Mat([17, 1]), [[1, 8, 0, 4]]]
ellheight(a, b=None, flag=-1, precision=0)

Canonical height of point a on elliptic curve self, resp. the value of the associated bilinear form at (a,b).

INPUT:

  • self– an elliptic curve over \QQ.
  • a – rational point on self.
  • b – (optional) rational point on self.
  • precision (optional) – the precision of the result, in bits.

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit()
sage: e.ellheight([1,0])
0.476711659343740
sage: e.ellheight([1,0], precision=128).sage()
0.47671165934373953737948605888465305945902294218            # 32-bit
0.476711659343739537379486058884653059459022942211150879336  # 64-bit

Computing the bilinear form:

sage: e.ellheight([1, 0], [-1, 1])
0.418188984498861
ellheightmatrix(x, precision=0)

e.ellheightmatrix(x): return the height matrix for the vector x of points on the elliptic curve e.

In other words, it returns the Gram matrix of x with respect to the height bilinear form on e (see ellbil).

INPUT:

  • e - elliptic curve over \QQ, assumed to be in a standard minimal integral model (as given by ellminimalmodel)
  • x - vector of rational points on e

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit().ellminimalmodel()[0]
sage: e.ellheightmatrix([[1,0], [-1,1]])
[0.476711659343740, 0.418188984498861; 0.418188984498861, 0.686667083305587]
ellinit(flag=-1, precision=0)

Return the PARI elliptic curve object with Weierstrass coefficients given by self, a list with 5 elements.

INPUT:

  • self – a list of 5 coefficients

  • flag – ignored (for backwards compatibility)

  • precision (optional, default: 0) - the real precision to be used in the computation of the components of the PARI (s)ell structure; if 0, use the default 64 bits.

    Note

    The parameter precision in ellinit controls not only the real precision of the resulting (s)ell structure, but in some cases also the precision of most subsequent computations with this elliptic curve (if those rely on the precomputations done by ellinit). You should therefore set the precision from the start to the value you require.

OUTPUT:

  • gen – a PARI ell structure.

EXAMPLES:

An elliptic curve with integer coefficients:

sage: e = pari([0,1,0,1,0]).ellinit(); e
[0, 1, 0, 1, 0, 4, 2, 0, -1, -32, 224, -48, 2048/3, Vecsmall([1]), [Vecsmall([64, -1])], [0, 0, 0, 0, 0, 0, 0, 0]]

The coefficients can be any ring elements that convert to PARI:

sage: pari([0,1/2,0,-3/4,0]).ellinit()
[0, 1/2, 0, -3/4, 0, 2, -3/2, 0, -9/16, 40, -116, 117/4, 256000/117, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]]
sage: pari([0,0.5,0,-0.75,0]).ellinit()
[0, 0.500000000000000, 0, -0.750000000000000, 0, 2.00000000000000, -1.50000000000000, 0, -0.562500000000000, 40.0000000000000, -116.000000000000, 29.2500000000000, 2188.03418803419, Vecsmall([0]), [Vecsmall([64, 1])], [0, 0, 0, 0]]
sage: pari([0,I,0,1,0]).ellinit()
[0, I, 0, 1, 0, 4*I, 2, 0, -1, -64, 352*I, -80, 16384/5, Vecsmall([0]), [Vecsmall([64, 0])], [0, 0, 0, 0]]
sage: pari([0,x,0,2*x,1]).ellinit()
[0, x, 0, 2*x, 1, 4*x, 4*x, 4, -4*x^2 + 4*x, 16*x^2 - 96*x, -64*x^3 + 576*x^2 - 864, 64*x^4 - 576*x^3 + 576*x^2 - 432, (256*x^6 - 4608*x^5 + 27648*x^4 - 55296*x^3)/(4*x^4 - 36*x^3 + 36*x^2 - 27), Vecsmall([0]), [Vecsmall([64, 0])], [0, 0, 0, 0]]
ellisoncurve(x)

e.ellisoncurve(x): return True if the point x is on the elliptic curve e, False otherwise.

If the point or the curve have inexact coefficients, an attempt is made to take this into account.

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit()
sage: e.ellisoncurve([1,0])
True
sage: e.ellisoncurve([1,1])
False
sage: e.ellisoncurve([1,0.00000000000000001])
False
sage: e.ellisoncurve([1,0.000000000000000001])
True
sage: e.ellisoncurve([0])
True
ellj(precision=0)

Elliptic j-invariant of self.

EXAMPLES:

sage: pari(I).ellj()
1728.00000000000
sage: pari(3*I).ellj()
153553679.396729
sage: pari('quadgen(-3)').ellj()
0.E-54
sage: pari('quadgen(-7)').ellj(precision=256).sage()
-3375.000000000000000000000000000000000000000000000000000000000000000000000000
sage: pari(-I).ellj()
Traceback (most recent call last):
...
PariError: domain error in modular function: Im(argument) <= 0
elllocalred(p)

e.elllocalred(p): computes the data of local reduction at the prime p on the elliptic curve e

For more details on local reduction and Kodaira types, see IV.8 and IV.9 in J. Silverman’s book “Advanced topics in the arithmetic of elliptic curves”.

INPUT:

  • e - elliptic curve with coefficients in \ZZ
  • p - prime number

OUTPUT:

  • gen - the exponent of p in the arithmetic conductor of e
  • gen - the Kodaira type of e at p, encoded as an integer:
  • 1 - type I_0: good reduction, nonsingular curve of genus 1
  • 2 - type II: rational curve with a cusp
  • 3 - type III: two nonsingular rational curves intersecting tangentially at one point
  • 4 - type IV: three nonsingular rational curves intersecting at one point
  • 5 - type I_1: rational curve with a node
  • 6 or larger - think of it as 4+v, then it is type I_v: v nonsingular rational curves arranged as a v-gon
  • -1 - type I_0^*: nonsingular rational curve of multiplicity two with four nonsingular rational curves of multiplicity one attached
  • -2 - type II^*: nine nonsingular rational curves in a special configuration
  • -3 - type III^*: eight nonsingular rational curves in a special configuration
  • -4 - type IV^*: seven nonsingular rational curves in a special configuration
  • -5 or smaller - think of it as -4-v, then it is type I_v^*: chain of v+1 nonsingular rational curves of multiplicity two, with two nonsingular rational curves of multiplicity one attached at either end
  • gen - a vector with 4 components, giving the coordinate changes done during the local reduction; if the first component is 1, then the equation for e was already minimal at p
  • gen - the local Tamagawa number c_p

EXAMPLES:

Type I_0:

sage: e = pari([0,0,0,0,1]).ellinit()
sage: e.elllocalred(7)
[0, 1, [1, 0, 0, 0], 1]

Type II:

sage: e = pari(EllipticCurve('27a3').a_invariants()).ellinit()
sage: e.elllocalred(3)
[3, 2, [1, -1, 0, 1], 1]

Type III:

sage: e = pari(EllipticCurve('24a4').a_invariants()).ellinit()
sage: e.elllocalred(2)
[3, 3, [1, 1, 0, 1], 2]

Type IV:

sage: e = pari(EllipticCurve('20a2').a_invariants()).ellinit()
sage: e.elllocalred(2)
[2, 4, [1, 1, 0, 1], 3]

Type I_1:

sage: e = pari(EllipticCurve('11a2').a_invariants()).ellinit()
sage: e.elllocalred(11)
[1, 5, [1, 0, 0, 0], 1]

Type I_2:

sage: e = pari(EllipticCurve('14a4').a_invariants()).ellinit()
sage: e.elllocalred(2)
[1, 6, [1, 0, 0, 0], 2]

Type I_6:

sage: e = pari(EllipticCurve('14a1').a_invariants()).ellinit()
sage: e.elllocalred(2)
[1, 10, [1, 0, 0, 0], 2]

Type I_0^*:

sage: e = pari(EllipticCurve('32a3').a_invariants()).ellinit()
sage: e.elllocalred(2)
[5, -1, [1, 1, 1, 0], 1]

Type II^*:

sage: e = pari(EllipticCurve('24a5').a_invariants()).ellinit()
sage: e.elllocalred(2)
[3, -2, [1, 2, 1, 4], 1]

Type III^*:

sage: e = pari(EllipticCurve('24a2').a_invariants()).ellinit()
sage: e.elllocalred(2)
[3, -3, [1, 2, 1, 4], 2]

Type IV^*:

sage: e = pari(EllipticCurve('20a1').a_invariants()).ellinit()
sage: e.elllocalred(2)
[2, -4, [1, 0, 1, 2], 3]

Type I_1^*:

sage: e = pari(EllipticCurve('24a1').a_invariants()).ellinit()
sage: e.elllocalred(2)
[3, -5, [1, 0, 1, 2], 4]

Type I_6^*:

sage: e = pari(EllipticCurve('90c2').a_invariants()).ellinit()
sage: e.elllocalred(3)
[2, -10, [1, 96, 1, 316], 4]
elllseries(s, A=1, precision=0)

e.elllseries(s, A=1): return the value of the L-series of the elliptic curve e at the complex number s.

This uses an O(N^{1/2}) algorithm in the conductor N of e, so it is impractical for large conductors (say greater than 10^{12}).

INPUT:

  • e - elliptic curve defined over \QQ
  • s - complex number
  • A (optional) - cutoff point for the integral, which must be chosen close to 1 for best speed.

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit()
sage: e.elllseries(2.1)
0.402838047956645
sage: e.elllseries(1, precision=128)
2.98766720445395 E-38
sage: e.elllseries(1, precision=256)
5.48956813891054 E-77
sage: e.elllseries(-2)
0
sage: e.elllseries(2.1, A=1.1)
0.402838047956645
ellminimalmodel()

ellminimalmodel(e): return the standard minimal integral model of the rational elliptic curve e and the corresponding change of variables. INPUT:

  • e - gen (that defines an elliptic curve)

OUTPUT:

  • gen - minimal model
  • gen - change of coordinates

EXAMPLES:

sage: e = pari([1,2,3,4,5]).ellinit()
sage: F, ch = e.ellminimalmodel()
sage: F[:5]
[1, -1, 0, 4, 3]
sage: ch
[1, -1, 0, -1]
sage: e.ellchangecurve(ch)[:5]
[1, -1, 0, 4, 3]
ellmul(z, n)

Return n times the point z on the elliptic curve e.

INPUT:

  • e - elliptic curve
  • z - point on e
  • n - integer, or a complex quadratic integer of complex multiplication for e. Complex multiplication currently only works if e is defined over Q.

EXAMPLES: We consider a curve with CM by Z[i]:

sage: e = pari([0,0,0,3,0]).ellinit()
sage: p = [1,2]  # Point of infinite order

Multiplication by two:

sage: e.ellmul([0,0], 2)
[0]
sage: e.ellmul(p, 2)
[1/4, -7/8]

Complex multiplication:

sage: q = e.ellmul(p, 1+I); q
[-2*I, 1 + I]
sage: e.ellmul(q, 1-I)
[1/4, -7/8]

TESTS:

sage: for D in [-7, -8, -11, -12, -16, -19, -27, -28]:  # long time (1s)
....:     hcpol = hilbert_class_polynomial(D)
....:     j = hcpol.roots(multiplicities=False)[0]
....:     t = (1728-j)/(27*j)
....:     E = EllipticCurve([4*t,16*t^2])
....:     P = E.point([0, 4*t])
....:     assert(E.j_invariant() == j)
....:     #
....:     # Compute some CM number and its minimal polynomial
....:     #
....:     cm = pari('cm = (3*quadgen(%s)+2)'%D)
....:     cm_minpoly = pari('minpoly(cm)')
....:     #
....:     # Evaluate cm_minpoly(cm)(P), which should be zero
....:     #
....:     e = pari(E)  # Convert E to PARI
....:     P2 = e.ellmul(P, cm_minpoly[2]*cm + cm_minpoly[1])
....:     P0 = e.elladd(e.ellmul(P, cm_minpoly[0]), e.ellmul(P2, cm))
....:     assert(P0 == E(0))
ellorder(x)

e.ellorder(x): return the order of the point x on the elliptic curve e (return 0 if x is not a torsion point)

INPUT:

  • e - elliptic curve defined over \QQ
  • x - point on e

EXAMPLES:

sage: e = pari(EllipticCurve('65a1').a_invariants()).ellinit()

A point of order two:

sage: e.ellorder([0,0])
2

And a point of infinite order:

sage: e.ellorder([1,0])
0
ellordinate(x, precision=0)

e.ellordinate(x): return the y-coordinates of the points on the elliptic curve e having x as x-coordinate.

INPUT:

  • e - elliptic curve
  • x - x-coordinate (can be a complex or p-adic number, or a more complicated object like a power series)

EXAMPLES:

sage: e = pari([0,1,1,-2,0]).ellinit()
sage: e.ellordinate(0)
[0, -1]
sage: e.ellordinate(I)
[0.582203589721741 - 1.38606082464177*I, -1.58220358972174 + 1.38606082464177*I]
sage: e.ellordinate(I, precision=128)[0].sage()
0.58220358972174117723338947874993600727 - 1.3860608246417697185311834209833653345*I
sage: e.ellordinate(1+3*5^1+O(5^3))
[4*5 + 5^2 + O(5^3), 4 + 3*5^2 + O(5^3)]
sage: e.ellordinate('z+2*z^2+O(z^4)')
[-2*z - 7*z^2 - 23*z^3 + O(z^4), -1 + 2*z + 7*z^2 + 23*z^3 + O(z^4)]

The field in which PARI looks for the point depends on the input field:

sage: e.ellordinate(5)
[]
sage: e.ellordinate(5.0)
[11.3427192823270, -12.3427192823270]
ellpointtoz(pt, precision=0)

e.ellpointtoz(pt): return the complex number (in the fundamental parallelogram) corresponding to the point pt on the elliptic curve e, under the complex uniformization of e given by the Weierstrass p-function.

The complex number z returned by this function lies in the parallelogram formed by the real and complex periods of e, as given by e.omega().

EXAMPLES:

sage: e = pari([0,0,0,1,0]).ellinit()
sage: e.ellpointtoz([0,0])
1.85407467730137

The point at infinity is sent to the complex number 0:

sage: e.ellpointtoz([0])
0
ellpow(*args, **kwds)

Deprecated: Use ellmul() instead. See trac ticket #18203 for details.

ellrootno(p=None)

Return the root number for the L-function of the elliptic curve E/Q at a prime p (including 0, for the infinite place); return the global root number if p is omitted.

INPUT:

  • e - elliptic curve over \QQ
  • p - a prime number or None.

OUTPUT: 1 or -1

EXAMPLES: Here is a curve of rank 3:

sage: e = pari([0,0,0,-82,0]).ellinit()
sage: e.ellrootno()
-1
sage: e.ellrootno(2)
1
sage: e.ellrootno(1009)
1
ellsigma(z, flag=0, precision=0)

e.ellsigma(z, flag=0): return the value at the complex point z of the Weierstrass \sigma function associated to the elliptic curve e.

EXAMPLES:

sage: e = pari([0,0,0,1,0]).ellinit()
sage: C.<i> = ComplexField()
sage: e.ellsigma(2+i)
1.43490215804166 + 1.80307856719256*I
ellsub(z0, z1)

e.ellsub(z0, z1): return z0-z1 on this elliptic curve.

INPUT:

  • e - elliptic curve E
  • z0 - point on E
  • z1 - point on E

OUTPUT: point on E

EXAMPLES:

sage: e = pari([0, 1, 1, -2, 0]).ellinit()
sage: e.ellsub([1,0], [-1,1])
[0, 0]
elltaniyama(n=-1)
elltors(flag=0)

e.elltors(flag = 0): return information about the torsion subgroup of the elliptic curve e

INPUT:

  • e - elliptic curve over \QQ
  • flag (optional) - specify which algorithm to use:
  • 0 (default) - use Doud’s algorithm: bound torsion by computing the cardinality of e(GF(p)) for small primes of good reduction, then look for torsion points using Weierstrass parametrization and Mazur’s classification
  • 1 - use algorithm given by the Nagell-Lutz theorem (this is much slower)

OUTPUT:

  • gen - the order of the torsion subgroup, a.k.a. the number of points of finite order
  • gen - vector giving the structure of the torsion subgroup as a product of cyclic groups, sorted in non-increasing order
  • gen - vector giving points on e generating these cyclic groups

EXAMPLES:

sage: e = pari([1,0,1,-19,26]).ellinit()
sage: e.elltors()
[12, [6, 2], [[1, 2], [3, -2]]]
ellwp(z='z', n=20, flag=0, precision=0)

Return the value or the series expansion of the Weierstrass P-function at z on the lattice self (or the lattice defined by the elliptic curve self).

INPUT:

  • self – an elliptic curve created using ellinit or a list [om1, om2] representing generators for a lattice.
  • z – (default: ‘z’) a complex number or a variable name (as string or PARI variable).
  • n – (default: 20) if ‘z’ is a variable, compute the series expansion up to at least O(z^n).
  • flag – (default = 0): If flag is 0, compute only P(z). If flag is 1, compute [P(z), P'(z)].

OUTPUT:

  • P(z) (if flag is 0) or [P(z), P'(z)] (if flag is 1).

    numbers

EXAMPLES:

We first define the elliptic curve X_0(11):

sage: E = pari([0,-1,1,-10,-20]).ellinit()

Compute P(1):

sage: E.ellwp(1)
13.9658695257485

Compute P(1+i), where i = sqrt(-1):

sage: C.<i> = ComplexField()
sage: E.ellwp(pari(1+i))
-1.11510682565555 + 2.33419052307470*I
sage: E.ellwp(1+i)
-1.11510682565555 + 2.33419052307470*I

The series expansion, to the default O(z^20) precision:

sage: E.ellwp()
z^-2 + 31/15*z^2 + 2501/756*z^4 + 961/675*z^6 + 77531/41580*z^8 + 1202285717/928746000*z^10 + 2403461/2806650*z^12 + 30211462703/43418875500*z^14 + 3539374016033/7723451736000*z^16 + 413306031683977/1289540602350000*z^18 + O(z^20)

Compute the series for wp to lower precision:

sage: E.ellwp(n=4)
z^-2 + 31/15*z^2 + O(z^4)

Next we use the version where the input is generators for a lattice:

sage: pari([1.2692, 0.63 + 1.45*i]).ellwp(1)
13.9656146936689 + 0.000644829272810...*I

With flag=1, compute the pair P(z) and P’(z):

sage: E.ellwp(1, flag=1)
[13.9658695257485, 50.5619300880073]
ellzeta(z, precision=0)

e.ellzeta(z): return the value at the complex point z of the Weierstrass \zeta function associated with the elliptic curve e.

Note

This function has infinitely many poles (one of which is at z=0); attempting to evaluate it too close to one of the poles will result in a PariError.

INPUT:

  • e - elliptic curve
  • z - complex number

EXAMPLES:

sage: e = pari([0,0,0,1,0]).ellinit()
sage: e.ellzeta(1)
1.06479841295883
sage: C.<i> = ComplexField()
sage: e.ellzeta(i-1)
-0.350122658523049 - 0.350122658523049*I
ellztopoint(z, precision=0)

e.ellztopoint(z): return the point on the elliptic curve e corresponding to the complex number z, under the usual complex uniformization of e by the Weierstrass p-function.

INPUT:

  • e - elliptic curve
  • z - complex number

OUTPUT point on e

EXAMPLES:

sage: e = pari([0,0,0,1,0]).ellinit()
sage: C.<i> = ComplexField()
sage: e.ellztopoint(1+i)
[0.E-... - 1.02152286795670*I, -0.149072813701096 - 0.149072813701096*I]

Complex numbers belonging to the period lattice of e are of course sent to the point at infinity on e:

sage: e.ellztopoint(0)
[0]
erfc(x, precision=0)

Return the complementary error function:

(2/\sqrt{\pi}) \int_{x}^{\infty} e^{-t^2} dt.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).erfc()
0.157299207050285
eta(x, flag=0, precision=0)

x.eta(flag=0): if flag=0, \eta function without the q^{1/24}; otherwise \eta of the complex number x in the upper half plane intelligently computed using \mathrm{SL}(2,\ZZ) transformations.

DETAILS: This functions computes the following. If the input x is a complex number with positive imaginary part, the result is \prod_{n=1}^{\infty} (q-1^n), where q=e^{2 i \pi x}. If x is a power series (or can be converted to a power series) with positive valuation, the result is \prod_{n=1}^{\infty} (1-x^n).

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: C.<i> = ComplexField()
sage: pari(i).eta()
0.998129069925959
eval(*args, **kwds)

Evaluate self with the given arguments.

This is currently implemented in 3 cases:

  • univariate polynomials, rational functions, power series and Laurent series (using a single unnamed argument or keyword arguments),
  • any PARI object supporting the PARI function substvec (in particular, multivariate polynomials) using keyword arguments,
  • objects of type t_CLOSURE (functions in GP bytecode form) using unnamed arguments.

In no case is mixing unnamed and keyword arguments allowed.

EXAMPLES:

sage: f = pari('x^2 + 1')
sage: f.type()
't_POL'
sage: f.eval(I)
0
sage: f.eval(x=2)
5
sage: (1/f).eval(x=1)
1/2

The notation f(x) is an alternative for f.eval(x):

sage: f(3) == f.eval(3)
True

Evaluating power series:

sage: f = pari('1 + x + x^3 + O(x^7)')
sage: f(2*pari('y')^2)
1 + 2*y^2 + 8*y^6 + O(y^14)

Substituting zero is sometimes possible, and trying to do so in illegal cases can raise various errors:

sage: pari('1 + O(x^3)').eval(0)
1
sage: pari('1/x').eval(0)
Traceback (most recent call last):
...
PariError: impossible inverse in gdiv: 0
sage: pari('1/x + O(x^2)').eval(0)
Traceback (most recent call last):
...
ZeroDivisionError: substituting 0 in Laurent series with negative valuation
sage: pari('1/x + O(x^2)').eval(pari('O(x^3)'))
Traceback (most recent call last):
...
PariError: impossible inverse in gdiv: O(x^3)
sage: pari('O(x^0)').eval(0)
Traceback (most recent call last):
...
PariError: domain error in polcoeff: t_SER = O(x^0)

Evaluating multivariate polynomials:

sage: f = pari('y^2 + x^3')
sage: f(1)    # Dangerous, depends on PARI variable ordering
y^2 + 1
sage: f(x=1)  # Safe
y^2 + 1
sage: f(y=1)
x^3 + 1
sage: f(1, 2)
Traceback (most recent call last):
...
TypeError: evaluating PARI t_POL takes exactly 1 argument (2 given)
sage: f(y='x', x='2*y')
x^2 + 8*y^3
sage: f()
x^3 + y^2

It’s not an error to substitute variables which do not appear:

sage: f.eval(z=37)
x^3 + y^2
sage: pari(42).eval(t=0)
42

We can define and evaluate closures as follows:

sage: T = pari('n -> n + 2')
sage: T.type()
't_CLOSURE'
sage: T.eval(3)
5

sage: T = pari('() -> 42')
sage: T()
42

sage: pr = pari('s -> print(s)')
sage: pr.eval('"hello world"')
hello world

sage: f = pari('myfunc(x,y) = x*y')
sage: f.eval(5, 6)
30

Default arguments work, missing arguments are treated as zero (like in GP):

sage: f = pari("(x, y, z=1.0) -> [x, y, z]")
sage: f(1, 2, 3)
[1, 2, 3]
sage: f(1, 2)
[1, 2, 1.00000000000000]
sage: f(1)
[1, 0, 1.00000000000000]
sage: f()
[0, 0, 1.00000000000000]

Variadic closures are supported as well (trac ticket #18623):

sage: f = pari("(v[..])->length(v)")
sage: f('a', f)
2
sage: g = pari("(x,y,z[..])->[x,y,z]")
sage: g(), g(1), g(1,2), g(1,2,3), g(1,2,3,4)
([0, 0, []], [1, 0, []], [1, 2, []], [1, 2, [3]], [1, 2, [3, 4]])

Using keyword arguments, we can substitute in more complicated objects, for example a number field:

sage: K.<a> = NumberField(x^2 + 1)
sage: nf = K._pari_()
sage: nf
[y^2 + 1, [0, 1], -4, 1, [Mat([1, 0.E-38 + 1.00000000000000*I]), [1, 1.00000000000000; 1, -1.00000000000000], [1, 1; 1, -1], [2, 0; 0, -2], [2, 0; 0, 2], [1, 0; 0, -1], [1, [0, -1; 1, 0]], []], [0.E-38 + 1.00000000000000*I], [1, y], [1, 0; 0, 1], [1, 0, 0, -1; 0, 1, 1, 0]]
sage: nf(y='x')
[x^2 + 1, [0, 1], -4, 1, [Mat([1, 0.E-38 + 1.00000000000000*I]), [1, 1.00000000000000; 1, -1.00000000000000], [1, 1; 1, -1], [2, 0; 0, -2], [2, 0; 0, 2], [1, 0; 0, -1], [1, [0, -1; 1, 0]], []], [0.E-38 + 1.00000000000000*I], [1, x], [1, 0; 0, 1], [1, 0, 0, -1; 0, 1, 1, 0]]
exp(precision=0)

x.exp(): exponential of x.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(0).exp()
1.00000000000000
sage: pari(1).exp()
2.71828182845905
sage: pari('x+O(x^8)').exp()
1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + 1/720*x^6 + 1/5040*x^7 + O(x^8)
factor(limit=-1, proof=1)

Return the factorization of x.

INPUT:

  • limit – (default: -1) is optional and can be set whenever x is of (possibly recursive) rational type. If limit is set return partial factorization, using primes up to limit (up to primelimit if limit=0).
  • proof – (default: True) optional. If False (not the default), returned factors larger than 2^{64} may only be pseudoprimes.

Note

In the standard PARI/GP interpreter and C-library the factor command always has proof=False, so beware!

EXAMPLES:

sage: pari('x^10-1').factor()
[x - 1, 1; x + 1, 1; x^4 - x^3 + x^2 - x + 1, 1; x^4 + x^3 + x^2 + x + 1, 1]
sage: pari(2^100-1).factor()
[3, 1; 5, 3; 11, 1; 31, 1; 41, 1; 101, 1; 251, 1; 601, 1; 1801, 1; 4051, 1; 8101, 1; 268501, 1]
sage: pari(2^100-1).factor(proof=False)
[3, 1; 5, 3; 11, 1; 31, 1; 41, 1; 101, 1; 251, 1; 601, 1; 1801, 1; 4051, 1; 8101, 1; 268501, 1]

We illustrate setting a limit:

sage: pari(next_prime(10^50)*next_prime(10^60)*next_prime(10^4)).factor(10^5)
[10007, 1; 100000000000000000000000000000000000000000000000151000000000700000000000000000000000000000000000000000000001057, 1]

PARI doesn’t have an algorithm for factoring multivariate polynomials:

sage: pari('x^3 - y^3').factor()
Traceback (most recent call last):
...
PariError: sorry, factor for general polynomials is not yet implemented
factornf(t)

Factorization of the polynomial self over the number field defined by the polynomial t. This does not require that t is integral, nor that the discriminant of the number field can be factored.

EXAMPLES:

sage: x = polygen(QQ)
sage: K.<a> = NumberField(x^2 - 1/8)
sage: pari(x^2 - 2).factornf(K.pari_polynomial("a"))
[x + Mod(-4*a, 8*a^2 - 1), 1; x + Mod(4*a, 8*a^2 - 1), 1]
factorpadic(p, r=20, flag=-1)

p-adic factorization of the polynomial pol to precision r.

EXAMPLES:

sage: x = polygen(QQ)
sage: pol = (x^2 - 1)^2
sage: pari(pol).factorpadic(5)
[(1 + O(5^20))*x + (1 + O(5^20)), 2; (1 + O(5^20))*x + (4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + 4*5^5 + 4*5^6 + 4*5^7 + 4*5^8 + 4*5^9 + 4*5^10 + 4*5^11 + 4*5^12 + 4*5^13 + 4*5^14 + 4*5^15 + 4*5^16 + 4*5^17 + 4*5^18 + 4*5^19 + O(5^20)), 2]
sage: pari(pol).factorpadic(5,3)
[(1 + O(5^3))*x + (1 + O(5^3)), 2; (1 + O(5^3))*x + (4 + 4*5 + 4*5^2 + O(5^3)), 2]
ffgen(T, v=-1)

Return the generator g=x \bmod T of the finite field defined by the polynomial T.

INPUT:

  • T – a gen of type t_POL with coefficients of type t_INTMOD:

    a polynomial over a prime finite field

  • v – string: a variable name or -1 (optional)

If v is a string, then g will be a polynomial in v, else the variable of the polynomial T is used.

EXAMPLES:

sage: x = GF(2)['x'].gen()
sage: pari(x^2+x+2).ffgen()
x
sage: pari(x^2+x+1).ffgen('a')
a
ffinit(p, n, v=-1)

Return a monic irreducible polynomial g of degree n over the finite field of p elements.

INPUT:

  • p – a gen of type t_INT: a prime number
  • n – integer: the degree of the polynomial
  • v – string: a variable name or -1 (optional)

If v \geq 0', then `g will be a polynomial in v, else the variable x is used.

EXAMPLES:

sage: pari(7).ffinit(11)
Mod(1, 7)*x^11 + Mod(1, 7)*x^10 + Mod(4, 7)*x^9 + Mod(5, 7)*x^8 + Mod(1, 7)*x^7 + Mod(1, 7)*x^2 + Mod(1, 7)*x + Mod(6, 7)
sage: pari(2003).ffinit(3)
Mod(1, 2003)*x^3 + Mod(1, 2003)*x^2 + Mod(1993, 2003)*x + Mod(1995, 2003)
fflog(g, o=None)

Return the discrete logarithm of the finite field element self in base g.

INPUT:

  • self – a PARI finite field element (FFELT) in the multiplicative group generated by g.
  • g – the base of the logarithm as a PARI finite field element (FFELT). If o is None, this must be a generator of the parent finite field.
  • o – either None (then g must a primitive root) or the order of g or a tuple (o, o.factor()).

OUTPUT:

  • An integer n such that self = g^n.

EXAMPLES:

sage: k.<a> = GF(2^12)
sage: g = pari(a).ffprimroot()
sage: (g^1234).fflog(g)
1234
sage: pari(k(1)).fflog(g)
0

This element does not generate the full multiplicative group:

sage: b = g^5
sage: ord = b.fforder(); ord
819
sage: (b^555).fflog(b, ord)
555
sage: (b^555).fflog(b, (ord, ord.factor()) )
555
fforder(o=None)

Return the multiplicative order of the finite field element self.

INPUT:

  • self – a PARI finite field element (FFELT).
  • o – either None or a multiple of the order of o or a tuple (o, o.factor()).

OUTPUT:

  • The smallest positive integer n such that self^n = 1.

EXAMPLES:

sage: k.<a> = GF(5^80)
sage: g = pari(a).ffprimroot()
sage: g.fforder()
82718061255302767487140869206996285356581211090087890624
sage: g.fforder( (5^80-1, factor(5^80-1)) )
82718061255302767487140869206996285356581211090087890624
sage: k(2)._pari_().fforder(o=4)
4
ffprimroot()

Return a primitive root of the multiplicative group of the definition field of the given finite field element.

INPUT:

  • self – a PARI finite field element (FFELT)

OUTPUT:

  • A generator of the multiplicative group of the finite field generated by self.

EXAMPLES:

sage: x = polygen(GF(3))
sage: k.<a> = GF(9, modulus=x^2+1)
sage: b = pari(a).ffprimroot()
sage: b  # random
a + 1
sage: b.fforder()
8
fibonacci(x)

Return the Fibonacci number of index x.

EXAMPLES:

sage: pari(18).fibonacci()
2584
sage: [pari(n).fibonacci() for n in range(10)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
floor(x)

For real x: return the largest integer = x. For rational functions: the quotient of numerator by denominator. For lists: apply componentwise.

INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari(5/9).floor()
0
sage: pari(11/9).floor()
1
sage: pari(1.17).floor()
1
sage: pari([1.5,2.3,4.99]).floor()
[1, 2, 4]
sage: pari([[1.1,2.2],[3.3,4.4]]).floor()
[[1, 2], [3, 4]]
sage: pari(x).floor()
x
sage: pari((x^2+x+1)/x).floor()
x + 1
sage: pari(x^2+5*x+2.5).floor()
x^2 + 5*x + 2.50000000000000
sage: pari('"hello world"').floor()
Traceback (most recent call last):
...
PariError: incorrect type in gfloor (t_STR)
frac(x)

frac(x): Return the fractional part of x, which is x - floor(x).

INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari(1.75).frac()
0.750000000000000
sage: pari(sqrt(2)).frac()
0.414213562373095
sage: pari('sqrt(-2)').frac()
Traceback (most recent call last):
...
PariError: incorrect type in gfloor (t_COMPLEX)
galoisfixedfield(perm, flag=0, v=-1)

Compute the fixed field of the Galois group self.

This wraps the galoisfixedfield function from PARI.

INPUT:

  • self – A Galois group as generated by galoisinit().
  • perm – An element of a Galois group, a vector of such elements, or a subgroup generated by galoissubgroups().
  • flag – Amount of data to include in output (see below).
  • v – Name of the second variable to use (default: 'y').

OUTPUT:

This depends on the value of flag:

  • flag = 0 – A two-element tuple consisting of the defining polynomial of the fixed field and a description of its roots modulo the primes used in the group.
  • flag = 1 – Just the polynomial.
  • flag = 2 – A third tuple element will describe the factorization of the original polynomial, using the variable indicated by v to stand for a root of the polynomial from the first tuple element.

EXAMPLES:

sage: G = pari(x^4 + 1).galoisinit()
sage: G.galoisfixedfield(G[5][1], flag=2)
[x^2 + 4, Mod(2*x^2, x^4 + 1), [x^2 - 1/2*y, x^2 + 1/2*y]]
sage: G.galoisfixedfield(G[5][5:7])
[x^4 + 1, Mod(x, x^4 + 1)]
sage: L = G.galoissubgroups()
sage: G.galoisfixedfield(L[2], flag=2, v='z')
[x^2 + 2, Mod(x^3 + x, x^4 + 1), [x^2 - z*x - 1, x^2 + z*x - 1]]
galoisinit(den=None)

Calculate the Galois group of self.

This wraps the galoisinit function from PARI.

INPUT:

  • self – A number field or a polynomial.
  • den – If set, this must be a multiple of the least common denominator of the automorphisms, expressed as polynomials in a root of the defining polynomial.

OUTPUT:

An eight-tuple, represented as a GEN object, with details about the Galois group of the number field. For details see the PARI manual. Note that the element indices in Sage and PARI are 0-based and 1-based, respectively.

EXAMPLES:

sage: P = pari(x^6 + 108)
sage: G = P.galoisinit()
sage: G[0] == P
True
sage: len(G[5]) == prod(G[7])
True
galoisisabelian(flag=0)

Decide whether self is an abelian group.

This wraps the galoisisabelian function from PARI.

INPUT:

  • self – A Galois group as generated by galoisinit(), or a subgroup thereof as returned by galoissubgroups().
  • flag – Controls the details contained in the returned result.

OUTPUT:

This returns 0 if self is not an abelian group. If it is, then the output depends on flag:

  • flag = 0 – The HNF matrix of self over its generators is returned.
  • flag = 1 – The return value is simply 1.

EXAMPLES:

sage: G = pari(x^6 + 108).galoisinit()
sage: G.galoisisabelian()
0
sage: H = G.galoissubgroups()[2]
sage: H.galoisisabelian()
Mat(2)
sage: H.galoisisabelian(flag=1)
1
galoisisnormal(subgrp)

Decide whether subgrp is a normal subgroup of self.

This wraps the galoisisnormal function from PARI.

INPUT:

OUTPUT:

One if subgrp is a subgroup of self, zero otherwise.

EXAMPLES:

sage: G = pari(x^6 + 108).galoisinit()
sage: L = G.galoissubgroups()
sage: G.galoisisnormal(L[0])
1
sage: G.galoisisnormal(L[2])
0
galoispermtopol(perm)

Return the polynomial defining the Galois automorphism perm.

This wraps the galoispermtopol function from PARI.

INPUT:

  • self – A Galois group as generated by galoisinit().
  • perm – A permutation from that group, or a vector or matrix of such permutations.

OUTPUT:

The defining polynomial of the specified automorphism.

EXAMPLES:

sage: G = pari(x^6 + 108).galoisinit()
sage: G.galoispermtopol(G[5])
[x, 1/12*x^4 - 1/2*x, -1/12*x^4 - 1/2*x, 1/12*x^4 + 1/2*x, -1/12*x^4 + 1/2*x, -x]
sage: G.galoispermtopol(G[5][1])
1/12*x^4 - 1/2*x
sage: G.galoispermtopol(G[5][1:4])
[1/12*x^4 - 1/2*x, -1/12*x^4 - 1/2*x, 1/12*x^4 + 1/2*x]
galoissubfields(flag=0, v=-1)

List all subfields of the Galois group self.

This wraps the galoissubfields function from PARI.

This method is essentially the same as applying galoisfixedfield() to each group returned by galoissubgroups().

INPUT:

OUTPUT:

A vector of all subfields of this group. Each entry is as described in the galoisfixedfield() method.

EXAMPLES:

sage: G = pari(x^6 + 108).galoisinit()
sage: G.galoissubfields(flag=1)
[x, x^2 + 972, x^3 + 54, x^3 + 864, x^3 - 54, x^6 + 108]
sage: G = pari(x^4 + 1).galoisinit()
sage: G.galoissubfields(flag=2, v='z')[2]
[x^2 + 2, Mod(x^3 + x, x^4 + 1), [x^2 - z*x - 1, x^2 + z*x - 1]]
galoissubgroups()

List all subgroups of the Galois group self.

This wraps the galoissubgroups function from PARI.

INPUT:

OUTPUT:

A vector of all subgroups of this group. Each subgroup is described as a two-tuple, with the subgroup generators as first element and the orders of these generators as second element.

EXAMPLES:

sage: G = pari(x^6 + 108).galoisinit()
sage: L = G.galoissubgroups()
sage: list(L[0][1])
[3, 2]
gamma(s, precision=0)

s.gamma(precision): Gamma function at s.

If s is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If s is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).gamma()
1.00000000000000
sage: pari(5).gamma()
24.0000000000000
sage: C.<i> = ComplexField()
sage: pari(1+i).gamma()
0.498015668118356 - 0.154949828301811*I

TESTS:

sage: pari(-1).gamma()
Traceback (most recent call last):
...
PariError: domain error in gamma: argument = non-positive integer
gammah(s, precision=0)

s.gammah(): Gamma function evaluated at the argument x+1/2.

If s is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If s is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).gammah()
1.32934038817914
sage: pari(5).gammah()
52.3427777845535
sage: C.<i> = ComplexField()
sage: pari(1+i).gammah()
0.575315188063452 + 0.0882106775440939*I
gcd(x, y=None)

Return the greatest common divisor of x and y.

If y is None, then x must be a list or tuple, and the greatest common divisor of its components is returned.

EXAMPLES:

sage: pari(10).gcd(15)
5
sage: pari([5, 'y']).gcd()
1
sage: pari(['x', x^2]).gcd()
x
gequal(a, b)

Check whether a and b are equal using PARI’s gequal.

EXAMPLES:

sage: a = pari(1); b = pari(1.0); c = pari('"some_string"')
sage: a.gequal(a)
True
sage: b.gequal(b)
True
sage: c.gequal(c)
True
sage: a.gequal(b)
True
sage: a.gequal(c)
False

WARNING: this relation is not transitive:

sage: a = pari('[0]'); b = pari(0); c = pari('[0,0]')
sage: a.gequal(b)
True
sage: b.gequal(c)
True
sage: a.gequal(c)
False
gequal0(a)

Check whether a is equal to zero.

EXAMPLES:

sage: pari(0).gequal0()
True
sage: pari(1).gequal0()
False
sage: pari(1e-100).gequal0()
False
sage: pari("0.0 + 0.0*I").gequal0()
True
sage: pari(GF(3^20,'t')(0)).gequal0()
True
gequal_long(a, b)

Check whether a is equal to the long int b using PARI’s gequalsg.

EXAMPLES:

sage: a = pari(1); b = pari(2.0); c = pari('3*matid(3)')
sage: a.gequal_long(1)
True
sage: a.gequal_long(-1)
False
sage: a.gequal_long(0)
False
sage: b.gequal_long(2)
True
sage: b.gequal_long(-2)
False
sage: c.gequal_long(3)
True
sage: c.gequal_long(-3)
False
getattr(attr)

Return the PARI attribute with the given name.

EXAMPLES:

sage: K = pari("nfinit(x^2 - x - 1)")
sage: K.getattr("pol")
x^2 - x - 1
sage: K.getattr("disc")
5

sage: K.getattr("reg")
Traceback (most recent call last):
...
PariError: _.reg: incorrect type in reg (t_VEC)
sage: K.getattr("zzz")
Traceback (most recent call last):
...
PariError: not a function in function call
hyperu(a, b, x, precision=0)

a.hyperu(b,x): U-confluent hypergeometric function.

If a, b, or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).hyperu(2,3)
0.333333333333333
idealchinese(x, y)

Chinese Remainder Theorem over number fields.

INPUT:

  • x – prime ideal factorization
  • y – vector of elements

OUTPUT:

An element b in the ambient number field self such that v_p(b-y_p) \ge v_p(x) for all prime ideals p dividing x, and v_p(b) \ge 0 for all other p.

EXAMPLES:

sage: F = QuadraticField(5, 'alpha')
sage: nf = F._pari_()
sage: P = F.ideal(F.gen())
sage: Q = F.ideal(2)
sage: moduli = pari.matrix(2,2,[P.pari_prime(),4,Q.pari_prime(),4])
sage: residues = pari.vector(2,[0,1])
sage: b = F(nf.idealchinese(moduli,residues))
sage: b.valuation(P) >= 4
True
sage: (b-1).valuation(Q) >= 2
True
idealcoprime(x, y)

Given two integral ideals x and y of a pari number field self, return an element a of the field (expressed in the integral basis of self) such that a*x is an integral ideal coprime to y.

EXAMPLES:

sage: F = NumberField(x^3-2, 'alpha')
sage: nf = F._pari_()
sage: x = pari('[1, -1, 2]~')
sage: y = pari('[1, -1, 3]~')
sage: nf.idealcoprime(x, y)
[1, 0, 0]~

sage: y = pari('[2, -2, 4]~')
sage: nf.idealcoprime(x, y)
[5/43, 9/43, -1/43]~
idealintersection(x, y)
ideallist(bound, flag=4)

Vector of vectors L of all idealstar of all ideals of norm <= bound.

The binary digits of flag mean:

  • 1: give generators;
  • 2: add units;
  • 4: (default) give only the ideals and not the bid.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^2 + 1)
sage: L = K.pari_nf().ideallist(100)

Now we have our list L. Entry L[n-1] contains all ideals of norm n:

sage: L[0]   # One ideal of norm 1.
[[1, 0; 0, 1]]
sage: L[64]  # 4 ideals of norm 65.
[[65, 8; 0, 1], [65, 47; 0, 1], [65, 18; 0, 1], [65, 57; 0, 1]]
ideallog(x, bid)

Return the discrete logarithm of the unit x in (ring of integers)/bid.

INPUT:

  • self - a pari number field
  • bid - a big ideal structure (corresponding to an ideal I of self) output by idealstar
  • x - an element of self with valuation zero at all primes dividing I

OUTPUT:

  • the discrete logarithm of x on the generators given in bid[2]

EXAMPLE:

sage: F = NumberField(x^3-2, 'alpha')
sage: nf = F._pari_()
sage: I = pari('[1, -1, 2]~')
sage: bid = nf.idealstar(I)
sage: x = pari('5')
sage: nf.ideallog(x, bid)
[25]~
idealprimedec(nf, p)

Prime ideal decomposition of the prime number p in the number field nf as a vector of 5 component vectors [p,a,e,f,b] representing the prime ideals p O_K + a O_K, e ,`f` as usual, a as vector of components on the integral basis, b Lenstra’s constant.

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: F = pari(K).idealprimedec(5); F
[[5, [-2, 1]~, 1, 1, [2, -1; 1, 2]], [5, [2, 1]~, 1, 1, [-2, -1; 1, -2]]]
sage: F[0].pr_get_p()
5
idealstar(I, flag=1)

Return the big ideal (bid) structure of modulus I.

INPUT:

  • self - a pari number field
  • I – an ideal of self, or a row vector whose first component is an ideal and whose second component is a row vector of r_1 0 or 1.
  • flag - determines the amount of computation and the shape of the output:
    • 1 (default): return a bid structure without generators
    • 2: return a bid structure with generators (slower)
    • 0 (deprecated): only outputs units of (ring of integers/I) as an abelian group, i.e as a 3-component vector [h,d,g]: h is the order, d is the vector of SNF cyclic components and g the corresponding generators. This flag is deprecated: it is in fact slightly faster to compute a true bid structure, which contains much more information.

EXAMPLE:

sage: F = NumberField(x^3-2, 'alpha')
sage: nf = F._pari_()
sage: I = pari('[1, -1, 2]~')
sage: nf.idealstar(I)
[[[43, 9, 5; 0, 1, 0; 0, 0, 1], [0]], [42, [42]], Mat([[43, [9, 1, 0]~, 1, 1, [-5, 2, -18; -9, -5, 2; 1, -9, -5]], 1]), [[[[42], [3], [3], [Vecsmall([])], 1]], [[], [], []]], Mat(1)]
idealval(x, p)
imag(x)

imag(x): Return the imaginary part of x. This function also works component-wise.

INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari('1+2*I').imag()
2
sage: pari(sqrt(-2)).imag()
1.41421356237310
sage: pari('x+I').imag()
1
sage: pari('x+2*I').imag()
2
sage: pari('(1+I)*x^2+2*I').imag()
x^2 + 2
sage: pari('[1,2,3] + [4*I,5,6]').imag()
[4, 0, 0]
incgam(s, x, y=None, precision=0)

s.incgam(x, y, precision): incomplete gamma function. y is optional and is the precomputed value of gamma(s).

If s is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If s is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: C.<i> = ComplexField()
sage: pari(1+i).incgam(3-i)
-0.0458297859919946 + 0.0433696818726677*I
incgamc(s, x, precision=0)

s.incgamc(x): complementary incomplete gamma function.

The arguments x and s are complex numbers such that s is not a pole of \Gamma and |x|/(|s|+1) is not much larger than 1 (otherwise, the convergence is very slow). The function returns the value of the integral \int_{0}^{x} e^{-t} t^{s-1} dt.

If s or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).incgamc(2)
0.864664716763387
ispower(k=None)

Determine whether or not self is a perfect k-th power. If k is not specified, find the largest k so that self is a k-th power.

INPUT:

  • k - int (optional)

OUTPUT:

  • power - int, what power it is
  • g - what it is a power of

EXAMPLES:

sage: pari(9).ispower()
(2, 3)
sage: pari(17).ispower()
(1, 17)
sage: pari(17).ispower(2)
(False, None)
sage: pari(17).ispower(1)
(1, 17)
sage: pari(2).ispower()
(1, 2)
isprime(flag=0)

isprime(x, flag=0): Returns True if x is a PROVEN prime number, and False otherwise.

INPUT:

  • flag - int 0 (default): use a combination of algorithms. 1: certify primality using the Pocklington-Lehmer Test. 2: certify primality using the APRCL test.

OUTPUT:

  • bool - True or False

EXAMPLES:

sage: pari(9).isprime()
False
sage: pari(17).isprime()
True
sage: n = pari(561)    # smallest Carmichael number
sage: n.isprime()      # not just a pseudo-primality test!
False
sage: n.isprime(1)
False
sage: n.isprime(2)
False
sage: n = pari(2^31-1)
sage: n.isprime(1)
(True, [2, 3, 1; 3, 5, 1; 7, 3, 1; 11, 3, 1; 31, 2, 1; 151, 3, 1; 331, 3, 1])
isprimepower()

Check whether self is a prime power (with an exponent >= 1).

INPUT:

  • self - A PARI integer

OUTPUT:

A tuple (k, p) where k is a Python integer and p a PARI integer.

  • If the input was a prime power, p is the prime and k the power.
  • Otherwise, k = 0 and p is self.

See also

If you don’t need a proof that p is prime, you can use ispseudoprimepower() instead.

EXAMPLES:

sage: pari(9).isprimepower()
(2, 3)
sage: pari(17).isprimepower()
(1, 17)
sage: pari(18).isprimepower()
(0, 18)
sage: pari(3^12345).isprimepower()
(12345, 3)
ispseudoprime(flag=0)

ispseudoprime(x, flag=0): Returns True if x is a pseudo-prime number, and False otherwise.

INPUT:

  • flag - int 0 (default): checks whether x is a Baillie-Pomerance-Selfridge-Wagstaff pseudo prime (strong Rabin-Miller pseudo prime for base 2, followed by strong Lucas test for the sequence (P,-1), P smallest positive integer such that P^2 - 4 is not a square mod x). 0: checks whether x is a strong Miller-Rabin pseudo prime for flag randomly chosen bases (with end-matching to catch square roots of -1).

OUTPUT:

  • bool - True or False, or when flag=1, either False or a tuple (True, cert) where cert is a primality certificate.

EXAMPLES:

sage: pari(9).ispseudoprime()
False
sage: pari(17).ispseudoprime()
True
sage: n = pari(561)     # smallest Carmichael number
sage: n.ispseudoprime(2)
False
ispseudoprimepower()

Check whether self is the power (with an exponent >= 1) of a pseudo-prime.

INPUT:

  • self - A PARI integer

OUTPUT:

A tuple (k, p) where k is a Python integer and p a PARI integer.

  • If the input was a pseudoprime power, p is the pseudoprime and k the power.
  • Otherwise, k = 0 and p is self.

EXAMPLES:

sage: pari(3^12345).ispseudoprimepower()
(12345, 3)
sage: p = pari(2^1500 + 1465)         # next_prime(2^1500)
sage: (p^11).ispseudoprimepower()[0]  # very fast
11
issquare(x, find_root=False)

issquare(x,n): True if x is a square, False if not. If find_root is given, also returns the exact square root.

issquarefree()

EXAMPLES:

sage: pari(10).issquarefree()
True
sage: pari(20).issquarefree()
False
j()

e.j(): return the j-invariant of the elliptic curve e.

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: e.j()
-122023936/161051
sage: _.factor()
[-1, 1; 2, 12; 11, -5; 31, 3]
lcm(x, y=None)

Return the least common multiple of x and y.

If y is None, then x must be a list or tuple, and the least common multiple of its components is returned.

EXAMPLES:

sage: pari(10).lcm(15)
30
sage: pari([5, 'y']).lcm()
5*y
sage: pari([10, 'x', x^2]).lcm()
10*x^2
lift(x, v=-1)

lift(x,v): Returns the lift of an element of Z/nZ to Z or R[x]/(P) to R[x] for a type R if v is omitted. If v is given, lift only polymods with main variable v. If v does not occur in x, lift only intmods.

INPUT:

  • x - gen
  • v - (optional) variable

OUTPUT: gen

EXAMPLES:

sage: x = pari("x")
sage: a = x.Mod('x^3 + 17*x + 3')
sage: a
Mod(x, x^3 + 17*x + 3)
sage: b = a^4; b
Mod(-17*x^2 - 3*x, x^3 + 17*x + 3)
sage: b.lift()
-17*x^2 - 3*x

??? more examples

list()

Convert self to a list of PARI gens.

EXAMPLES:

A PARI vector becomes a Sage list:

sage: L = pari("vector(10,i,i^2)").list()
sage: L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
sage: type(L)
<type 'list'>
sage: type(L[0])
<type 'sage.libs.pari.gen.gen'>

For polynomials, list() behaves as for ordinary Sage polynomials:

sage: pol = pari("x^3 + 5/3*x"); pol.list()
[0, 5/3, 0, 1]

For power series or Laurent series, we get all coefficients starting from the lowest degree term. This includes trailing zeros:

sage: R.<x> = LaurentSeriesRing(QQ)
sage: s = x^2 + O(x^8)
sage: s.list()
[1]
sage: pari(s).list()
[1, 0, 0, 0, 0, 0]
sage: s = x^-2 + O(x^0)
sage: s.list()
[1]
sage: pari(s).list()
[1, 0]

For matrices, we get a list of columns:

sage: M = matrix(ZZ,3,2,[1,4,2,5,3,6]); M
[1 4]
[2 5]
[3 6]
sage: pari(M).list()
[[1, 2, 3]~, [4, 5, 6]~]

For “scalar” types, we get a 1-element list containing self:

sage: pari("42").list()
[42]
list_str()

Return str that might correctly evaluate to a Python-list.

listinsert(obj, n)
listput(obj, n)
lllgram()
lllgramint()
lngamma(x, precision=0)

Alias for log_gamma().

EXAMPLES:

sage: pari(100).lngamma()
359.134205369575
log(x, precision=0)

x.log(): natural logarithm of x.

This function returns the principal branch of the natural logarithm of x, i.e., the branch such that \Im(\log(x)) \in ]-\pi, \pi]. The result is complex (with imaginary part equal to \pi) if x\in \RR and x<0. In general, the algorithm uses the formula

\log(x) \simeq \frac{\pi}{2{\rm agm}(1,4/s)} - m\log(2),

if s=x 2^m is large enough. (The result is exact to B bits provided that s>2^{B/2}.) At low accuracies, this function computes \log using the series expansion near 1.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

Note that p-adic arguments can also be given as input, with the convention that \log(p)=0. Hence, in particular, \exp(\log(x))/x is not in general equal to 1 but instead to a (p-1)-st root of unity (or \pm 1 if p=2) times a power of p.

EXAMPLES:

sage: pari(5).log()
1.60943791243410
sage: C.<i> = ComplexField()
sage: pari(i).log()
0.E-19 + 1.57079632679490*I
log_gamma(x, precision=0)

Logarithm of the gamma function of x.

This function returns the principal branch of the logarithm of the gamma function of x. The function \log(\Gamma(x)) is analytic on the complex plane with non-positive integers removed. This function can have much larger inputs than \Gamma itself.

The p-adic analogue of this function is unfortunately not implemented.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(100).log_gamma()
359.134205369575
matadjoint()

matadjoint(x): adjoint matrix of x.

EXAMPLES:

sage: pari('[1,2,3; 4,5,6;  7,8,9]').matadjoint()
[-3, 6, -3; 6, -12, 6; -3, 6, -3]
sage: pari('[a,b,c; d,e,f; g,h,i]').matadjoint()
[(i*e - h*f), (-i*b + h*c), (f*b - e*c); (-i*d + g*f), i*a - g*c, -f*a + d*c; (h*d - g*e), -h*a + g*b, e*a - d*b]
matdet(flag=0)

Return the determinant of this matrix.

INPUT:

  • flag - (optional) flag 0: using Gauss-Bareiss. 1: use classical Gaussian elimination (slightly better for integer entries)

EXAMPLES:

sage: pari('[1,2; 3,4]').matdet(0)
-2
sage: pari('[1,2; 3,4]').matdet(1)
-2
matfrobenius(flag=0)

M.matfrobenius(flag=0): Return the Frobenius form of the square matrix M. If flag is 1, return only the elementary divisors (a list of polynomials). If flag is 2, return a two-components vector [F,B] where F is the Frobenius form and B is the basis change so that M=B^{-1} F B.

EXAMPLES:

sage: a = pari('[1,2;3,4]')
sage: a.matfrobenius()
[0, 2; 1, 5]
sage: a.matfrobenius(flag=1)
[x^2 - 5*x - 2]
sage: a.matfrobenius(2)
[[0, 2; 1, 5], [1, -1/3; 0, 1/3]]
sage: v = a.matfrobenius(2)
sage: v[0]
[0, 2; 1, 5]
sage: v[1]^(-1)*v[0]*v[1]
[1, 2; 3, 4]

We let t be the matrix of T_2 acting on modular symbols of level 43, which was computed using ModularSymbols(43,sign=1).T(2).matrix():

sage: t = pari('[3, -2, 0, 0; 0, -2, 0, 1; 0, -1, -2, 2; 0, -2, 0, 2]')
sage: t.matfrobenius()
[0, 0, 0, -12; 1, 0, 0, -2; 0, 1, 0, 8; 0, 0, 1, 1]
sage: t.charpoly('x')
x^4 - x^3 - 8*x^2 + 2*x + 12
sage: t.matfrobenius(1)
[x^4 - x^3 - 8*x^2 + 2*x + 12]

AUTHORS:

  • Martin Albrect (2006-04-02)
mathnf(flag=0)

A.mathnf(flag=0): (upper triangular) Hermite normal form of A, basis for the lattice formed by the columns of A.

INPUT:

  • flag - optional, value range from 0 to 4 (0 if omitted), meaning : 0: naive algorithm
  • 1: Use Batut's algorithm - output 2-component vector [H,U] such that H is the HNF of A, and U is a unimodular matrix such that xU=H. 3: Use Batut’s algorithm. Output [H,U,P] where P is a permutation matrix such that P A U = H. 4: As 1, using a heuristic variant of LLL reduction along the way.

EXAMPLES:

sage: pari('[1,2,3; 4,5,6;  7,8,9]').mathnf()
[6, 1; 3, 1; 0, 1]
mathnfmod(d)

Returns the Hermite normal form if d is a multiple of the determinant

Beware that PARI’s concept of a Hermite normal form is an upper triangular matrix with the same column space as the input matrix.

INPUT:

  • d - multiple of the determinant of self

EXAMPLES:

       sage: M=matrix([[1,2,3],[4,5,6],[7,8,11]])
sage: d=M.det()
sage: pari(M).mathnfmod(d)
       [6, 4, 3; 0, 1, 0; 0, 0, 1]

Note that d really needs to be a multiple of the discriminant, not just of the exponent of the cokernel:

       sage: M=matrix([[1,0,0],[0,2,0],[0,0,6]])
sage: pari(M).mathnfmod(6)
[1, 0, 0; 0, 1, 0; 0, 0, 6]
sage: pari(M).mathnfmod(12)
[1, 0, 0; 0, 2, 0; 0, 0, 6]
mathnfmodid(d)

Returns the Hermite Normal Form of M concatenated with d*Identity

Beware that PARI’s concept of a Hermite normal form is a maximal rank upper triangular matrix with the same column space as the input matrix.

INPUT:

  • d - Determines

EXAMPLES:

       sage: M=matrix([[1,0,0],[0,2,0],[0,0,6]])
sage: pari(M).mathnfmodid(6)
       [1, 0, 0; 0, 2, 0; 0, 0, 6]

This routine is not completely equivalent to mathnfmod:

sage: pari(M).mathnfmod(6)
[1, 0, 0; 0, 1, 0; 0, 0, 6]
matker(flag=0)

Return a basis of the kernel of this matrix.

INPUT:

  • flag - optional; may be set to 0: default; non-zero: x is known to have integral entries.

EXAMPLES:

sage: pari('[1,2,3;4,5,6;7,8,9]').matker()
[1; -2; 1]

With algorithm 1, even if the matrix has integer entries the kernel need not be saturated (which is weird):

sage: pari('[1,2,3;4,5,6;7,8,9]').matker(1)
[3; -6; 3]
sage: pari('matrix(3,3,i,j,i)').matker()
[-1, -1; 1, 0; 0, 1]
sage: pari('[1,2,3;4,5,6;7,8,9]*Mod(1,2)').matker()
[Mod(1, 2); Mod(0, 2); Mod(1, 2)]
matkerint(flag=0)

Return the integer kernel of a matrix.

This is the LLL-reduced Z-basis of the kernel of the matrix x with integral entries.

EXAMPLES:

sage: pari('[2,1;2,1]').matker()
[-1/2; 1]
sage: pari('[2,1;2,1]').matkerint()
[1; -2]
sage: pari('[2,1;2,1]').matkerint(1)
doctest:...: DeprecationWarning: The flag argument to matkerint() is deprecated by PARI
See http://trac.sagemath.org/18203 for details.
[1; -2]
matsnf(flag=0)

x.matsnf(flag=0): Smith normal form (i.e. elementary divisors) of the matrix x, expressed as a vector d. Binary digits of flag mean 1: returns [u,v,d] where d=u*x*v, otherwise only the diagonal d is returned, 2: allow polynomial entries, otherwise assume x is integral, 4: removes all information corresponding to entries equal to 1 in d.

EXAMPLES:

sage: pari('[1,2,3; 4,5,6;  7,8,9]').matsnf()
[0, 3, 1]
matsolve(B)

matsolve(B): Solve the linear system Mx=B for an invertible matrix M

matsolve(B) uses Gaussian elimination to solve Mx=B, where M is invertible and B is a column vector.

The corresponding pari library routine is gauss. The gp-interface name matsolve has been given preference here.

INPUT:

  • B - a column vector of the same dimension as the square matrix self

EXAMPLES:

sage: pari('[1,1;1,-1]').matsolve(pari('[1;0]'))
[1/2; 1/2]
matsolvemod(D, B, flag=0)

For column vectors D=(d_i) and B=(b_i), find a small integer solution to the system of linear congruences

R_ix=b_i\text{ (mod }d_i),

where R_i is the ith row of self. If d_i=0, the equation is considered over the integers. The entries of self, D, and B should all be integers (those of D should also be non-negative).

If flag is 1, the output is a two-component row vector whose first component is a solution and whose second component is a matrix whose columns form a basis of the solution set of the homogeneous system.

For either value of flag, the output is 0 if there is no solution.

Note that if D or B is an integer, then it will be considered as a vector all of whose entries are that integer.

EXAMPLES:

sage: D = pari('[3,4]~')
sage: B = pari('[1,2]~')
sage: M = pari('[1,2;3,4]')
sage: M.matsolvemod(D, B)
[-2, 0]~
sage: M.matsolvemod(3, 1)
[-1, 1]~
sage: M.matsolvemod(pari('[3,0]~'), pari('[1,2]~'))
[6, -4]~
sage: M2 = pari('[1,10;9,18]')
sage: M2.matsolvemod(3, pari('[2,3]~'), 1)
[[0, -1]~, [-1, -2; 1, -1]]
sage: M2.matsolvemod(9, pari('[2,3]~'))
0
sage: M2.matsolvemod(9, pari('[2,45]~'), 1)
[[1, 1]~, [-1, -4; 1, -5]]
mattranspose()

Transpose of the matrix self.

EXAMPLES:

sage: pari('[1,2,3; 4,5,6; 7,8,9]').mattranspose()
[1, 4, 7; 2, 5, 8; 3, 6, 9]
mod()

Given an INTMOD or POLMOD Mod(a,m), return the modulus m.

EXAMPLES:

sage: pari(4).Mod(5).mod()
5
sage: pari("Mod(x, x*y)").mod()
y*x
sage: pari("[Mod(4,5)]").mod()
Traceback (most recent call last):
...
TypeError: Not an INTMOD or POLMOD in mod()
ncols()

Return the number of columns of self.

EXAMPLES:

sage: pari('matrix(19,8)').ncols()
8
newtonpoly(p)

x.newtonpoly(p): Newton polygon of polynomial x with respect to the prime p.

EXAMPLES:

sage: x = pari('y^8+6*y^6-27*y^5+1/9*y^2-y+1')
sage: x.newtonpoly(3)
[1, 1, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
nextprime(add_one=0)

nextprime(x): smallest pseudoprime greater than or equal to x. If add_one is non-zero, return the smallest pseudoprime strictly greater than x.

EXAMPLES:

sage: pari(1).nextprime()
2
sage: pari(2).nextprime()
2
sage: pari(2).nextprime(add_one = 1)
3
sage: pari(2^100).nextprime()
1267650600228229401496703205653
nf_get_diff()

Returns the different of this number field as a PARI ideal.

INPUT:

  • self – A PARI number field being the output of nfinit(),

    bnfinit() or bnrinit().

EXAMPLES:

sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
sage: pari(K).nf_get_diff()
[12, 0, 0, 0; 0, 12, 8, 0; 0, 0, 4, 0; 0, 0, 0, 4]
nf_get_pol()

Returns the defining polynomial of this number field.

INPUT:

  • self – A PARI number field being the output of nfinit(),

    bnfinit() or bnrinit().

EXAMPLES:

sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
sage: pari(K).nf_get_pol()
y^4 - 4*y^2 + 1
sage: bnr = pari("K = bnfinit(x^4 - 4*x^2 + 1); bnrinit(K, 2*x)")
sage: bnr.nf_get_pol()
x^4 - 4*x^2 + 1

For relative number fields, this returns the relative polynomial. However, beware that pari(L) returns an absolute number field:

sage: L.<b> = K.extension(x^2 - 5)
sage: pari(L).nf_get_pol()        # Absolute
y^8 - 28*y^6 + 208*y^4 - 408*y^2 + 36
sage: L.pari_rnf().nf_get_pol()   # Relative
x^2 - 5

TESTS:

sage: x = polygen(QQ)
sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
sage: K.pari_nf().nf_get_pol()
y^4 - 4*y^2 + 1
sage: K.pari_bnf().nf_get_pol()
y^4 - 4*y^2 + 1

An error is raised for invalid input:

sage: pari("[0]").nf_get_pol()
Traceback (most recent call last):
...
PariError: incorrect type in pol (t_VEC)
nf_get_sign()

Returns a Python list [r1, r2], where r1 and r2 are Python ints representing the number of real embeddings and pairs of complex embeddings of this number field, respectively.

INPUT:

  • self – A PARI number field being the output of nfinit(),

    bnfinit() or bnrinit().

EXAMPLES:

sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
sage: s = K.pari_nf().nf_get_sign(); s
[4, 0]
sage: type(s); type(s[0])
<type 'list'>
<type 'int'>
sage: CyclotomicField(15).pari_nf().nf_get_sign()
[0, 4]
nf_get_zk()

Returns a vector with a \ZZ-basis for the ring of integers of this number field. The first element is always 1.

INPUT:

  • self – A PARI number field being the output of nfinit(),

    bnfinit() or bnrinit().

EXAMPLES:

sage: K.<a> = NumberField(x^4 - 4*x^2 + 1)
sage: pari(K).nf_get_zk()
[1, y, y^3 - 4*y, y^2 - 2]
nf_subst(z)

Given a PARI number field self, return the same PARI number field but in the variable z.

INPUT:

  • self – A PARI number field being the output of nfinit(),

    bnfinit() or bnrinit().

EXAMPLES:

sage: x = polygen(QQ)
sage: K = NumberField(x^2 + 5, 'a')

We can substitute in a PARI nf structure:

sage: Kpari = K.pari_nf()
sage: Kpari.nf_get_pol()
y^2 + 5
sage: Lpari = Kpari.nf_subst('a')
sage: Lpari.nf_get_pol()
a^2 + 5

We can also substitute in a PARI bnf structure:

sage: Kpari = K.pari_bnf()
sage: Kpari.nf_get_pol()
y^2 + 5
sage: Kpari.bnf_get_cyc()  # Structure of class group
[2]
sage: Lpari = Kpari.nf_subst('a')
sage: Lpari.nf_get_pol()
a^2 + 5
sage: Lpari.bnf_get_cyc()  # We still have a bnf after substituting
[2]
nfbasis(flag=0, fa=None)

Integral basis of the field \QQ[a], where a is a root of the polynomial x.

INPUT:

  • flag: if set to 1 and fa is not given: assume that no square of a prime > 500000 divides the discriminant of x.

  • fa: If present, encodes a subset of primes at which to check for maximality. This must be one of the three following things:

    • an integer: check all primes up to fa using trial division.
    • a vector: a list of primes to check.
    • a matrix: a partial factorization of the discriminant of x.

Note

In earlier versions of Sage, other bits in flag were defined but these are now simply ignored.

EXAMPLES:

sage: pari('x^3 - 17').nfbasis()
[1, x, 1/3*x^2 - 1/3*x + 1/3]

We test flag = 1, noting it gives a wrong result when the discriminant (-4 * p`^2 * `q in the example below) has a big square factor:

sage: p = next_prime(10^10); q = next_prime(p)
sage: x = polygen(QQ); f = x^2 + p^2*q
sage: pari(f).nfbasis(1)   # Wrong result
[1, x]
sage: pari(f).nfbasis()    # Correct result
[1, 1/10000000019*x]
sage: pari(f).nfbasis(fa=10^6)   # Check primes up to 10^6: wrong result
[1, x]
sage: pari(f).nfbasis(fa="[2,2; %s,2]"%p)    # Correct result and faster
[1, 1/10000000019*x]
sage: pari(f).nfbasis(fa=[2,p])              # Equivalent with the above
[1, 1/10000000019*x]
nfbasis_d(flag=0, fa=None)

Like nfbasis(), but return a tuple (B, D) where B is the integral basis and D the discriminant.

EXAMPLES:

sage: F = NumberField(x^3-2,'alpha')
sage: F._pari_()[0].nfbasis_d()
([1, y, y^2], -108)
sage: G = NumberField(x^5-11,'beta')
sage: G._pari_()[0].nfbasis_d()
([1, y, y^2, y^3, y^4], 45753125)
sage: pari([-2,0,0,1]).Polrev().nfbasis_d()
([1, x, x^2], -108)
nfbasistoalg(nf, x)

Transforms the column vector x on the integral basis into an algebraic number.

INPUT:

  • nf – a number field
  • x – a column of rational numbers of length equal to the degree of nf or a single rational number

OUTPUT:

  • A POLMOD representing the element of nf whose coordinates are x in the Z-basis of nf.

EXAMPLES:

sage: x = polygen(QQ)
sage: K.<a> = NumberField(x^3 - 17)
sage: Kpari = K.pari_nf()
sage: Kpari.getattr('zk')
[1, 1/3*y^2 - 1/3*y + 1/3, y]
sage: Kpari.nfbasistoalg(42)
Mod(42, y^3 - 17)
sage: Kpari.nfbasistoalg("[3/2, -5, 0]~")
Mod(-5/3*y^2 + 5/3*y - 1/6, y^3 - 17)
sage: Kpari.getattr('zk') * pari("[3/2, -5, 0]~")
-5/3*y^2 + 5/3*y - 1/6
nfbasistoalg_lift(nf, x)

Transforms the column vector x on the integral basis into a polynomial representing the algebraic number.

INPUT:

  • nf – a number field
  • x – a column of rational numbers of length equal to the degree of nf or a single rational number

OUTPUT:

  • nf.nfbasistoalg(x).lift()

EXAMPLES:

sage: x = polygen(QQ)
sage: K.<a> = NumberField(x^3 - 17)
sage: Kpari = K.pari_nf()
sage: Kpari.getattr('zk')
[1, 1/3*y^2 - 1/3*y + 1/3, y]
sage: Kpari.nfbasistoalg_lift(42)
42
sage: Kpari.nfbasistoalg_lift("[3/2, -5, 0]~")
-5/3*y^2 + 5/3*y - 1/6
sage: Kpari.getattr('zk') * pari("[3/2, -5, 0]~")
-5/3*y^2 + 5/3*y - 1/6
nfdisc(flag=-1, p=None)

nfdisc(x): Return the discriminant of the number field defined over QQ by x.

EXAMPLES:

sage: F = NumberField(x^3-2,'alpha')
sage: F._pari_()[0].nfdisc()
-108
sage: G = NumberField(x^5-11,'beta')
sage: G._pari_()[0].nfdisc()
45753125
sage: f = x^3-2
sage: f._pari_()
x^3 - 2
sage: f._pari_().nfdisc()
-108
nfeltdiveuc(x, y)

Given x and y in the number field self, return q such that x - q y is “small”.

EXAMPLES:

sage: k.<a> = NumberField(x^2 + 5)
sage: x = 10
sage: y = a + 1
sage: pari(k).nfeltdiveuc(pari(x), pari(y))
[2, -2]~
nfeltreduce(x, I)

Given an ideal I in Hermite normal form and an element x of the pari number field self, finds an element r in self such that x-r belongs to the ideal and r is small.

EXAMPLES:

sage: k.<a> = NumberField(x^2 + 5)
sage: I = k.ideal(a)
sage: kp = pari(k)
sage: kp.nfeltreduce(12, I.pari_hnf())
[2, 0]~
sage: 12 - k(kp.nfeltreduce(12, I.pari_hnf())) in I
True
nfgaloisconj(flag=0, denom=None, precision=0)

Edited from the pari documentation:

nfgaloisconj(nf): list of conjugates of a root of the polynomial x=nf.pol in the same number field.

Uses a combination of Allombert’s algorithm and nfroots.

EXAMPLES:

sage: x = QQ['x'].0; nf = pari(x^2 + 2).nfinit()
sage: nf.nfgaloisconj()
[-x, x]~
sage: nf = pari(x^3 + 2).nfinit()
sage: nf.nfgaloisconj()
[x]~
sage: nf = pari(x^4 + 2).nfinit()
sage: nf.nfgaloisconj()
[-x, x]~
nfgenerator()
nfhilbert(a, b, p=None)

nfhilbert(nf,a,b,{p}): if p is omitted, global Hilbert symbol (a,b) in nf, that is 1 if X^2-aY^2-bZ^2 has a non-trivial solution (X,Y,Z) in nf, -1 otherwise. Otherwise compute the local symbol modulo the prime ideal p.

EXAMPLES:

sage: x = polygen(QQ)
sage: K.<t> = NumberField(x^3 - x + 1)
sage: pari(K).nfhilbert(t, t + 2)
-1
sage: P = K.ideal(t^2 + t - 2)   # Prime ideal above 5
sage: pari(K).nfhilbert(t, t + 2, P.pari_prime())
-1
sage: P = K.ideal(t^2 + 3*t - 1) # Prime ideal above 23, ramified
sage: pari(K).nfhilbert(t, t + 2, P.pari_prime())
1
nfhnf(x)

nfhnf(nf,x) : given a pseudo-matrix (A, I) or an integral pseudo-matrix (A,I,J), finds a pseudo-basis in Hermite normal form of the module it generates.

A pseudo-matrix is a 2-component row vector (A, I) where A is a relative m x n matrix and I an ideal list of length n. An integral pseudo-matrix is a 3-component row vector (A, I, J).

Note

The definition of a pseudo-basis ([Cohen]): Let M be a finitely generated, torsion-free R-module, and set V = KM. If \mathfrak{a}_i are fractional ideals of R and w_i are elements of V, we say that (w_i, \mathfrak{a}_k)_{1 \leq i \leq k} is a pseudo-basis of M if M = \mathfrak{a}_1 w_1 \oplus \cdots \oplus \mathfrak{a}_k w_k.

REFERENCES:

[Cohen]Cohen, “Advanced Topics in Computational Number Theory”

EXAMPLES:

sage: F.<a> = NumberField(x^2-x-1)
sage: Fp = pari(F)
sage: A = matrix(F,[[1,2,a,3],[3,0,a+2,0],[0,0,a,2],[3+a,a,0,1]])
sage: I = [F.ideal(-2*a+1),F.ideal(7), F.ideal(3),F.ideal(1)]
sage: Fp.nfhnf([pari(A),[pari(P) for P in I]])
[[1, [-969/5, -1/15]~, [15, -2]~, [-1938, -3]~; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1], [[3997, 1911; 0, 7], [15, 6; 0, 3], 1, 1]]
sage: K.<b> = NumberField(x^3-2)
sage: Kp = pari(K)
sage: A = matrix(K,[[1,0,0,5*b],[1,2*b^2,b,57],[0,2,1,b^2-3],[2,0,0,b]])
sage: I = [K.ideal(2),K.ideal(3+b^2),K.ideal(1),K.ideal(1)]
sage: Kp.nfhnf([pari(A),[pari(P) for P in I]])
[[1, -225, 72, -31; 0, 1, [0, -1, 0]~, [0, 0, -1/2]~; 0, 0, 1, [0, 0, -1/2]~; 0, 0, 0, 1], [[1116, 756, 612; 0, 18, 0; 0, 0, 18], 2, 1, [2, 0, 0; 0, 1, 0; 0, 0, 1]]]

An example where the ring of integers of the number field is not a PID:

sage: K.<b> = NumberField(x^2+5)
sage: Kp = pari(K)
sage: A = matrix(K,[[1,0,0,5*b],[1,2*b^2,b,57],[0,2,1,b^2-3],[2,0,0,b]])
sage: I = [K.ideal(2),K.ideal(3+b^2),K.ideal(1),K.ideal(1)]
sage: Kp.nfhnf([pari(A),[pari(P) for P in I]])
[[1, [15, 6]~, [0, -54]~, [113, 72]~; 0, 1, [-4, -1]~, [0, -1]~; 0, 0, 1, 0; 0, 0, 0, 1], [[360, 180; 0, 180], [6, 4; 0, 2], 1, 1]]
sage: A = matrix(K,[[1,0,0,5*b],[1,2*b,b,57],[0,2,1,b-3],[2,0,b,b]])
sage: I = [K.ideal(2).factor()[0][0],K.ideal(3+b),K.ideal(1),K.ideal(1)]
sage: Kp.nfhnf([pari(A),[pari(P) for P in I]])
[[1, [7605, 4]~, [5610, 5]~, [7913, -6]~; 0, 1, 0, -1; 0, 0, 1, 0; 0, 0, 0, 1], [[19320, 13720; 0, 56], [2, 1; 0, 1], 1, 1]]

AUTHORS:

  • Aly Deines (2012-09-19)
nfinit(flag=0, precision=0)

nfinit(pol, {flag=0}): pol being a nonconstant irreducible polynomial, gives a vector containing all the data necessary for PARI to compute in this number field.

flag is optional and can be set to:
  • 0: default

  • 1: do not compute different

  • 2: first use polred to find a simpler polynomial

  • 3: outputs a two-element vector [nf,Mod(a,P)], where nf is as in 2

    and Mod(a,P) is a polmod equal to Mod(x,pol) and P=nf.pol

EXAMPLES:

sage: pari('x^3 - 17').nfinit()
[x^3 - 17, [1, 1], -867, 3, [[1, 1.68006914259990, 2.57128159065824; 1, -0.340034571299952 - 2.65083754153991*I, -1.28564079532912 + 2.22679517779329*I], [1, 1.68006914259990, 2.57128159065824; 1, -2.99087211283986, 0.941154382464174; 1, 2.31080297023995, -3.51243597312241], [1, 2, 3; 1, -3, 1; 1, 2, -4], [3, 1, 0; 1, -11, 17; 0, 17, 0], [51, 0, 16; 0, 17, 3; 0, 0, 1], [17, 0, -1; 0, 0, 3; -1, 3, 2], [51, [-17, 6, -1; 0, -18, 3; 1, 0, -16]], [3, 17]], [2.57128159065824, -1.28564079532912 + 2.22679517779329*I], [1, 1/3*x^2 - 1/3*x + 1/3, x], [1, 0, -1; 0, 0, 3; 0, 1, 1], [1, 0, 0, 0, -4, 6, 0, 6, -1; 0, 1, 0, 1, 1, -1, 0, -1, 3; 0, 0, 1, 0, 2, 0, 1, 0, 1]]

TESTS:

sage: pari('x^2 + 10^100 + 1').nfinit()
[...]
sage: pari('1.0').nfinit()
Traceback (most recent call last):
...
PariError: incorrect type in checknf [please apply nfinit()] (t_REAL)
nfisisom(other)

nfisisom(x, y): Determine if the number fields defined by x and y are isomorphic. According to the PARI documentation, this is much faster if at least one of x or y is a number field. If they are isomorphic, it returns an embedding for the generators. If not, returns 0.

EXAMPLES:

sage: F = NumberField(x^3-2,'alpha')
sage: G = NumberField(x^3-2,'beta')
sage: F._pari_().nfisisom(G._pari_())
[y]
sage: GG = NumberField(x^3-4,'gamma')
sage: F._pari_().nfisisom(GG._pari_())
[1/2*y^2]
sage: F._pari_().nfisisom(GG.pari_nf())
[1/2*y^2]
sage: F.pari_nf().nfisisom(GG._pari_()[0])
[y^2]
sage: H = NumberField(x^2-2,'alpha')
sage: F._pari_().nfisisom(H._pari_())
0

TESTS:

This method converts its second argument (trac ticket #18728):

sage: K.<a> = NumberField(x^2 + x + 1)
sage: L.<b> = NumberField(x^2 + 3)
sage: pari(K).nfisisom(L)
[-1/2*y - 1/2, 1/2*y - 1/2]
nfroots(poly)

Return the roots of poly in the number field self without multiplicity.

EXAMPLES:

sage: y = QQ['yy'].0; _ = pari(y) # pari has variable ordering rules
sage: x = QQ['zz'].0; nf = pari(x^2 + 2).nfinit()
sage: nf.nfroots(y^2 + 2)
[Mod(-zz, zz^2 + 2), Mod(zz, zz^2 + 2)]
sage: nf = pari(x^3 + 2).nfinit()
sage: nf.nfroots(y^3 + 2)
[Mod(zz, zz^3 + 2)]
sage: nf = pari(x^4 + 2).nfinit()
sage: nf.nfroots(y^4 + 2)
[Mod(-zz, zz^4 + 2), Mod(zz, zz^4 + 2)]
nfrootsof1()

nf.nfrootsof1()

number of roots of unity and primitive root of unity in the number field nf.

EXAMPLES:

sage: nf = pari('x^2 + 1').nfinit()
sage: nf.nfrootsof1()
[4, x]
nfsubfields(d=0)

Find all subfields of degree d of number field nf (all subfields if d is null or omitted). Result is a vector of subfields, each being given by [g,h], where g is an absolute equation and h expresses one of the roots of g in terms of the root x of the polynomial defining nf.

INPUT:

  • self - nf number field
  • d - C long integer
nrows()

Return the number of rows of self.

EXAMPLES:

sage: pari('matrix(19,8)').nrows()
19
numbpart(x)

numbpart(x): returns the number of partitions of x.

EXAMPLES:

sage: pari(20).numbpart()
627
sage: pari(100).numbpart()
190569292
numdiv(n)

Return the number of divisors of the integer n.

EXAMPLES:

sage: pari(10).numdiv()
4
omega(precision=0)

e.omega(): return basis for the period lattice of the elliptic curve e.

EXAMPLES:

sage: e = pari([0, -1, 1, -10, -20]).ellinit()
sage: e.omega()
[1.26920930427955, 0.634604652139777 - 1.45881661693850*I]
order()
padicprec(x, p)

padicprec(x,p): Return the absolute p-adic precision of the object x.

INPUT:

  • x - gen

OUTPUT: int

EXAMPLES:

sage: K = Qp(11,5)
sage: x = K(11^-10 + 5*11^-7 + 11^-6)
sage: y = pari(x)
sage: y.padicprec(11)
-5
sage: y.padicprec(17)
Traceback (most recent call last):
...
PariError: inconsistent moduli in padicprec: 11 != 17

This works for polynomials too:

sage: R.<t> = PolynomialRing(Zp(3))
sage: pol = R([O(3^4), O(3^6), O(3^5)])
sage: pari(pol).padicprec(3)
4
padicprime(x)

The uniformizer of the p-adic ring this element lies in, as a t_INT.

INPUT:

  • x - gen, of type t_PADIC

OUTPUT:

  • p - gen, of type t_INT

EXAMPLES:

sage: K = Qp(11,5)
sage: x = K(11^-10 + 5*11^-7 + 11^-6)
sage: y = pari(x)
sage: y.padicprime()
11
sage: y.padicprime().type()
't_INT'
phi(n)

Return the Euler phi function of n.

EXAMPLES:

sage: pari(10).phi()
4
polcoeff(n, var=-1)

EXAMPLES:

sage: f = pari("x^2 + y^3 + x*y")
sage: f
x^2 + y*x + y^3
sage: f.polcoeff(1)
y
sage: f.polcoeff(3)
0
sage: f.polcoeff(3, "y")
1
sage: f.polcoeff(1, "y")
x
poldegree(var=-1)

f.poldegree(var=x): Return the degree of this polynomial.

poldisc(var=-1)

Return the discriminant of this polynomial.

EXAMPLES:

sage: pari("x^2 + 1").poldisc()
-4

Before trac ticket #15654, this used to take a very long time. Now it takes much less than a second:

sage: pari.allocatemem(200000)
PARI stack size set to 200000 bytes
sage: x = polygen(ZpFM(3,10))
sage: pol = ((x-1)^50 + x)
sage: pari(pol).poldisc()
2*3 + 3^4 + 2*3^6 + 3^7 + 2*3^8 + 2*3^9 + O(3^10)
polinterpolate(ya, x)

self.polinterpolate(ya,x,e): polynomial interpolation at x according to data vectors self, ya (i.e. return P such that P(self[i]) = ya[i] for all i). Also return an error estimate on the returned value.

polisirreducible()

f.polisirreducible(): Returns True if f is an irreducible non-constant polynomial, or False if f is reducible or constant.

polroots(flag=-1, precision=0)

Complex roots of the given polynomial using Schonhage’s method, as modified by Gourdon.

polrootspadicfast(p, r=20)
polsturm_full(*args, **kwds)

Deprecated: Use polsturm() instead. See trac ticket #18203 for details.

polylog(x, m, flag=0, precision=0)

x.polylog(m,flag=0): m-th polylogarithm of x. flag is optional, and can be 0: default, 1: D_m -modified m-th polylog of x, 2: D_m-modified m-th polylog of x, 3: P_m-modified m-th polylog of x.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

TODO: Add more explanation, copied from the PARI manual.

EXAMPLES:

sage: pari(10).polylog(3)
5.64181141475134 - 8.32820207698027*I
sage: pari(10).polylog(3,0)
5.64181141475134 - 8.32820207698027*I
sage: pari(10).polylog(3,1)
0.523778453502411
sage: pari(10).polylog(3,2)
-0.400459056163451
pr_get_e()

Returns the ramification index (over \QQ) of this prime ideal.

NOTE: self must be a PARI prime ideal (as returned by idealfactor for example).

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: pari(K).idealfactor(K.ideal(2))[0,0].pr_get_e()
2
sage: pari(K).idealfactor(K.ideal(3))[0,0].pr_get_e()
1
sage: pari(K).idealfactor(K.ideal(5))[0,0].pr_get_e()
1
pr_get_f()

Returns the residue class degree (over \QQ) of this prime ideal.

NOTE: self must be a PARI prime ideal (as returned by idealfactor for example).

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: pari(K).idealfactor(K.ideal(2))[0,0].pr_get_f()
1
sage: pari(K).idealfactor(K.ideal(3))[0,0].pr_get_f()
2
sage: pari(K).idealfactor(K.ideal(5))[0,0].pr_get_f()
1
pr_get_gen()

Returns the second generator of this PARI prime ideal, where the first generator is self.pr_get_p().

NOTE: self must be a PARI prime ideal (as returned by idealfactor for example).

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: g = pari(K).idealfactor(K.ideal(2))[0,0].pr_get_gen(); g; K(g)
[1, 1]~
i + 1
sage: g = pari(K).idealfactor(K.ideal(3))[0,0].pr_get_gen(); g; K(g)
[3, 0]~
3
sage: g = pari(K).idealfactor(K.ideal(5))[0,0].pr_get_gen(); g; K(g)
[-2, 1]~
i - 2
pr_get_p()

Returns the prime of \ZZ lying below this prime ideal.

NOTE: self must be a PARI prime ideal (as returned by idealfactor for example).

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: F = pari(K).idealfactor(K.ideal(5)); F
[[5, [-2, 1]~, 1, 1, [2, -1; 1, 2]], 1; [5, [2, 1]~, 1, 1, [-2, -1; 1, -2]], 1]
sage: F[0,0].pr_get_p()
5
precision(x, n=-1)

precision(x,n): Change the precision of x to be n, where n is a C-integer). If n is omitted, output the real precision of x.

INPUT:

  • x - gen
  • n - (optional) int

OUTPUT: nothing or gen if n is omitted

EXAMPLES:

primepi()

Return the number of primes less than or equal to self.

EXAMPLES:

sage: pari(7).primepi()
4
sage: pari(100).primepi()
25
sage: pari(1000).primepi()
168
sage: pari(100000).primepi()
9592
sage: pari(0).primepi()
0
sage: pari(-15).primepi()
0
sage: pari(500509).primepi()
41581
printtex(x)
psi(x, precision=0)

x.psi(): psi-function at x.

Return the \psi-function of x, i.e., the logarithmic derivative \Gamma'(x)/\Gamma(x).

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).psi()
-0.577215664901533
python(locals=None)

Return Python eval of self.

Note: is self is a real (type t_REAL) the result will be a RealField element of the equivalent precision; if self is a complex (type t_COMPLEX) the result will be a ComplexField element of precision the minimum precision of the real and imaginary parts.

EXAMPLES:

sage: pari('389/17').python()
389/17
sage: f = pari('(2/3)*x^3 + x - 5/7 + y'); f
2/3*x^3 + x + (y - 5/7)
sage: var('x,y')
(x, y)
sage: f.python({'x':x, 'y':y})
2/3*x^3 + x + y - 5/7

You can also use .sage, which is a psynonym:

sage: f.sage({'x':x, 'y':y})
2/3*x^3 + x + y - 5/7
python_list()

Return a Python list of the PARI gens. This object must be of type t_VEC.

INPUT: None

OUTPUT:

  • list - Python list whose elements are the elements of the input gen.

EXAMPLES:

sage: v=pari([1,2,3,10,102,10])
sage: w = v.python_list()
sage: w
[1, 2, 3, 10, 102, 10]
sage: type(w[0])
<type 'sage.libs.pari.gen.gen'>
sage: pari("[1,2,3]").python_list()
[1, 2, 3]
python_list_small()

Return a Python list of the PARI gens. This object must be of type t_VECSMALL, and the resulting list contains python ‘int’s.

EXAMPLES:

sage: v=pari([1,2,3,10,102,10]).Vecsmall()
sage: w = v.python_list_small()
sage: w
[1, 2, 3, 10, 102, 10]
sage: type(w[0])
<type 'int'>
qfbclassno(d, flag=0)

Computes the class number of the quadratic order of discriminant d.

INPUT:

  • d (gen) – a quadratic discriminant, which is an integer congruent to 0 or 1mod4`, not a square.
  • flag (long int) – if 0 (default), uses Euler product and the functional equation for d>0 or Shanks’s method for d<0; if 1, uses Euler products and the functional equation in both cases.

OUTPUT:

The class number of the quadratic order with discriminant d.

Warning

Using Euler products and the functional equation is reliable but has complexity O(|d|^{1/2}). Using Shanks’s method for d<0 is O(|d|^{1/4}) but this function may give incorrect results when the class group has many cyclic factors, because implementing Shanks’s method in full generality slows it down immensely. It is therefore strongly recommended to double-check results using either the version with flag = 1 or the function quadclassunit. The result is unconditionally correct for -d < 2e10.

EXAMPLES:

sage: pari(-4).qfbclassno()
1
sage: pari(-23).qfbclassno()
3
sage: pari(-104).qfbclassno()
6

sage: pari(109).qfbclassno()
1
sage: pari(10001).qfbclassno()
16
sage: pari(10001).qfbclassno(flag=1)
16

TESTS:

The input must be congruent to 0 or 1\mod4 and not a square:

sage: pari(3).qfbclassno()
Traceback (most recent call last):
...
PariError: domain error in classno2: disc % 4 > 1
sage: pari(4).qfbclassno()
Traceback (most recent call last):
...
PariError: domain error in classno2: issquare(disc) = 1
qfbhclassno(n)

Computes the Hurwitz-Kronecker class number of n.

INPUT:

  • n (gen) – a non-negative integer

OUTPUT:

0 if n<0, otherwise the Hurwitz-Kronecker class number of n. This is 0 if n\equiv1,2\mod4, -1/12 when n=0, and otherwise it is the number of classes of positive definite binary quadratic forms with discriminant -n, each weighted by the number of its automorphisms.

Note

If n is large (more than 5*10^5), the result is conditional upon GRH.

EXAMPLES:

The Hurwitz class number is 0 if n is congruent to 1 or 2 modulo 4:

sage: pari(10009).qfbhclassno()
0
sage: pari(2).qfbhclassno()
0

It is -1/12 for n=0:

sage: pari(0).qfbhclassno()
-1/12

Otherwise it is the number of classes of positive definite binary quadratic forms with discriminant -n, weighted by 1/m where m is the number of automorphisms of the form:

sage: pari(4).qfbhclassno()
1/2
sage: pari(3).qfbhclassno()
1/3
sage: pari(23).qfbhclassno()
3
qfminim(b=None, m=None, flag=0, precision=0)

Return vectors with bounded norm for this quadratic form.

INPUT:

  • self – a quadratic form

  • b – a bound on vector norm (finds minimal non-zero vectors if b is None)

  • m – maximum number of vectors to return. If None (default), return all vectors of norm at most B

  • flag (optional) –

    • 0: default;
    • 1: return only the first minimal vector found (ignore max);
    • 2: as 0 but uses a more robust, slower implementation, valid for non integral quadratic forms.

OUTPUT:

A triple consisting of

  • the number of vectors of norm <= b,
  • the actual maximum norm of vectors listed
  • a matrix whose columns are vectors with norm less than or equal to b for the definite quadratic form. Only one of v and -v is returned and the zero vector is never returned.

Note

If max is specified then only max vectors will be output, but all vectors withing the given norm bound will be computed.

EXAMPLES:

sage: A = Matrix(3,3,[1,2,3,2,5,5,3,5,11])
sage: A.is_positive_definite()
True

The first 5 vectors of norm at most 10:

sage: pari(A).qfminim(10, 5).python()
[
         [-17 -14 -15 -16 -13]
         [  4   3   3   3   2]
146, 10, [  3   3   3   3   3]
]

All vectors of minimal norm:

sage: pari(A).qfminim().python()
[
      [-5 -2  1]
      [ 1  1  0]
6, 1, [ 1  0  0]
]

Use flag=2 for non-integral input:

sage: pari(A.change_ring(RR)).qfminim(5, m=5, flag=2).python()
[
                         [ -5 -10  -2  -7   3]
                         [  1   2   1   2   0]
10, 5.00000000000000000, [  1   2   0   1  -1]
]
qfparam(sol, flag=0)

Coefficients of binary quadratic forms that parametrize the solutions of the ternary quadratic form self, using the particular solution sol.

INPUT:

  • self – a rational symmetric matrix
  • sol – a non-trivial solution to the quadratic form self

OUTPUT:

A matrix whose rows define polynomials which parametrize all solutions to the quadratic form self in the projective plane.

EXAMPLES:

The following can be used to parametrize Pythagorean triples:

sage: M = diagonal_matrix([1,1,-1])
sage: P = M._pari_().qfparam([0,1,-1]); P
[0, -2, 0; 1, 0, -1; -1, 0, -1]
sage: R.<x,y> = QQ[]
sage: v = P.sage() * vector([x^2, x*y, y^2]); v
(-2*x*y, x^2 - y^2, -x^2 - y^2)
sage: v(x=2, y=1)
(-4, 3, -5)
sage: v(x=3,y=8)
(-48, -55, -73)
sage: 48^2 + 55^2 == 73^2
True
qfrep(B, flag=0)

Vector of (half) the number of vectors of norms from 1 to B for the integral and definite quadratic form self. Binary digits of flag mean 1: count vectors of even norm from 1 to 2B, 2: return a t_VECSMALL instead of a t_VEC (which is faster).

EXAMPLES:

sage: M = pari("[5,1,1;1,3,1;1,1,1]")
sage: M.qfrep(20)
[1, 1, 2, 2, 2, 4, 4, 3, 3, 4, 2, 4, 6, 0, 4, 6, 4, 5, 6, 4]
sage: M.qfrep(20, flag=1)
[1, 2, 4, 3, 4, 4, 0, 6, 5, 4, 12, 4, 4, 8, 0, 3, 8, 6, 12, 12]
sage: M.qfrep(20, flag=2)
Vecsmall([1, 1, 2, 2, 2, 4, 4, 3, 3, 4, 2, 4, 6, 0, 4, 6, 4, 5, 6, 4])
qfsolve()

Try to solve over \mathbb{Q} the quadratic equation X^t G X = 0 for a matrix G with rational coefficients.

INPUT:

  • self – a rational symmetric matrix

OUTPUT:

If the quadratic form is solvable, return a column or a matrix with multiple columns spanning an isotropic subspace (there is no guarantee that the maximal isotropic subspace is returned).

If the quadratic form is not solvable and the dimension is at 3, return the local obstruction: a place (-1 or a prime p) where the form is not locally solvable. For unsolvable forms in dimension 2, the number -2 is returned.

EXAMPLES:

sage: M = diagonal_matrix([1,2,3,4,-5])
sage: M._pari_().qfsolve()
[0, 1, -1, 0, -1]~
sage: M = diagonal_matrix([4,-9])
sage: M._pari_().qfsolve()
[6, 4]~

An example of a real obstruction:

sage: M = diagonal_matrix([1,1,1,1,1])
sage: M._pari_().qfsolve()
-1

An example of a p-adic obstruction:

sage: M = diagonal_matrix([1,1,-3])
sage: M._pari_().qfsolve()
3

In dimension 2, we get -2 if the form is not solvable:

sage: M = diagonal_matrix([1,-42])
sage: M._pari_().qfsolve()
-2

For singular quadratic forms, the kernel is returned:

sage: M = diagonal_matrix([1,-1,0,0])
sage: M._pari_().qfsolve().sage()
[0 0]
[0 0]
[1 0]
[0 1]
quadclassunit(d, precision=0)

Returns the class group of a quadratic order of discriminant d.

INPUT:

  • d (gen) – a quadratic discriminant, which is an integer congruent to 0 or 1mod4`, not a square.

OUTPUT:

(h,cyc,gen,reg) where:

  • h is the class number
  • cyc is the class group structure (list of invariants)
  • gen is the class group generators (list of quadratic forms)
  • reg is the regulator

ALGORITHM:

Buchmann-McCurley’s sub-exponential algorithm

EXAMPLES:

sage: pari(-4).quadclassunit()
[1, [], [], 1]
sage: pari(-23).quadclassunit()
[3, [3], [Qfb(2, 1, 3)], 1]
sage: pari(-104).quadclassunit()
[6, [6], [Qfb(5, -4, 6)], 1]

sage: pari(109).quadclassunit()
[1, [], [], 5.56453508676047]
sage: pari(10001).quadclassunit() # random generators
[16, [16], [Qfb(10, 99, -5, 0.E-38)], 5.29834236561059]
sage: pari(10001).quadclassunit()[0]
16
sage: pari(10001).quadclassunit()[1]
[16]
sage: pari(10001).quadclassunit()[3]
5.29834236561059

TESTS:

The input must be congruent to 0 or 1\mod4 and not a square:

sage: pari(3).quadclassunit()
Traceback (most recent call last):
...
PariError: domain error in Buchquad: disc % 4 > 1
sage: pari(4).quadclassunit()
Traceback (most recent call last):
...
PariError: domain error in Buchquad: issquare(disc) = 1
quadhilbert()

Returns a polynomial over \QQ whose roots generate the Hilbert class field of the quadratic field of discriminant self (which must be fundamental).

EXAMPLES:

sage: pari(-23).quadhilbert()
x^3 - x^2 + 1
sage: pari(145).quadhilbert()
x^4 - 6*x^2 - 5*x - 1
sage: pari(-12).quadhilbert()   # Not fundamental
Traceback (most recent call last):
...
PariError: domain error in quadray: isfundamental(D) = 0
reverse()

Return the polynomial obtained by reversing the coefficients of this polynomial.

rnfidealdown(x)

rnfidealdown(rnf,x): finds the intersection of the ideal x with the base field.

EXAMPLES:

sage: x = ZZ['xx1'].0; pari(x)
xx1
sage: y = ZZ['yy1'].0; pari(y)
yy1
sage: nf = pari(y^2 - 6*y + 24).nfinit()
sage: rnf = nf.rnfinit(x^2 - pari(y))

This is the relative HNF of the inert ideal (2) in rnf:

sage: P = pari('[[[1, 0]~, [0, 0]~; [0, 0]~, [1, 0]~], [[2, 0; 0, 2], [2, 0; 0, 1/2]]]')

And this is the inert ideal (2) in nf:

sage: rnf.rnfidealdown(P) 2
rnfinit(poly)

EXAMPLES: We construct a relative number field.

sage: f = pari('y^3+y+1')
sage: K = f.nfinit()
sage: x = pari('x'); y = pari('y')
sage: g = x^5 - x^2 + y
sage: L = K.rnfinit(g)
rnfisnorm(T, flag=0)
rnfpolred(*args, **kwds)
rnfpolredabs(*args, **kwds)
round(x, estimate=False)

round(x,estimate=False): If x is a real number, returns x rounded to the nearest integer (rounding up). If the optional argument estimate is True, also returns the binary exponent e of the difference between the original and the rounded value (the “fractional part”) (this is the integer ceiling of log_2(error)).

When x is a general PARI object, this function returns the result of rounding every coefficient at every level of PARI object. Note that this is different than what the truncate function does (see the example below).

One use of round is to get exact results after a long approximate computation, when theory tells you that the coefficients must be integers.

INPUT:

  • x - gen
  • estimate - (optional) bool, False by default

OUTPUT:

  • if estimate is False, return a single gen.
  • if estimate is True, return rounded version of x and error estimate in bits, both as gens.

EXAMPLES:

sage: pari('1.5').round()
2
sage: pari('1.5').round(True)
(2, -1)
sage: pari('1.5 + 2.1*I').round()
2 + 2*I
sage: pari('1.0001').round(True)
(1, -14)
sage: pari('(2.4*x^2 - 1.7)/x').round()
(2*x^2 - 2)/x
sage: pari('(2.4*x^2 - 1.7)/x').truncate()
2.40000000000000*x
sage(locals=None)

Return Python eval of self.

Note: is self is a real (type t_REAL) the result will be a RealField element of the equivalent precision; if self is a complex (type t_COMPLEX) the result will be a ComplexField element of precision the minimum precision of the real and imaginary parts.

EXAMPLES:

sage: pari('389/17').python()
389/17
sage: f = pari('(2/3)*x^3 + x - 5/7 + y'); f
2/3*x^3 + x + (y - 5/7)
sage: var('x,y')
(x, y)
sage: f.python({'x':x, 'y':y})
2/3*x^3 + x + y - 5/7

You can also use .sage, which is a psynonym:

sage: f.sage({'x':x, 'y':y})
2/3*x^3 + x + y - 5/7
serreverse()

serreverse(f): reversion of the power series f.

If f(t) is a series in t with valuation 1, find the series g(t) such that g(f(t)) = t.

EXAMPLES:

sage: f = pari('x+x^2+x^3+O(x^4)'); f
x + x^2 + x^3 + O(x^4)
sage: g = f.serreverse(); g
x - x^2 + x^3 + O(x^4)
sage: f.subst('x',g)
x + O(x^4)
sage: g.subst('x',f)
x + O(x^4)
sign(x)

Return the sign of x, where x is of type integer, real or fraction.

EXAMPLES:

sage: pari(pi).sign()
1
sage: pari(0).sign()
0
sage: pari(-1/2).sign()
-1

PARI throws an error if you attempt to take the sign of a complex number:

sage: pari(I).sign()
Traceback (most recent call last):
...
PariError: incorrect type in gsigne (t_COMPLEX)
simplify(x)

simplify(x): Simplify the object x as much as possible, and return the result.

A complex or quadratic number whose imaginary part is an exact 0 (i.e., not an approximate one such as O(3) or 0.E-28) is converted to its real part, and a a polynomial of degree 0 is converted to its constant term. Simplification occurs recursively.

This function is useful before using arithmetic functions, which expect integer arguments:

EXAMPLES:

sage: y = pari('y')
sage: x = pari('9') + y - y
sage: x
9
sage: x.type()
't_POL'
sage: x.factor()
matrix(0,2)
sage: pari('9').factor()
Mat([3, 2])
sage: x.simplify()
9
sage: x.simplify().factor()
Mat([3, 2])
sage: x = pari('1.5 + 0*I')
sage: x.type()
't_REAL'
sage: x.simplify()
1.50000000000000
sage: y = x.simplify()
sage: y.type()
't_REAL'
sin(x, precision=0)

x.sin(): The sine of x.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).sin()
0.841470984807897
sage: C.<i> = ComplexField()
sage: pari(1+i).sin()
1.29845758141598 + 0.634963914784736*I
sinh(x, precision=0)

The hyperbolic sine function.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(0).sinh()
0.E-19
sage: C.<i> = ComplexField()
sage: pari(1+i).sinh()
0.634963914784736 + 1.29845758141598*I
sizebyte(x)

Return the total number of bytes occupied by the complete tree of the object x. Note that this number depends on whether the computer is 32-bit or 64-bit.

INPUT:

  • x - gen

OUTPUT: int (a Python int)

EXAMPLE:

sage: pari('1').sizebyte()
12           # 32-bit
24           # 64-bit
sizedigit(x)

sizedigit(x): Return a quick estimate for the maximal number of decimal digits before the decimal point of any component of x.

INPUT:

  • x - gen

OUTPUT: Python integer

EXAMPLES:

sage: x = pari('10^100')
sage: x.Str().length()
101
sage: x.sizedigit()
doctest:...: DeprecationWarning: sizedigit() is deprecated in PARI
See http://trac.sagemath.org/18203 for details.
101

Note that digits after the decimal point are ignored:

sage: x = pari('1.234')
sage: x
1.23400000000000
sage: x.sizedigit()
1

The estimate can be one too big:

sage: pari('7234.1').sizedigit()
4
sage: pari('9234.1').sizedigit()
5
sizeword(x)

Return the total number of machine words occupied by the complete tree of the object x. A machine word is 32 or 64 bits, depending on the computer.

INPUT:

  • x - gen

OUTPUT: int (a Python int)

EXAMPLES:

sage: pari('0').sizeword()
2
sage: pari('1').sizeword()
3
sage: pari('1000000').sizeword()
3
sage: pari('10^100').sizeword()
13      # 32-bit
8       # 64-bit
sage: pari(RDF(1.0)).sizeword()
4       # 32-bit
3       # 64-bit
sage: pari('x').sizeword()
9
sage: pari('x^20').sizeword()
66
sage: pari('[x, I]').sizeword()
20
sqr(x)

x.sqr(): square of x. Faster than, and most of the time (but not always - see the examples) identical to x*x.

EXAMPLES:

sage: pari(2).sqr()
4

For 2-adic numbers, x.sqr() may not be identical to x*x (squaring a 2-adic number increases its precision):

sage: pari("1+O(2^5)").sqr()
1 + O(2^6)
sage: pari("1+O(2^5)")*pari("1+O(2^5)")
1 + O(2^5)

However:

sage: x = pari("1+O(2^5)"); x*x
1 + O(2^6)
sqrt(x, precision=0)

x.sqrt(precision): The square root of x.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).sqrt()
1.41421356237310
sqrtint(x)

Return the integer square root of the integer x, rounded towards zero.

EXAMPLES:

sage: pari(8).sqrtint()
2
sage: pari(10^100).sqrtint()
100000000000000000000000000000000000000000000000000
sqrtn(x, n, precision=0)

x.sqrtn(n): return the principal branch of the n-th root of x, i.e., the one such that \arg(\sqrt(x)) \in ]-\pi/n, \pi/n]. Also returns a second argument which is a suitable root of unity allowing one to recover all the other roots. If it was not possible to find such a number, then this second return value is 0. If the argument is present and no square root exists, return 0 instead of raising an error.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

Note

intmods (modulo a prime) and p-adic numbers are allowed as arguments.

INPUT:

  • x - gen
  • n - integer

OUTPUT:

  • gen - principal n-th root of x
  • gen - root of unity z that gives the other roots

EXAMPLES:

sage: s, z = pari(2).sqrtn(5)
sage: z
0.309016994374947 + 0.951056516295154*I
sage: s
1.14869835499704
sage: s^5
2.00000000000000
sage: z^5
1.00000000000000 - 2.710505431 E-20*I       # 32-bit
1.00000000000000 - 2.71050543121376 E-20*I  # 64-bit
sage: (s*z)^5
2.00000000000000 + 0.E-19*I
subst(var, z)

In self, replace the variable var by the expression z.

EXAMPLES:

sage: x = pari("x"); y = pari("y")
sage: f = pari('x^3 + 17*x + 3')
sage: f.subst(x, y)
y^3 + 17*y + 3
sage: f.subst(x, "z")
z^3 + 17*z + 3
sage: f.subst(x, "z")^2
z^6 + 34*z^4 + 6*z^3 + 289*z^2 + 102*z + 9
sage: f.subst(x, "x+1")
x^3 + 3*x^2 + 20*x + 21
sage: f.subst(x, "xyz")
xyz^3 + 17*xyz + 3
sage: f.subst(x, "xyz")^2
xyz^6 + 34*xyz^4 + 6*xyz^3 + 289*xyz^2 + 102*xyz + 9
sumdiv(n)

Return the sum of the divisors of n.

EXAMPLES:

sage: pari(10).sumdiv()
18
sumdivk(n, k)

Return the sum of the k-th powers of the divisors of n.

EXAMPLES:

sage: pari(10).sumdivk(2)
130
tan(x, precision=0)

x.tan() - tangent of x

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(2).tan()
-2.18503986326152
sage: C.<i> = ComplexField()
sage: pari(i).tan()
0.761594155955765*I
tanh(x, precision=0)

x.tanh() - hyperbolic tangent of x

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(1).tanh()
0.761594155955765
sage: C.<i> = ComplexField()
sage: z = pari(i); z
1.00000000000000*I
sage: result = z.tanh()
sage: result.real() <= 1e-18
True
sage: result.imag()
1.55740772465490
teichmuller(x)

teichmuller(x): teichmuller character of p-adic number x.

This is the unique (p-1)-st root of unity congruent to x/p^{v_p(x)} modulo p.

EXAMPLES:

sage: pari('2+O(7^5)').teichmuller()
2 + 4*7 + 6*7^2 + 3*7^3 + O(7^5)
theta(q, z, precision=0)

q.theta(z): Jacobi sine theta-function.

If q or z is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(0.5).theta(2)
1.63202590295260
thetanullk(q, k, precision=0)

q.thetanullk(k): return the k-th derivative at z=0 of theta(q,z).

If q is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If q is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

EXAMPLES:

sage: pari(0.5).thetanullk(1)
0.548978532560341
trace()

Return the trace of this PARI object.

EXAMPLES:

sage: pari('[1,2; 3,4]').trace()
5
truncate(x, estimate=False)

truncate(x,estimate=False): Return the truncation of x. If estimate is True, also return the number of error bits.

When x is in the real numbers, this means that the part after the decimal point is chopped away, e is the binary exponent of the difference between the original and truncated value (the “fractional part”). If x is a rational function, the result is the integer part (Euclidean quotient of numerator by denominator) and if requested the error estimate is 0.

When truncate is applied to a power series (in X), it transforms it into a polynomial or a rational function with denominator a power of X, by chopping away the O(X^k). Similarly, when applied to a p-adic number, it transforms it into an integer or a rational number by chopping away the O(p^k).

INPUT:

  • x - gen
  • estimate - (optional) bool, which is False by default

OUTPUT:

  • if estimate is False, return a single gen.
  • if estimate is True, return rounded version of x and error estimate in bits, both as gens.

EXAMPLES:

sage: pari('(x^2+1)/x').round()
(x^2 + 1)/x
sage: pari('(x^2+1)/x').truncate()
x
sage: pari('1.043').truncate()
1
sage: pari('1.043').truncate(True)
(1, -5)
sage: pari('1.6').truncate()
1
sage: pari('1.6').round()
2
sage: pari('1/3 + 2 + 3^2 + O(3^3)').truncate()
34/3
sage: pari('sin(x+O(x^10))').truncate()
1/362880*x^9 - 1/5040*x^7 + 1/120*x^5 - 1/6*x^3 + x
sage: pari('sin(x+O(x^10))').round()   # each coefficient has abs < 1
x + O(x^10)
type()

Return the PARI type of self as a string.

Note

In Cython, it is much faster to simply use typ(self.g) for checking PARI types.

EXAMPLES:

sage: pari(7).type()
't_INT'
sage: pari('x').type()
't_POL'
valuation(x, p)

valuation(x,p): Return the valuation of x with respect to p.

The valuation is the highest exponent of p dividing x.

  • If p is an integer, x must be an integer, an intmod whose modulus is divisible by p, a rational number, a p-adic number, or a polynomial or power series in which case the valuation is the minimum of the valuations of the coefficients.
  • If p is a polynomial, x must be a polynomial or a rational function. If p is a monomial then x may also be a power series.
  • If x is a vector, complex or quadratic number, then the valuation is the minimum of the component valuations.
  • If x = 0, the result is 2^31-1 on 32-bit machines or 2^63-1 on 64-bit machines if x is an exact object. If x is a p-adic number or power series, the result is the exponent of the zero.

INPUT:

  • x - gen
  • p - coercible to gen

OUTPUT:

  • gen - integer

EXAMPLES:

sage: pari(9).valuation(3)
2
sage: pari(9).valuation(9)
1
sage: x = pari(9).Mod(27); x.valuation(3)
2
sage: pari('5/3').valuation(3)
-1
sage: pari('9 + 3*x + 15*x^2').valuation(3)
1
sage: pari([9,3,15]).valuation(3)
1
sage: pari('9 + 3*x + 15*x^2 + O(x^5)').valuation(3)
1
sage: pari('x^2*(x+1)^3').valuation(pari('x+1'))
3
sage: pari('x + O(x^5)').valuation('x')
1
sage: pari('2*x^2 + O(x^5)').valuation('x')
2
sage: pari(0).valuation(3)
2147483647            # 32-bit
9223372036854775807   # 64-bit
variable(x)

variable(x): Return the main variable of the object x, or p if x is a p-adic number.

This function raises a TypeError exception on scalars, i.e., on objects with no variable associated to them.

INPUT:

  • x - gen

OUTPUT: gen

EXAMPLES:

sage: pari('x^2 + x -2').variable()
x
sage: pari('1+2^3 + O(2^5)').variable()
2
sage: pari('x+y0').variable()
x
sage: pari('y0+z0').variable()
y0
vecextract(y, z=None)

self.vecextract(y,z): extraction of the components of the matrix or vector x according to y and z. If z is omitted, y designates columns, otherwise y corresponds to rows and z to columns. y and z can be vectors (of indices), strings (indicating ranges as in”1..10”) or masks (integers whose binary representation indicates the indices to extract, from left to right 1, 2, 4, 8, etc.)

Note

This function uses the PARI row and column indexing, so the first row or column is indexed by 1 instead of 0.

vecmax(x)

vecmax(x): Return the maximum of the elements of the vector/matrix x.

vecmin(x)

vecmin(x): Return the maximum of the elements of the vector/matrix x.

weber(x, flag=0, precision=0)

x.weber(flag=0): One of Weber’s f functions of x. flag is optional, and can be 0: default, function f(x)=exp(-i*Pi/24)*eta((x+1)/2)/eta(x) such that j=(f^{24}-16)^3/f^{24}, 1: function f1(x)=eta(x/2)/eta(x) such that j=(f1^24+16)^3/f2^{24}, 2: function f2(x)=sqrt(2)*eta(2*x)/eta(x) such that j=(f2^{24}+16)^3/f2^{24}.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

TODO: Add further explanation from PARI manual.

EXAMPLES:

sage: C.<i> = ComplexField()
sage: pari(i).weber()
1.18920711500272
sage: pari(i).weber(1)
1.09050773266526
sage: pari(i).weber(2)
1.09050773266526
xgcd(x, y)

Returns u,v,d such that d=gcd(x,y) and u*x+v*y=d.

EXAMPLES:

sage: pari(10).xgcd(15)
doctest:...: DeprecationWarning: xgcd() is deprecated, use gcdext() instead (note that the output is in a different order!)
See http://trac.sagemath.org/18203 for details.
(5, -1, 1)
zeta(s, precision=0)

zeta(s): zeta function at s with s a complex or a p-adic number.

If s is a complex number, this is the Riemann zeta function \zeta(s)=\sum_{n\geq 1} n^{-s}, computed either using the Euler-Maclaurin summation formula (if s is not an integer), or using Bernoulli numbers (if s is a negative integer or an even nonnegative integer), or using modular forms (if s is an odd nonnegative integer).

If s is a p-adic number, this is the Kubota-Leopoldt zeta function, i.e. the unique continuous p-adic function on the p-adic integers that interpolates the values of (1-p^{-k})\zeta(k) at negative integers k such that k\equiv 1\pmod{p-1} if p is odd, and at odd k if p=2.

If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.

INPUT:

  • s - gen (real, complex, or p-adic number)

OUTPUT:

  • gen - value of zeta at s.

EXAMPLES:

sage: pari(2).zeta()
1.64493406684823
sage: x = RR(pi)^2/6
sage: pari(x)
1.64493406684823
sage: pari(3).zeta()
1.20205690315959
sage: pari('1+5*7+2*7^2+O(7^3)').zeta()
4*7^-2 + 5*7^-1 + O(7^0)
znprimroot()

Return a primitive root modulo self, whenever it exists.

INPUT:

  • self – an integer n such that |n| is equal to 1, 2, 4, a power of an odd prime, or twice a power of an odd prime

OUTPUT:

A generator (type t_INTMOD) of (\ZZ/n\ZZ)^*. Note that this group is cyclic if and only if n is of the above form.

EXAMPLES:

sage: pari(4).znprimroot()
Mod(3, 4)
sage: pari(10007^3).znprimroot()
Mod(5, 1002101470343)
sage: pari(2*109^10).znprimroot()
Mod(236736367459211723407, 473472734918423446802)
znstar()

Return the structure of the group (\ZZ/n\ZZ)^*.

INPUT:

  • self – any integer n (type t_INT)

OUTPUT:

A triple [\phi(n), [d_1, \ldots, d_k], [x_1, \ldots, x_k]], where

  • \phi(n) is the order of (\ZZ/n\ZZ)^*;
  • d_1, \ldots, d_k are the unique integers greater than 1 with d_k \mid d_{k-1} \mid \ldots \mid d_1 such that (\ZZ/n\ZZ)^* is isomorphic to \prod_{i=1}^k \ZZ/d_i\ZZ;
  • x_1, \ldots, x_k are the images of the standard generators under some isomorphism from \prod_{i=1}^k \ZZ/d_i\ZZ to (\ZZ/n\ZZ)^*.

EXAMPLES:

sage: pari(0).znstar()
[2, [2], [-1]]
sage: pari(96).znstar()
[32, [8, 2, 2], [Mod(37, 96), Mod(79, 96), Mod(65, 96)]]
sage: pari(-5).znstar()
[4, [4], [Mod(2, 5)]]
class sage.libs.pari.gen.gen_auto

Bases: sage.structure.element.RingElement

Part of the gen class containing auto-generated functions.

This class is not meant to be used directly, use the derived class gen instead.

Col(x, n=0)

Transforms the object x into a column vector. The dimension of the resulting vector can be optionally specified via the extra parameter n.

If n is omitted or 0, the dimension depends on the type of x; the vector has a single component, except when x is

  • a vector or a quadratic form (in which case the resulting vector is simply the initial object considered as a row vector),
  • a polynomial or a power series. In the case of a polynomial, the coefficients of the vector start with the leading coefficient of the polynomial, while for power series only the significant coefficients are taken into account, but this time by increasing order of degree. In this last case, Vec is the reciprocal function of Pol and Ser respectively,
  • a matrix (the column of row vector comprising the matrix is returned),
  • a character string (a vector of individual characters is returned).

In the last two cases (matrix and character string), n is meaningless and must be omitted or an error is raised. Otherwise, if n is given, 0 entries are appended at the end of the vector if n > 0, and prepended at the beginning if n < 0. The dimension of the resulting vector is \|n\|.

Note that the function Colrev does not exist, use Vecrev.

Colrev(x, n=0)

As Col(x, -n), then reverse the result. In particular, Colrev is the reciprocal function of Polrev: the coefficients of the vector start with the constant coefficient of the polynomial and the others follow by increasing degree.

List(x)

Transforms a (row or column) vector x into a list, whose components are the entries of x. Similarly for a list, but rather useless in this case. For other types, creates a list with the single element x. Note that, except when x is omitted, this function creates a small memory leak; so, either initialize all lists to the empty list, or use them sparingly.

Map(x)

A “Map” is an associative array, or dictionary: a data type composed of a collection of (key, value) pairs, such that each key appears just once in the collection. This function converts the matrix [a_1,b_1;a_2,b_2;...;a_n,b_n] to the map a_i:--->
b_i.

? M = Map(factor(13!));
? mapget(M,3)
%2 = 5

If the argument x is omitted, create an empty map, which may be filled later via mapput

Mat(x)

Transforms the object x into a matrix. If x is already a matrix, a copy of x is created. If x is a row (resp. column) vector, this creates a 1-row (resp. 1-column) matrix, unless all elements are column (resp. row) vectors of the same length, in which case the vectors are concatenated sideways and the associated big matrix is returned. If x is a binary quadratic form, creates the associated 2 x 2 matrix. Otherwise, this creates a 1 x 1 matrix containing x.

? Mat(x + 1)
%1 =
[x + 1]
? Vec( matid(3) )
%2 = [[1, 0, 0]~, [0, 1, 0]~, [0, 0, 1]~]
? Mat(%)
%3 =
[1 0 0]

[0 1 0]

[0 0 1]
? Col( [1,2; 3,4] )
%4 = [[1, 2], [3, 4]]~
? Mat(%)
%5 =
[1 2]

[3 4]
? Mat(Qfb(1,2,3))
%6 =
[1 1]

[1 3]
Mod(a, b)

In its basic form, creates an intmod or a polmod (a mod b); b must be an integer or a polynomial. We then obtain a t_INTMOD and a t_POLMOD respectively:

? t = Mod(2,17); t^8
%1 = Mod(1, 17)
? t = Mod(x,x^2+1); t^2
%2 = Mod(-1, x^2+1)

If a \% b makes sense and yields a result of the appropriate type (t_INT or scalar/t_POL), the operation succeeds as well:

? Mod(1/2, 5)
%3 = Mod(3, 5)
? Mod(7 + O(3^6), 3)
%4 = Mod(1, 3)
? Mod(Mod(1,12), 9)
%5 = Mod(1, 3)
? Mod(1/x, x^2+1)
%6 = Mod(-1, x^2+1)
? Mod(exp(x), x^4)
%7 = Mod(1/6*x^3 + 1/2*x^2 + x + 1, x^4)

If a is a complex object, “base change” it to \mathbb{Z}/b\mathbb{Z} or K[x]/(b), which is equivalent to, but faster than, multiplying it by Mod(1,b):

? Mod([1,2;3,4], 2)
%8 =
[Mod(1, 2) Mod(0, 2)]

[Mod(1, 2) Mod(0, 2)]
? Mod(3*x+5, 2)
%9 = Mod(1, 2)*x + Mod(1, 2)
? Mod(x^2 + y*x + y^3, y^2+1)
%10 = Mod(1, y^2 + 1)*x^2 + Mod(y, y^2 + 1)*x + Mod(-y, y^2 + 1)

This function is not the same as x % y, the result of which has no knowledge of the intended modulus y. Compare

? x = 4 % 5; x + 1
%1 = 5
? x = Mod(4,5); x + 1
%2 = Mod(0,5)

Note that such “modular” objects can be lifted via lift or centerlift. The modulus of a t_INTMOD or t_POLMOD z can be recovered via :math:`z.mod`.

Pol(t, v=None)

Transforms the object t into a polynomial with main variable v. If t is a scalar, this gives a constant polynomial. If t is a power series with non-negative valuation or a rational function, the effect is similar to truncate, i.e. we chop off the O(X^k) or compute the Euclidean quotient of the numerator by the denominator, then change the main variable of the result to v.

The main use of this function is when t is a vector: it creates the polynomial whose coefficients are given by t, with t[1] being the leading coefficient (which can be zero). It is much faster to evaluate Pol on a vector of coefficients in this way, than the corresponding formal expression a_n X^n +...+ a_0, which is evaluated naively exactly as written (linear versus quadratic time in n). Polrev can be used if one wants x[1] to be the constant coefficient:

? Pol([1,2,3])
%1 = x^2 + 2*x + 3
? Polrev([1,2,3])
%2 = 3*x^2 + 2*x + 1

The reciprocal function of Pol (resp. Polrev) is Vec (resp.  Vecrev).

? Vec(Pol([1,2,3]))
%1 = [1, 2, 3]
? Vecrev( Polrev([1,2,3]) )
%2 = [1, 2, 3]

Warning. This is not a substitution function. It will not transform an object containing variables of higher priority than v.

? Pol(x + y, y)
 *** at top-level: Pol(x+y,y)
 *** ^----------
 *** Pol: variable must have higher priority in gtopoly.
Polrev(t, v=None)

Transform the object t into a polynomial with main variable v. If t is a scalar, this gives a constant polynomial. If t is a power series, the effect is identical to truncate, i.e. it chops off the O(X^k).

The main use of this function is when t is a vector: it creates the polynomial whose coefficients are given by t, with t[1] being the constant term. Pol can be used if one wants t[1] to be the leading coefficient:

? Polrev([1,2,3])
%1 = 3*x^2 + 2*x + 1
? Pol([1,2,3])
%2 = x^2 + 2*x + 3

The reciprocal function of Pol (resp. Polrev) is Vec (resp.  Vecrev).

Qfb(a, b, c, D=None, precision=0)

Creates the binary quadratic form ax^2+bxy+cy^2. If b^2-4ac > 0, initialize Shanks’ distance function to D. Negative definite forms are not implemented, use their positive definite counterpart instead.

Ser(s, v=None, serprec=-1)

Transforms the object s into a power series with main variable v (x by default) and precision (number of significant terms) equal to d >= 0 (d = seriesprecision by default). If s is a scalar, this gives a constant power series in v with precision d. If s is a polynomial, the polynomial is truncated to d terms if needed

? Ser(1, 'y, 5)
%1 = 1 + O(y^5)
? Ser(x^2,, 5)
%2 = x^2 + O(x^7)
? T = polcyclo(100)
%3 = x^40 - x^30 + x^20 - x^10 + 1
? Ser(T, 'x, 11)
%4 = 1 - x^10 + O(x^11)

The function is more or less equivalent with multiplication by 1 + O(v^d) in theses cases, only faster.

If s is a vector, on the other hand, the coefficients of the vector are understood to be the coefficients of the power series starting from the constant term (as in Polrev(x)), and the precision d is ignored: in other words, in this case, we convert t_VEC / t_COL to the power series whose significant terms are exactly given by the vector entries. Finally, if s is already a power series in v, we return it verbatim, ignoring d again. If d significant terms are desired in the last two cases, convert/truncate to t_POL first.

? v = [1,2,3]; Ser(v, t, 7)
%5 = 1 + 2*t + 3*t^2 + O(t^3) \\ 3 terms: 7 is ignored!
? Ser(Polrev(v,t), t, 7)
%6 = 1 + 2*t + 3*t^2 + O(t^7)
? s = 1+x+O(x^2); Ser(s, x, 7)
%7 = 1 + x + O(x^2) \\ 2 terms: 7 ignored
? Ser(truncate(s), x, 7)
%8 = 1 + x + O(x^7)

The warning given for Pol also applies here: this is not a substitution function.

Set(x)

Converts x into a set, i.e. into a row vector, with strictly increasing entries with respect to the (somewhat arbitrary) universal comparison function cmp. Standard container types t_VEC, t_COL, t_LIST and t_VECSMALL are converted to the set with corresponding elements. All others are converted to a set with one element.

? Set([1,2,4,2,1,3])
%1 = [1, 2, 3, 4]
? Set(x)
%2 = [x]
? Set(Vecsmall([1,3,2,1,3]))
%3 = [1, 2, 3]
Strchr(x)

Converts x to a string, translating each integer into a character.

? Strchr(97)
%1 = "a"
? Vecsmall("hello world")
%2 = Vecsmall([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100])
? Strchr(%)
%3 = "hello world"
Vec(x, n=0)

Transforms the object x into a row vector. The dimension of the resulting vector can be optionally specified via the extra parameter n.

If n is omitted or 0, the dimension depends on the type of x; the vector has a single component, except when x is

  • a vector or a quadratic form (in which case the resulting vector is simply the initial object considered as a row vector),
  • a polynomial or a power series. In the case of a polynomial, the coefficients of the vector start with the leading coefficient of the polynomial, while for power series only the significant coefficients are taken into account, but this time by increasing order of degree. In this last case, Vec is the reciprocal function of Pol and Ser respectively,
  • a matrix: return the vector of columns comprising the matrix.
  • a character string: return the vector of individual characters.
  • an error context (t_ERROR): return the error components, see iferr.

In the last three cases (matrix, character string, error), n is meaningless and must be omitted or an error is raised. Otherwise, if n is given, 0 entries are appended at the end of the vector if n > 0, and prepended at the beginning if n < 0. The dimension of the resulting vector is \|n\|. Variant: GEN :strong:`gtovec`(GEN x) is also available.

Vecrev(x, n=0)

As Vec(x, -n), then reverse the result. In particular, Vecrev is the reciprocal function of Polrev: the coefficients of the vector start with the constant coefficient of the polynomial and the others follow by increasing degree.

Vecsmall(x, n=0)

Transforms the object x into a row vector of type t_VECSMALL. The dimension of the resulting vector can be optionally specified via the extra parameter n.

This acts as Vec(x,n), but only on a limited set of objects: the result must be representable as a vector of small integers. If x is a character string, a vector of individual characters in ASCII encoding is returned (Strchr yields back the character string).

abs(x, precision=0)

Absolute value of x (modulus if x is complex). Rational functions are not allowed. Contrary to most transcendental functions, an exact argument is not converted to a real number before applying abs and an exact result is returned if possible.

? abs(-1)
%1 = 1
? abs(3/7 + 4/7*I)
%2 = 5/7
? abs(1 + I)
%3 = 1.414213562373095048801688724

If x is a polynomial, returns -x if the leading coefficient is real and negative else returns x. For a power series, the constant coefficient is considered instead.

acos(x, precision=0)

Principal branch of {cos}^{-1}(x) = -i \log (x + i\sqrt{1-x^2}). In particular, {Re(acos}(x)) belongs to [0,\Pi] and if x belongs to \mathbb{R} and \|x\| > 1, then {acos}(x) is complex. The branch cut is in two pieces: ]- oo ,-1] , continuous with quadrant II, and [1,+ oo [, continuous with quadrant IV. We have {acos}(x) = \Pi/2 - {asin}(x) for all x.

acosh(x, precision=0)

Principal branch of {cosh}^{-1}(x) = 2
\log(\sqrt{(x+1)/2} + \sqrt{(x-1)/2}). In particular, {Re}({acosh}(x)) >= 0 and {In}({acosh}(x)) belongs to ]-\Pi,\Pi]0; if x belongs to \mathbb{R} and x < 1, then {acosh}(x) is complex.

addprimes(x)

Adds the integers contained in the vector x (or the single integer x) to a special table of “user-defined primes”, and returns that table. Whenever factor is subsequently called, it will trial divide by the elements in this table. If x is empty or omitted, just returns the current list of extra primes.

The entries in x must be primes: there is no internal check, even if the factor_proven default is set. To remove primes from the list use removeprimes.

agm(x, y, precision=0)

Arithmetic-geometric mean of x and y. In the case of complex or negative numbers, the optimal AGM is returned (the largest in absolute value over all choices of the signs of the square roots). p-adic or power series arguments are also allowed. Note that a p-adic agm exists only if x/y is congruent to 1 modulo p (modulo 16 for p = 2). x and y cannot both be vectors or matrices.

algabsdim(al)

Given an algebra al output by alginit or by algtableinit, returns the dimension of al over its prime subfield (\mathbb{Q} or \mathbb{F}_p).

? nf = nfinit(y^3-y+1);
? A = alginit(nf, [-1,-1]);
? algabsdim(A)
%3 = 12
algadd(al, x, y)

Given two elements x and y in al, computes their sum x+y in the algebra al.

? A = alginit(nfinit(y),[-1,1]);
? algadd(A,[1,0]~,[1,2]~)
%2 = [2, 2]~

Also accepts matrices with coefficients in al.

algalgtobasis(al, x)

Given an element x in the central simple algebra al output by alginit, transforms it to a column vector on the integral basis of al. This is the inverse function of algbasistoalg.

? A = alginit(nfinit(y^2-5),[2,y]);
? algalgtobasis(A,[y,1]~)
%2 = [0, 2, 0, -1, 2, 0, 0, 0]~
? algbasistoalg(A,algalgtobasis(A,[y,1]~))
%3 = [Mod(Mod(y, y^2 - 5), x^2 - 2), 1]~
algaut(al)

Given a cyclic algebra al = (L/K,\sigma,b) output by alginit, returns the automorphism \sigma.

? nf = nfinit(y);
? p = idealprimedec(nf,7)[1];
? p2 = idealprimedec(nf,11)[1];
? A = alginit(nf,[3,[[p,p2],[1/3,2/3]],[0]]);
? algaut(A)
%5 = -1/3*x^2 + 1/3*x + 26/3
algb(al)

Given a cyclic algebra al = (L/K,\sigma,b) output by alginit, returns the element b belongs to K.

nf = nfinit(y);
? p = idealprimedec(nf,7)[1];
? p2 = idealprimedec(nf,11)[1];
? A = alginit(nf,[3,[[p,p2],[1/3,2/3]],[0]]);
? algb(A)
%5 = Mod(-77, y)
algbasis(al)

Given an central simple algebra al output by alginit, returns a \mathbb{Z}-basis of the order {\\cal O}_0 stored in al with respect to the natural order in al. It is a maximal order if one has been computed.

A = alginit(nfinit(y), [-1,-1]);
? algbasis(A)
%2 =
[1 0 0 1/2]

[0 1 0 1/2]

[0 0 1 1/2]

[0 0 0 1/2]
algbasistoalg(al, x)

Given an element x in the central simple algebra al output by alginit, transforms it to its algebraic representation in al. This is the inverse function of algalgtobasis.

? A = alginit(nfinit(y^2-5),[2,y]);
? z = algbasistoalg(A,[0,1,0,0,2,-3,0,0]~);
? liftall(z)
%3 = [(-1/2*y - 2)*x + (-1/4*y + 5/4), -3/4*y + 7/4]~
? algalgtobasis(A,z)
%4 = [0, 1, 0, 0, 2, -3, 0, 0]~
algcenter(al)

If al is a table algebra output by algtableinit, returns a basis of the center of the algebra al over its prime field (\mathbb{Q} or \mathbb{F}_p). If al is a central simple algebra output by alginit, returns the center of al, which is stored in al.

A simple example: the 2 x 2 upper triangular matrices over \mathbb{Q}, generated by I_2, a = [0,1;0,0] and b = [0,0;0,1], such that a^2 = 0, ab = a, ba = 0, b^2 = b: the diagonal matrices for the center.

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? A = algtableinit(mt);
? algcenter(A) \\ = (I_2)
%3 =
[1]

[0]

[0]

An example in the central simple case:

? nf = nfinit(y^3-y+1);
? A = alginit(nf, [-1,-1]);
? algcenter(A).pol
%3 = y^3 - y + 1
algcentralproj(al, z, maps=0)

Given a table algebra al output by algtableinit and a t_VEC z = [z_1,...,z_n] of orthogonal central idempotents, returns a t_VEC [al_1,...,al_n] of algebras such that al_i = z_i al. If maps = 1, each al_i is a t_VEC [quo,proj,lift] where quo is the quotient algebra, proj is a t_MAT representing the projection onto this quotient and lift is a t_MAT representing a lift.

A simple example: \mathbb{F}_2\oplus \mathbb{F}_4, generated by 1 = (1,1), e = (1,0) and x such that x^2+x+1 = 0. We have e^2 = e, x^2 = x+1 and ex = 0.

? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2);
? e = [0,1,0]~;
? e2 = algsub(A,[1,0,0]~,e);
? [a,a2] = algcentralproj(A,[e,e2]);
? algdim(a)
%6 = 1
? algdim(a2)
%7 = 2
algchar(al)

Given an algebra al output by alginit or algtableinit, returns the characteristic of al.

? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,13);
? algchar(A)
%3 = 13
algcharpoly(al, b, v=None)

Given an element b in al, returns its characteristic polynomial as a polynomial in the variable v. If al is a table algebra output by algtableinit, returns the absolute characteristic polynomial of b, which is an element of \mathbb{F}_p[v] or \mathbb{Q}[v]; if al is a central simple algebra output by alginit, returns the reduced characteristic polynomial of b, which is an element of K[v] where K is the center of al.

? al = alginit(nfinit(y), [-1,-1]); \\ (-1,-1)_Q
? algcharpoly(al, [0,1]~)
%2 = x^2 + 1

Also accepts a square matrix with coefficients in al.

algdecomposition(al)

al being a table algebra output by algtableinit, returns [J,[al_1,...,al_n]] where J is a basis of the Jacobson radical of al and al_1,...,al_n are the simple factors of the semisimple algebra al/J.

algdegree(al)

Given a central simple algebra al output by alginit, returns the degree of al.

? nf = nfinit(y^3-y+1);
? A = alginit(nf, [-1,-1]);
? algdegree(A)
%3 = 2
algdep(x, k, flag=0)

x being real/complex, or p-adic, finds a polynomial of degree at most k with integer coefficients having x as approximate root. Note that the polynomial which is obtained is not necessarily the “correct” one. In fact it is not even guaranteed to be irreducible. One can check the closeness either by a polynomial evaluation (use subst), or by computing the roots of the polynomial given by algdep (use polroots).

Internally, lindep([1,x,...,x^k], flag) is used. A non-zero value of flag may improve on the default behavior if the input number is known to a huge accuracy, and you suspect the last bits are incorrect (this truncates the number, throwing away the least significant bits), but default values are usually sufficient:

? \p200
? algdep(2^(1/6)+3^(1/5), 30); \\ wrong in 0.8s
? algdep(2^(1/6)+3^(1/5), 30, 100); \\ wrong in 0.4s
? algdep(2^(1/6)+3^(1/5), 30, 170); \\ right in 0.8s
? algdep(2^(1/6)+3^(1/5), 30, 200); \\ wrong in 1.0s
? \p250
? algdep(2^(1/6)+3^(1/5), 30); \\ right in 1.0s
? algdep(2^(1/6)+3^(1/5), 30, 200); \\ right in 1.0s
? \p500
? algdep(2^(1/6)+3^(1/5), 30); \\ right in 2.9s
? \p1000
? algdep(2^(1/6)+3^(1/5), 30); \\ right in 10.6s

The changes in defaultprecision only affect the quality of the initial approximation to 2^{1/6} + 3^{1/5}, algdep itself uses exact operations (the size of its operands depend on the accuracy of the input of course: more accurate input means slower operations).

Proceeding by increments of 5 digits of accuracy, algdep with default flag produces its first correct result at 205 digits, and from then on a steady stream of correct results.

The above example is the test case studied in a 2000 paper by Borwein and Lisonek: Applications of integer relation algorithms, Discrete Math., 217, p. 65–82. The version of PARI tested there was 1.39, which succeeded reliably from precision 265 on, in about 200 as much time as the current version.

algdim(al)

Given a central simple algebra al output by alginit, returns the dimension of al over its center. Given a table algebra al output by algtableinit, returns the dimension of al over its prime subfield (\mathbb{Q} or \mathbb{F}_p).

? nf = nfinit(y^3-y+1);
? A = alginit(nf, [-1,-1]);
? algdim(A)
%3 = 4
algdisc(al)

Given a central simple algebra al output by alginit, computes the discriminant of the order {\\cal O}_0 stored in al, that is the determinant of the trace form \\rm{Tr} : {\\cal O}_0 x {\\cal O}_0 \\to \mathbb{Z}.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-3,1-y]);
? [PR,h] = alghassef(A);
%3 = [[[2, [2, 0]~, 1, 2, 1], [3, [3, 0]~, 1, 2, 1]], Vecsmall([0, 1])]
? n = algdegree(A);
? D = algabsdim(A);
? h = vector(#h, i, n - gcd(n,h[i]));
? n^D * nf.disc^(n^2) * idealnorm(nf, idealfactorback(nf,PR,h))^n
%4 = 12960000
? algdisc(A)
%5 = 12960000
algdivl(al, x, y)

Given two elements x and y in al, computes their left quotient x\\y in the algebra al: an element z such that xz = y (such an element is not unique when x is a zerodivisor). If x is invertible, this is the same as x^{-1}y. Assumes that y is left divisible by x (i.e. that z exists). Also accepts matrices with coefficients in al.

algdivr(al, x, y)

Given two elements x and y in al, return xy^{-1}. Also accepts matrices with coefficients in al.

alghasse(al, pl)

Given a central simple algebra al output by alginit and a prime ideal or an integer between 1 and r_1+r_2, returns a t_FRAC h : the local Hasse invariant of al at the place specified by pl.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? alghasse(A, 1)
%3 = 1/2
? alghasse(A, 2)
%4 = 0
? alghasse(A, idealprimedec(nf,2)[1])
%5 = 1/2
? alghasse(A, idealprimedec(nf,5)[1])
%6 = 0
alghassef(al)

Given a central simple algebra al output by alginit, returns a t_VEC [PR, h_f] describing the local Hasse invariants at the finite places of the center: PR is a t_VEC of primes and h_f is a t_VECSMALL of integers modulo the degree d of al.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,2*y-1]);
? [PR,hf] = alghassef(A);
? PR
%4 = [[19, [10, 2]~, 1, 1, [-8, 2; 2, -10]], [2, [2, 0]~, 1, 2, 1]]
? hf
%5 = Vecsmall([1, 0])
alghassei(al)

Given a central simple algebra al output by alginit, returns a t_VECSMALL h_i of r_1 integers modulo the degree d of al, where r_1 is the number of real places of the center: the local Hasse invariants of al at infinite places.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? alghassei(A)
%3 = Vecsmall([1, 0])
algindex(al, pl=None)

Return the index of the central simple algebra A over K (as output by alginit), that is the degree e of the unique central division algebra D over K such that A is isomorphic to some matrix algebra M_d(D). If pl is set, it should be a prime ideal of K or an integer between 1 and r_1+r_2, and in that case return the local index at the place pl instead.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? algindex(A, 1)
%3 = 2
? algindex(A, 2)
%4 = 1
? algindex(A, idealprimedec(nf,2)[1])
%5 = 2
? algindex(A, idealprimedec(nf,5)[1])
%6 = 1
? algindex(A)
%7 = 2
alginit(B, C, v=None, flag=1)

Initialize the central simple algebra defined by data B, C and variable v, as follows.

  • (multiplication table) B is the base number field K in nfinit form, C is a “multiplication table” over K. As a K-vector space, the algebra is generated by a basis (e_1 = 1,..., e_n); the table is given as a t_VEC of n matrices in M_n(K), giving the left multiplication by the basis elements e_i, in the given basis. Assumes that e_1 = 1, that the multiplication table is integral, and that K[e_1,...,e_n] describes a central simple algebra over K; v and flag are ignored.
{ m_i = [0,-1,0, 0;
 1, 0,0, 0;
 0, 0,0,-1;
 0, 0,1, 0];
 m_j = [0, 0,-1,0;
 0, 0, 0,1;
 1, 0, 0,0;
 0,-1, 0,0];
 m_k = [0, 0, 0, 0;
 0, 0,-1, 0;
 0, 1, 0, 0;
 1, 0, 0,-1];
 A = alginit(nfinit(y), [matid(4), m_i,m_j,m_k], 0); }

represents (in a complicated way) the quaternion algebra (-1,-1)_\mathbb{Q}. See below for a simpler solution.

  • (cyclic algebra) B is an rnf structure associated with a cyclic number field extension L/K of degree d, C is a t_VEC [sigma,b] with 2 components: sigma is a t_POLMOD representing an automorphism generating {Gal}(L/K), b is an element in K^*. This represents the cyclic algebra (L/K,\sigma,b). Currently the element b has to be integral.
? Q = nfinit(y); T = polcyclo(5, 'x); F = rnfinit(Q, T);
? A = alginit(F, [Mod(x^2,T), 3]);

defines the cyclic algebra (L/\mathbb{Q}, \sigma, 3), where L = \mathbb{Q}(\zeta_5) and \sigma:\zeta:--->\zeta^2 generates {Gal}(L/\mathbb{Q}).

  • (quaternion algebra, special case of the above) B is an nf structure associated with a number field K, C = [a,b] is a vector containing two elements of K^* with a not a square in K, returns the quaternion algebra (a,b)_K. The variable v ('x by default) must have higher priority than the variable of K.pol and is used to represent elements in the splitting field L = K[x]/(x^2-a).
? Q = nfinit(y); A = alginit(Q, [-1,-1]); \\ (-1,-1)_Q
  • (algebra/K defined by local Hasse invariants) B is an nf structure associated with a number field K, C = [d, [PR,h_f], h_i] is a triple containing an integer d > 1, a pair [PR, h_f] describing the Hasse invariants at finite places, and h_i the Hasse invariants at archimedean (real) places. A local Hasse invariant belongs to (1/d)\mathbb{Z}/\mathbb{Z}
\subset \mathbb{Q}/\mathbb{Z}, and is given either as a t_FRAC (lift to (1/d)\mathbb{Z}), a t_INT or t_INTMOD modulo d (lift to \mathbb{Z}/d\mathbb{Z}); a whole vector of local invariants can also be given as a t_VECSMALL, whose entries are handled as t_INT s. PR is a list of prime ideals (prid structures), and h_f is a vector of the same length giving the local invariants at those maximal ideals. The invariants at infinite real places are indexed by the real roots K.roots: if the Archimedean place v is associated with the j-th root, the value of h_v is given by h_i[j], must be 0 or 1/2 (or d/2 modulo d), and can be nonzero only if d is even.

By class field theory, provided the local invariants h_v sum to 0, up to Brauer equivalence, there is a unique central simple algebra over K with given local invariants and trivial invariant elsewhere. In particular, up to isomorphism, there is a unique such algebra A of degree d.

We realize A as a cyclic algebra through class field theory. The variable v ('x by default) must have higher priority than the variable of K.pol and is used to represent elements in the (cyclic) splitting field extension L/K for A.

? nf = nfinit(y^2+1);
? PR = idealprimedec(nf,5); #PR
%2 = 2
? hi = [];
? hf = [PR, [1/3,-1/3]];
? A = alginit(nf, [3,hf,hi]);
? algsplittingfield(A).pol
%6 = x^3 - 21*x + 7
  • (matrix algebra, toy example) B is an nf structure associated to a number field K, C = d is a positive integer. Returns a cyclic algebra isomorphic to the matrix algebra M_d(K).

In all cases, this function computes a maximal order for the algebra by default, which may require a lot of time. Setting flag = 0 prevents this computation.

The pari object representing such an algebra A is a t_VEC with the following data:

  • A splitting field L of A of the same degree over K as A, in rnfinit format, accessed with algsplittingfield.
  • The same splitting field L in nfinit format.
  • The Hasse invariants at the real places of K, accessed with alghassei.
  • The Hasse invariants of A at the finite primes of K that ramify in the natural order of A, accessed with alghassef.
  • A basis of an order {\\cal O}_0 expressed on the basis of the natural order, accessed with algord.
  • A basis of the natural order expressed on the basis of {\\cal O}_0, accessed with alginvord.
  • The left multiplication table of {\\cal O}_0 on the previous basis, accessed with algmultable.
  • The characteristic of A (always 0), accessed with algchar.
  • The absolute traces of the elements of the basis of {\\cal O}_0.
  • If A was constructed as a cyclic algebra (L/K,\sigma,b) of degree d, a t_VEC [\sigma,\sigma^2,...,\sigma^{d-1}]. The function algaut returns \sigma.
  • If A was constructed as a cyclic algebra (L/K,\sigma,b), the element b, accessed with algb.
  • If A was constructed with its multiplication table mt over K, the t_VEC of t_MAT mt, accessed with algrelmultable.
  • If A was constructed with its multiplication table mt over K, a t_VEC with three components: a t_COL representing an element of A generating the splitting field L as a maximal subfield of A, a t_MAT representing an L-basis {\cal B} of A expressed on the \mathbb{Z}-basis of {\cal O}_0, and a t_MAT representing the \mathbb{Z}-basis of {\cal O}_0 expressed on {\cal B}. This data is accessed with algsplittingdata.
alginv(al, x)

Given an element x in al, computes its inverse x^{-1} in the algebra al. Assumes that x is invertible.

? A = alginit(nfinit(y), [-1,-1]);
? alginv(A,[1,1,0,0]~)
%2 = [1/2, 1/2, 0, 0]~

Also accepts matrices with coefficients in al.

alginvbasis(al)

Given an central simple algebra al output by alginit, returns a \mathbb{Z}-basis of the natural order in al with respect to the order {\\cal
O}_0 stored in al.

A = alginit(nfinit(y), [-1,-1]);
? alginvbasis(A)
%2 =
[1 0 0 -1]

[0 1 0 -1]

[0 0 1 -1]

[0 0 0 2]
algisassociative(mt, p=None)

Returns 1 if the multiplication table mt is suitable for algtableinit(mt,p), 0 otherwise. More precisely, mt should be a t_VEC of n matrices in M_n(K), giving the left multiplications by the basis elements e_1,..., e_n (structure constants). We check whether the first basis element e_1 is 1 and e_i(e_je_k) = 
(e_ie_j)e_k for all i,j,k.

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? algisassociative(mt)
%2 = 1

May be used to check a posteriori an algebra: we also allow mt as output by algtableinit (p is ignored in this case).

algiscommutative(al)

al being a table algebra output by algtableinit or a central simple algebra output by alginit, tests whether the algebra al is commutative.

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? A = algtableinit(mt);
? algiscommutative(A)
%3 = 0
? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2);
? algiscommutative(A)
%6 = 1
algisdivision(al, pl=None)

Given a central simple algebra al output by alginit, test whether al is a division algebra. If pl is set, it should be a prime ideal of K or an integer between 1 and r_1+r_2, and in that case test whether al is locally a division algebra at the place pl instead.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? algisdivision(A, 1)
%3 = 1
? algisdivision(A, 2)
%4 = 0
? algisdivision(A, idealprimedec(nf,2)[1])
%5 = 1
? algisdivision(A, idealprimedec(nf,5)[1])
%6 = 0
? algisdivision(A)
%7 = 1
algisramified(al, pl=None)

Given a central simple algebra al output by alginit, test whether al is ramified, i.e. not isomorphic to a matrix algebra over its center. If pl is set, it should be a prime ideal of K or an integer between 1 and r_1+r_2, and in that case test whether al is locally ramified at the place pl instead.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? algisramified(A, 1)
%3 = 1
? algisramified(A, 2)
%4 = 0
? algisramified(A, idealprimedec(nf,2)[1])
%5 = 1
? algisramified(A, idealprimedec(nf,5)[1])
%6 = 0
? algisramified(A)
%7 = 1
algissemisimple(al)

al being a table algebra output by algtableinit or a central simple algebra output by alginit, tests whether the algebra al is semisimple.

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? A = algtableinit(mt);
? algissemisimple(A)
%3 = 0
? m_i=[0,-1,0,0;1,0,0,0;0,0,0,-1;0,0,1,0]; \\quaternion algebra (-1,-1)
? m_j=[0,0,-1,0;0,0,0,1;1,0,0,0;0,-1,0,0];
? m_k=[0,0,0,-1;0,0,-1,0;0,1,0,0;1,0,0,0];
? mt = [matid(4), m_i, m_j, m_k];
? A = algtableinit(mt);
? algissemisimple(A)
%9 = 1
algissimple(al, ss=0)

al being a table algebra output by algtableinit or a central simple algebra output by alginit, tests whether the algebra al is simple. If ss = 1, assumes that the algebra al is semisimple without testing it.

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? A = algtableinit(mt); \\ matrices [*,*; 0,*]
? algissimple(A)
%3 = 0
? algissimple(A,1) \\ incorrectly assume that A is semisimple
%4 = 1
? m_i=[0,-1,0,0;1,0,0,0;0,0,0,-1;0,0,1,0];
? m_j=[0,0,-1,0;0,0,0,1;1,0,0,0;0,-1,0,0];
? m_k=[0,0,0,-1;0,0,b,0;0,1,0,0;1,0,0,0];
? mt = [matid(4), m_i, m_j, m_k];
? A = algtableinit(mt); \\ quaternion algebra (-1,-1)
? algissimple(A)
%10 = 1
? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2); \\ direct sum F_4+F_2
? algissimple(A)
%13 = 0
algissplit(al, pl=None)

Given a central simple algebra al output by alginit, test whether al is split, i.e. isomorphic to a matrix algebra over its center. If pl is set, it should be a prime ideal of K or an integer between 1 and r_1+r_2, and in that case test whether al is locally split at the place pl instead.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? algissplit(A, 1)
%3 = 0
? algissplit(A, 2)
%4 = 1
? algissplit(A, idealprimedec(nf,2)[1])
%5 = 0
? algissplit(A, idealprimedec(nf,5)[1])
%6 = 1
? algissplit(A)
%7 = 0
algmul(al, x, y)

Given two elements x and y in al, computes their product x*y in the algebra al.

? A = alginit(nfinit(y), [-1,-1]);
? algmul(A,[1,1,0,0]~,[0,0,2,1]~)
%2 = [2, 3, 5, -4]~

Also accepts matrices with coefficients in al.

algmultable(al, x=None)

Given an element x in al, computes its left multiplication table. If x is given in basis form, returns its multiplication table on the integral basis; if x is given in algebraic form, returns its multiplication table on the basis corresponding to the algebraic form of elements of al. In every case, if x is a t_COL of length n, then the output is a n x n t_MAT. Also accepts a square matrix with coefficients in al.

If x is not set, returns a multiplication table of al over its prime subfield (\mathbb{Q} or \mathbb{F}_p), as a t_VEC of t_MAT: the left multiplication tables of basis elements. If al was output by algtableinit, returns the multiplication table used to define al. If al was output by alginit, returns the multiplication table of the order {\\cal O}_0 stored in al.

? A = alginit(nfinit(y), [-1,-1]);
? algmultable(A,[0,1,0,0]~)
%2 =
[0 -1 1 0]

[1 0 1 1]

[0 0 1 1]

[0 0 -2 -1]

Another example:

? A = alginit(nfinit(y), [-1,-1]);
? M = algmultable(A);
? #M
%3 = 4
? M[1]
%4 =
[1 0 0 0]

[0 1 0 0]

[0 0 1 0]

[0 0 0 1]

? M[2]
%5 =
[0 -1 1 0]

[1 0 1 1]

[0 0 1 1]

[0 0 -2 -1]
algneg(al, x)

Given an element x in al, computes its opposite -x in the algebra al.

? A = alginit(nfinit(y), [-1,-1]);
? algneg(A,[1,1,0,0]~)
%2 = [-1, -1, 0, 0]~

Also accepts matrices with coefficients in al.

algnorm(al, x)

Given an element x in al, computes its norm. If al is a table algebra output by algtableinit, returns the absolute norm of x, which is an element of \mathbb{F}_p of \mathbb{Q}; if al is a central simple algebra output by alginit, returns the reduced norm of x, which is an element of the center of al.

? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,19);
? algnorm(A,[0,-2,3]~)
%3 = 18

Also accepts a square matrix with coefficients in al.

algpoleval(al, T, b)

Given an element b in al and a polynomial T in K[X], computes T(b) in al.

algpow(al, x, n)

Given an element x in al and an integer n, computes the power x^n in the algebra al.

? A = alginit(nfinit(y), [-1,-1]);
? algpow(A,[1,1,0,0]~,7)
%2 = [8, -8, 0, 0]~

Also accepts a square matrix with coefficients in al.

algprimesubalg(al)

al being the output of algtableinit representing a semisimple algebra of positive characteristic, returns a basis of the prime subalgebra of al. The prime subalgebra of al is the subalgebra fixed by the Frobenius automorphism of the center of al. It is abstractly isomorphic to a product of copies of \mathbb{F}_p.

? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2);
? algprimesubalg(A)
%3 =
[1 0]

[0 1]

[0 0]
algquotient(al, I, flag=0)

al being a table algebra output by algtableinit and I being a basis of a two-sided ideal of al represented by a matrix, returns the quotient al/I. When flag = 1, returns a t_VEC [al/I,proj,lift] where proj and lift are matrices respectively representing the projection map and a section of it.

? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2);
? AQ = algquotient(A,[0;1;0]);
? algdim(AQ)
%4 = 2
algradical(al)

al being a table algebra output by algtableinit, returns a basis of the Jacobson radical of the algebra al over its prime field (\mathbb{Q} or \mathbb{F}_p).

Here is an example with A = \mathbb{Q}[x]/(x^2), generated by (1,x):

? mt = [matid(2),[0,0;1,0]];
? A = algtableinit(mt);
? algradical(A) \\ = (x)
%3 =
[0]

[1]

Another one with 2 x 2 upper triangular matrices over \mathbb{Q}, generated by I_2, a = [0,1;0,0] and b = [0,0;0,1], such that a^2 = 
0, ab = a, ba = 0, b^2 = b:

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? A = algtableinit(mt);
? algradical(A) \\ = (a)
%6 =
[0]

[1]

[0]
algramifiedplaces(al)

Given a central simple algebra al output by alginit, return a t_VEC containing the list of places of the center of al that are ramified in al. Each place is described as an integer between 1 and r_1 or as a prime ideal.

? nf = nfinit(y^2-5);
? A = alginit(nf, [-1,y]);
? algramifiedplaces(A)
%3 = [1, [2, [2, 0]~, 1, 2, 1]]
algrandom(al, b)

Given an algebra al and an integer b, returns a random element in al with coefficients in [-b,b].

algrelmultable(al)

Given a central simple algebra al output by alginit defined by a multiplication table over its center (a number field), returns this multiplication table.

? nf = nfinit(y^3-5); a = y; b = y^2;
? {m_i = [0,a,0,0;
 1,0,0,0;
 0,0,0,a;
 0,0,1,0];}
? {m_j = [0, 0,b, 0;
 0, 0,0,-b;
 1, 0,0, 0;
 0,-1,0, 0];}
? {m_k = [0, 0,0,-a*b;
 0, 0,b, 0;
 0,-a,0, 0;
 1, 0,0, 0];}
? mt = [matid(4), m_i, m_j, m_k];
? A = alginit(nf,mt,'x);
? M = algrelmultable(A);
? M[2] == m_i
%8 = 1
? M[3] == m_j
%9 = 1
? M[4] == m_k
%10 = 1
algsimpledec(al, flag=0)

al being the output of algtableinit representing a semisimple algebra, returns a t_VEC [al_1,al_2,...,al_n] such that al is isomorphic to the direct sum of the simple algebras al_i. When flag = 1, each component is instead a t_VEC [al_i,proj_i,lift_i] where proj_i and lift_i are matrices respectively representing the projection map on the i-th factor and a section of it.

Warning. The images of the lift_i are not guaranteed to form a direct sum.

algsplittingdata(al)

Given a central simple algebra al output by alginit defined by a multiplication table over its center K (a number field), returns data stored to compute a splitting of al over an extension. This data is a t_VEC [t,Lbas,Lbasinv] with 3 components:

  • an element t of al such that L = K(t) is a maximal subfield of al;
  • a matrix Lbas expressing a L-basis of al (given an L-vector space structure by multiplication on the right) on the integral basis of al;
  • a matrix Lbasinv expressing the integral basis of al on the previous L-basis.
? nf = nfinit(y^3-5); a = y; b = y^2;
? {m_i = [0,a,0,0;
 1,0,0,0;
 0,0,0,a;
 0,0,1,0];}
? {m_j = [0, 0,b, 0;
 0, 0,0,-b;
 1, 0,0, 0;
 0,-1,0, 0];}
? {m_k = [0, 0,0,-a*b;
 0, 0,b, 0;
 0,-a,0, 0;
 1, 0,0, 0];}
? mt = [matid(4), m_i, m_j, m_k];
? A = alginit(nf,mt,'x);
? [t,Lb,Lbi] = algsplittingdata(A);
? t
%8 = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]~;
? matsize(Lb)
%9 = [12, 2]
? matsize(Lbi)
%10 = [2, 12]
algsplittingfield(al)

Given a central simple algebra al output by alginit, returns an rnf structure: the splitting field of al that is stored in al, as a relative extension of the center.

nf = nfinit(y^3-5);
a = y; b = y^2;
{m_i = [0,a,0,0;
 1,0,0,0;
 0,0,0,a;
 0,0,1,0];}
{m_j = [0, 0,b, 0;
 0, 0,0,-b;
 1, 0,0, 0;
 0,-1,0, 0];}
{m_k = [0, 0,0,-a*b;
 0, 0,b, 0;
 0,-a,0, 0;
 1, 0,0, 0];}
mt = [matid(4), m_i, m_j, m_k];
A = alginit(nf,mt,'x);
algsplittingfield(A).pol
%8 = x^2 - y
algsplittingmatrix(al, x)

A central simple algebra al output by alginit contains data describing an isomorphism \phi : A\\otimes_K L \\to M_d(L), where d is the degree of the algebra and L is an extension of L with [L:K] = d. Returns the matrix \phi(x).

? A = alginit(nfinit(y), [-1,-1]);
? algsplittingmatrix(A,[0,0,0,2]~)
%2 =
[Mod(x + 1, x^2 + 1) Mod(Mod(1, y)*x + Mod(-1, y), x^2 + 1)]

[Mod(x + 1, x^2 + 1) Mod(-x + 1, x^2 + 1)]

Also accepts matrices with coefficients in al.

algsqr(al, x)

Given an element x in al, computes its square x^2 in the algebra al.

? A = alginit(nfinit(y), [-1,-1]);
? algsqr(A,[1,0,2,0]~)
%2 = [-3, 0, 4, 0]~

Also accepts a square matrix with coefficients in al.

algsub(al, x, y)

Given two elements x and y in al, computes their difference x-y in the algebra al.

? A = alginit(nfinit(y), [-1,-1]);
? algsub(A,[1,1,0,0]~,[1,0,1,0]~)
%2 = [0, 1, -1, 0]~

Also accepts matrices with coefficients in al.

algsubalg(al, B)

al being a table algebra output by algtableinit and B being a basis of a subalgebra of al represented by a matrix, returns an algebra isomorphic to B.

? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2);
? B = algsubalg(A,[1,0; 0,0; 0,1]);
? algdim(A)
%4 = 3
? algdim(B)
%5 = 2
algtableinit(mt, p=None)

Initialize the associative algebra over K = \mathbb{Q} (p omitted) or \mathbb{F}_p defined by the multiplication table mt. As a K-vector space, the algebra is generated by a basis (e_1 = 1, e_2,..., e_n); the table is given as a t_VEC of n matrices in M_n(K), giving the left multiplication by the basis elements e_i, in the given basis. Assumes that e_1 = 1, that K e_1\oplus...\oplus K e_n] describes an associative algebra over K, and in the case K = \mathbb{Q} that the multiplication table is integral. If the algebra is already known to be central and simple, then the case K = \mathbb{F}_p is useless, and one should use alginit directly.

The point of this function is to input a finite dimensional K-algebra, so as to later compute its radical, then to split the quotient algebra as a product of simple algebras over K.

The pari object representing such an algebra A is a t_VEC with the following data:

  • The characteristic of A, accessed with algchar.
  • The multiplication table of A, accessed with algmultable.
  • The traces of the elements of the basis.

A simple example: the 2 x 2 upper triangular matrices over \mathbb{Q}, generated by I_2, a = [0,1;0,0] and b = [0,0;0,1], such that a^2 = 0, ab = a, ba = 0, b^2 = b:

? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]];
? A = algtableinit(mt);
? algradical(A) \\ = (a)
%6 =
[0]

[1]

[0]
? algcenter(A) \\ = (I_2)
%7 =
[1]

[0]

[0]
algtensor(al1, al2, maxord=1)

Given two algebras al1 and al2, computes their tensor product. For table algebras output by algtableinit, the flag maxord is ignored. For central simple algebras output by alginit, computes a maximal order by default. Prevent this computation by setting maxord = 0.

Currently only implemented for cyclic algebras of coprime degree over the same center K, and the tensor product is over K.

algtrace(al, x)

Given an element x in al, computes its trace. If al is a table algebra output by algtableinit, returns the absolute trace of x, which is an element of \mathbb{F}_p or \mathbb{Q}; if al is the output of alginit, returns the reduced trace of x, which is an element of the center of al.

? A = alginit(nfinit(y), [-1,-1]);
? algtrace(A,[5,0,0,1]~)
%2 = 11

Also accepts a square matrix with coefficients in al.

algtype(al)

Given an algebra al output by alginit or by algtableinit, returns an integer indicating the type of algebra:

  • 0: not a valid algebra.
  • 1: table algebra output by algtableinit.
  • 2: central simple algebra output by alginit and represented by a multiplication table over its center.
  • 3: central simple algebra output by alginit and represented by a cyclic algebra.
? algtype([])
%1 = 0
? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]];
? A = algtableinit(mt,2);
? algtype(A)
%4 = 1
? nf = nfinit(y^3-5);
? a = y; b = y^2;
? {m_i = [0,a,0,0;
 1,0,0,0;
 0,0,0,a;
 0,0,1,0];}
? {m_j = [0, 0,b, 0;
 0, 0,0,-b;
 1, 0,0, 0;
 0,-1,0, 0];}
? {m_k = [0, 0,0,-a*b;
 0, 0,b, 0;
 0,-a,0, 0;
 1, 0,0, 0];}
? mt = [matid(4), m_i, m_j, m_k];
? A = alginit(nf,mt,'x);
? algtype(A)
%12 = 2
? A = alginit(nfinit(y), [-1,-1]);
? algtype(A)
%14 = 3
allocatemem(s)

This special operation changes the stack size after initialization. x must be a non-negative integer. If x > 0, a new stack of at least x bytes is allocated. We may allocate more than x bytes if x is way too small, or for alignment reasons: the current formula is \\max(16*ceil{x/16}, 500032) bytes.

If x = 0, the size of the new stack is twice the size of the old one.

This command is much more useful if parisizemax is non-zero, and we describe this case first. With parisizemax enabled, there are three sizes of interest:

  • a virtual stack size, parisizemax, which is an absolute upper limit for the stack size; this is set by default(parisizemax, ...).
  • the desired typical stack size, parisize, that will grow as needed, up to parisizemax; this is set by default(parisize, ...).
  • the current stack size, which is less that parisizemax, typically equal to parisize but possibly larger and increasing dynamically as needed; allocatemem allows to change that one explicitly.

The allocatemem command forces stack usage to increase temporarily (up to parisizemax of course); for instance if you notice using \gm2 that we seem to collect garbage a lot, e.g.

? \gm2
 debugmem = 2
? default(parisize,"32M")
 *** Warning: new stack size = 32000000 (30.518 Mbytes).
? bnfinit('x^2+10^30-1)
 *** bnfinit: collecting garbage in hnffinal, i = 1.
 *** bnfinit: collecting garbage in hnffinal, i = 2.
 *** bnfinit: collecting garbage in hnffinal, i = 3.

and so on for hundred of lines. Then, provided the breakloop default is set, you can interrupt the computation, type allocatemem(100*10^6) at the break loop prompt, then let the computation go on by typing :literal:` < Enter > . Back at the :literal:`gp prompt, the desired stack size of parisize is restored. Note that changing either parisize or parisizemax at the break loop prompt would interrupt the computation, contrary to the above.

In most cases, parisize will increase automatically (up to parisizemax) and there is no need to perform the above maneuvers. But that the garbage collector is sufficiently efficient that a given computation can still run without increasing the stack size, albeit very slowly due to the frequent garbage collections.

Deprecated: when :literal:`parisizemax. is unset` This is currently still the default behavior in order not to break backward compatibility. The rest of this section documents the behavior of allocatemem in that (deprecated) situation: it becomes a synonym for default(parisize,...). In that case, there is no notion of a virtual stack, and the stack size is always equal to parisize. If more memory is needed, the PARI stack overflows, aborting the computation.

Thus, increasing parisize via allocatemem or default(parisize,...) before a big computation is important. Unfortunately, either must be typed at the gp prompt in interactive usage, or left by itself at the start of batch files. They cannot be used meaningfully in loop-like constructs, or as part of a larger expression sequence, e.g

allocatemem(); x = 1; \\ This will not set x!

In fact, all loops are immediately exited, user functions terminated, and the rest of the sequence following allocatemem() is silently discarded, as well as all pending sequences of instructions. We just go on reading the next instruction sequence from the file we are in (or from the user). In particular, we have the following possibly unexpected behavior: in

read("file.gp"); x = 1

were file.gp contains an allocatemem statement, the x = 1 is never executed, since all pending instructions in the current sequence are discarded.

The reason for these unfortunate side-effects is that, with parisizemax disabled, increasing the stack size physically moves the stack, so temporary objects created during the current expression evaluation are not correct anymore. (In particular byte-compiled expressions, which are allocated on the stack.) To avoid accessing obsolete pointers to the old stack, this routine ends by a longjmp.

apply(f, A)

Apply the t_CLOSURE f to the entries of A. If A is a scalar, return f(A). If A is a polynomial or power series, apply f on all coefficients. If A is a vector or list, return the elements f(x) where x runs through A. If A is a matrix, return the matrix whose entries are the f(A[i,j]).

? apply(x->x^2, [1,2,3,4])
%1 = [1, 4, 9, 16]
? apply(x->x^2, [1,2;3,4])
%2 =
[1 4]

[9 16]
? apply(x->x^2, 4*x^2 + 3*x+ 2)
%3 = 16*x^2 + 9*x + 4

Note that many functions already act componentwise on vectors or matrices, but they almost never act on lists; in this case, apply is a good solution:

? L = List([Mod(1,3), Mod(2,4)]);
? lift(L)
 *** at top-level: lift(L)
 *** ^-------
 *** lift: incorrect type in lift.
? apply(lift, L);
%2 = List([1, 2])

Remark. For v a t_VEC, t_COL, t_LIST or t_MAT, the alternative set-notations

[g(x) | x <- v, f(x)]
[x | x <- v, f(x)]
[g(x) | x <- v]

are available as shortcuts for

apply(g, select(f, Vec(v)))
select(f, Vec(v))
apply(g, Vec(v))

respectively:

? L = List([Mod(1,3), Mod(2,4)]);
? [ lift(x) | x<-L ]
%2 = [1, 2]
arg(x, precision=0)

Argument of the complex number x, such that -\Pi < {arg}(x) <= \Pi.

asin(x, precision=0)

Principal branch of {sin}^{-1}(x) = -i \log(ix + \sqrt{1 - x^2}). In particular, {Re(asin}(x)) belongs to [-\Pi/2,\Pi/2] and if x belongs to \mathbb{R} and \|x\| > 1 then {asin}(x) is complex. The branch cut is in two pieces: ]- oo ,-1], continuous with quadrant II, and [1,+ oo [ continuous with quadrant IV. The function satisfies i {asin}(x) = 
{asinh}(ix).

asinh(x, precision=0)

Principal branch of {sinh}^{-1}(x) = \log(x + \sqrt{1+x^2}). In particular {Im(asinh}(x)) belongs to [-\Pi/2,\Pi/2]. The branch cut is in two pieces: [-i oo ,-i], continuous with quadrant III and [i,+i oo [ continuous with quadrant I.

atan(x, precision=0)

Principal branch of {tan}^{-1}(x) = \log ((1+ix)/(1-ix)) /
2i. In particular the real part of {atan}(x)) belongs to ]-\Pi/2,\Pi/2[. The branch cut is in two pieces: ]-i oo ,-i[, continuous with quadrant IV, and ]i,+i oo [ continuous with quadrant II. The function satisfies i {atan}(x) = 
-i{atanh}(ix) for all x != ± i.

atanh(x, precision=0)

Principal branch of {tanh}^{-1}(x) = log ((1+x)/(1-x)) / 2. In particular the imaginary part of {atanh}(x) belongs to [-\Pi/2,\Pi/2]; if x belongs to \mathbb{R} and \|x\| > 1 then {atanh}(x) is complex.

besselh1(nu, x, precision=0)

H^1-Bessel function of index nu and argument x.

besselh2(nu, x, precision=0)

H^2-Bessel function of index nu and argument x.

besseli(nu, x, precision=0)

I-Bessel function of index nu and argument x. If x converts to a power series, the initial factor (x/2)^\nu/\Gamma(\nu+1) is omitted (since it cannot be represented in PARI when \nu is not integral).

besselj(nu, x, precision=0)

J-Bessel function of index nu and argument x. If x converts to a power series, the initial factor (x/2)^\nu/\Gamma(\nu+1) is omitted (since it cannot be represented in PARI when \nu is not integral).

besseljh(n, x, precision=0)

J-Bessel function of half integral index. More precisely, besseljh(n,x) computes J_{n+1/2}(x) where n must be of type integer, and x is any element of \mathbb{C}. In the present version 2.8.0, this function is not very accurate when x is small.

besselk(nu, x, precision=0)

K-Bessel function of index nu and argument x.

besseln(nu, x, precision=0)

N-Bessel function of index nu and argument x.

bestappr(x, B=None)

Using variants of the extended Euclidean algorithm, returns a rational approximation a/b to x, whose denominator is limited by B, if present. If B is omitted, return the best approximation affordable given the input accuracy; if you are looking for true rational numbers, presumably approximated to sufficient accuracy, you should first try that option. Otherwise, B must be a positive real scalar (impose 0 < b <= B).

  • If x is a t_REAL or a t_FRAC, this function uses continued fractions.
? bestappr(Pi, 100)
%1 = 22/7
? bestappr(0.1428571428571428571428571429)
%2 = 1/7
? bestappr([Pi, sqrt(2) + 'x], 10^3)
%3 = [355/113, x + 1393/985]

By definition, a/b is the best rational approximation to x if \|b x - a\| < \|v x - u\| for all integers (u,v) with 0 < v <= B. (Which implies that n/d is a convergent of the continued fraction of x.)

  • If x is a t_INTMOD modulo N or a t_PADIC of precision N = 
p^k, this function performs rational modular reconstruction modulo N. The routine then returns the unique rational number a/b in coprime integers |a| < N/2B and b <= B which is congruent to x modulo N. Omitting B amounts to choosing it of the order of \sqrt{N/2}. If rational reconstruction is not possible (no suitable a/b exists), returns [].
? bestappr(Mod(18526731858, 11^10))
%1 = 1/7
? bestappr(Mod(18526731858, 11^20))
%2 = []
? bestappr(3 + 5 + 3*5^2 + 5^3 + 3*5^4 + 5^5 + 3*5^6 + O(5^7))
%2 = -1/3

In most concrete uses, B is a prime power and we performed Hensel lifting to obtain x.

The function applies recursively to components of complex objects (polynomials, vectors,...). If rational reconstruction fails for even a single entry, return [].

bestapprPade(x, B=-1)

Using variants of the extended Euclidean algorithm, returns a rational function approximation a/b to x, whose denominator is limited by B, if present. If B is omitted, return the best approximation affordable given the input accuracy; if you are looking for true rational functions, presumably approximated to sufficient accuracy, you should first try that option. Otherwise, B must be a non-negative real (impose 0 <= {degree}(b) <= B).

  • If x is a t_RFRAC or t_SER, this function uses continued fractions.
? bestapprPade((1-x^11)/(1-x)+O(x^11))
%1 = 1/(-x + 1)
? bestapprPade([1/(1+x+O(x^10)), (x^3-2)/(x^3+1)], 1)
%2 = [1/(x + 1), -2]
  • If x is a t_POLMOD modulo N or a t_SER of precision N = 
t^k, this function performs rational modular reconstruction modulo N. The routine then returns the unique rational function a/b in coprime polynomials, with {degree}(b) <= B which is congruent to x modulo N. Omitting B amounts to choosing it of the order of N/2. If rational reconstruction is not possible (no suitable a/b exists), returns [].
? bestapprPade(Mod(1+x+x^2+x^3+x^4, x^4-2))
%1 = (2*x - 1)/(x - 1)
? % * Mod(1,x^4-2)
%2 = Mod(x^3 + x^2 + x + 3, x^4 - 2)
? bestapprPade(Mod(1+x+x^2+x^3+x^5, x^9))
%2 = []
? bestapprPade(Mod(1+x+x^2+x^3+x^5, x^10))
%3 = (2*x^4 + x^3 - x - 1)/(-x^5 + x^3 + x^2 - 1)

The function applies recursively to components of complex objects (polynomials, vectors,...). If rational reconstruction fails for even a single entry, return [].

bezout(x, y)

Deprecated alias for gcdext

bezoutres(A, B, v=None)

Deprecated alias for polresultantext

bigomega(x)

Number of prime divisors of the integer \|x\| counted with multiplicity:

? factor(392)
%1 =
[2 3]

[7 2]

? bigomega(392)
%2 = 5; \\ = 3+2
? omega(392)
%3 = 2; \\ without multiplicity
binary(x)

Outputs the vector of the binary digits of \|x\|. Here x can be an integer, a real number (in which case the result has two components, one for the integer part, one for the fractional part) or a vector/matrix.

binomial(x, y)

binomial coefficient binom{x}{y}. Here y must be an integer, but x can be any PARI object.

bitand(x, y)

Bitwise and of two integers x and y, that is the integer

\sum_i (x_i and y_i) 2^i

Negative numbers behave 2-adically, i.e. the result is the 2-adic limit of bitand(x_n,y_n), where x_n and y_n are non-negative integers tending to x and y respectively. (The result is an ordinary integer, possibly negative.)

? bitand(5, 3)
%1 = 1
? bitand(-5, 3)
%2 = 3
? bitand(-5, -3)
%3 = -7
bitneg(x, n=-1)

bitwise negation of an integer x, truncated to n bits, n >= 0, that is the integer

\sum_{i = 0}^{n-1} not(x_i) 2^i.

The special case n = -1 means no truncation: an infinite sequence of leading 1 is then represented as a negative number.

See bitand (in the PARI manual) for the behavior for negative arguments.

bitnegimply(x, y)

Bitwise negated imply of two integers x and y (or not (x ==> y)), that is the integer

\sum
(x_i and not(y_i)) 2^i

See bitand (in the PARI manual) for the behavior for negative arguments.

bitor(x, y)

bitwise (inclusive) or of two integers x and y, that is the integer

\sum
(x_i or y_i) 2^i

See bitand (in the PARI manual) for the behavior for negative arguments.

bittest(x, n)

Outputs the n-th bit of x starting from the right (i.e. the coefficient of 2^n in the binary expansion of x). The result is 0 or 1.

? bittest(7, 3)
%1 = 1 \\ the 3rd bit is 1
? bittest(7, 4)
%2 = 0 \\ the 4th bit is 0

See bitand (in the PARI manual) for the behavior at negative arguments.

bitxor(x, y)

Bitwise (exclusive) or of two integers x and y, that is the integer

\sum (x_i xor y_i) 2^i

See bitand (in the PARI manual) for the behavior for negative arguments.

bnfcertify(bnf, flag=0)

bnf being as output by bnfinit, checks whether the result is correct, i.e. whether it is possible to remove the assumption of the Generalized Riemann Hypothesis. It is correct if and only if the answer is 1. If it is incorrect, the program may output some error message, or loop indefinitely. You can check its progress by increasing the debug level. The bnf structure must contain the fundamental units:

? K = bnfinit(x^3+2^2^3+1); bnfcertify(K)
 *** at top-level: K=bnfinit(x^3+2^2^3+1);bnfcertify(K)
 *** ^-------------
 *** bnfcertify: missing units in bnf.
? K = bnfinit(x^3+2^2^3+1, 1); \\ include units
? bnfcertify(K)
%3 = 1

If flag is present, only certify that the class group is a quotient of the one computed in bnf (much simpler in general); likewise, the computed units may form a subgroup of the full unit group. In this variant, the units are no longer needed:

? K = bnfinit(x^3+2^2^3+1); bnfcertify(K, 1)
%4 = 1
bnfcompress(bnf)

Computes a compressed version of bnf (from bnfinit), a “small Buchmann’s number field” (or sbnf for short) which contains enough information to recover a full bnf vector very rapidly, but which is much smaller and hence easy to store and print. Calling bnfinit on the result recovers a true bnf, in general different from the original. Note that an snbf is useless for almost all purposes besides storage, and must be converted back to bnf form before use; for instance, no nf*, bnf* or member function accepts them.

An sbnf is a 12 component vector v, as follows. Let bnf be the result of a full bnfinit, complete with units. Then v[1] is bnf.pol, v[2] is the number of real embeddings bnf.sign[1], v[3] is bnf.disc, v[4] is bnf.zk, v[5] is the list of roots bnf.roots, v[7] is the matrix W = bnf[1], v[8] is the matrix matalpha = bnf[2], v[9] is the prime ideal factor base bnf[5] coded in a compact way, and ordered according to the permutation bnf[6], v[10] is the 2-component vector giving the number of roots of unity and a generator, expressed on the integral basis, v[11] is the list of fundamental units, expressed on the integral basis, v[12] is a vector containing the algebraic numbers alpha corresponding to the columns of the matrix matalpha, expressed on the integral basis.

All the components are exact (integral or rational), except for the roots in v[5].

bnfdecodemodule(nf, m)

If m is a module as output in the first component of an extension given by bnrdisclist, outputs the true module.

? K = bnfinit(x^2+23); L = bnrdisclist(K, 10); s = L[1][2]
%1 = [[Mat([8, 1]), [[0, 0, 0]]], [Mat([9, 1]), [[0, 0, 0]]]]
? bnfdecodemodule(K, s[1][1])
%2 =
[2 0]

[0 1]
bnfinit(P, flag=0, tech=None, precision=0)

Initializes a bnf structure. Used in programs such as bnfisprincipal, bnfisunit or bnfnarrow. By default, the results are conditional on the GRH, see GRHbnf (in the PARI manual). The result is a 10-component vector bnf.

This implements Buchmann’s sub-exponential algorithm for computing the class group, the regulator and a system of fundamental units of the general algebraic number field K defined by the irreducible polynomial P with integer coefficients.

If the precision becomes insufficient, gp does not strive to compute the units by default (flag = 0).

When flag = 1, we insist on finding the fundamental units exactly. Be warned that this can take a very long time when the coefficients of the fundamental units on the integral basis are very large. If the fundamental units are simply too large to be represented in this form, an error message is issued. They could be obtained using the so-called compact representation of algebraic numbers as a formal product of algebraic integers. The latter is implemented internally but not publicly accessible yet.

tech is a technical vector (empty by default, see GRHbnf (in the PARI manual)). Careful use of this parameter may speed up your computations, but it is mostly obsolete and you should leave it alone.

The components of a bnf or sbnf are technical and never used by the casual user. In fact: never access a component directly, always use a proper member function. However, for the sake of completeness and internal documentation, their description is as follows. We use the notations explained in the book by H. Cohen, A Course in Computational Algebraic Number Theory, Graduate Texts in Maths 138, Springer-Verlag, 1993, Section 6.5, and subsection 6.5.5 in particular.

bnf[1] contains the matrix W, i.e. the matrix in Hermite normal form giving relations for the class group on prime ideal generators (p_i)_{1 <= i <= r}.

bnf[2] contains the matrix B, i.e. the matrix containing the expressions of the prime ideal factorbase in terms of the p_i. It is an r x c matrix.

bnf[3] contains the complex logarithmic embeddings of the system of fundamental units which has been found. It is an (r_1+r_2) x (r_1+r_2-1) matrix.

bnf[4] contains the matrix M"_C of Archimedean components of the relations of the matrix (W\|B).

bnf[5] contains the prime factor base, i.e. the list of prime ideals used in finding the relations.

bnf[6] used to contain a permutation of the prime factor base, but has been obsoleted. It contains a dummy 0.

bnf[7] or :emphasis:`bnf.nf` is equal to the number field data nf as would be given by nfinit.

bnf[8] is a vector containing the classgroup :emphasis:`bnf.clgp` as a finite abelian group, the regulator :emphasis:`bnf.reg`, a 1 (used to contain an obsolete “check number”), the number of roots of unity and a generator :emphasis:`bnf.tu`, the fundamental units :emphasis:`bnf.fu`.

bnf[9] is a 3-element row vector used in bnfisprincipal only and obtained as follows. Let D = U W V obtained by applying the Smith normal form algorithm to the matrix W ( = bnf[1]) and let U_r be the reduction of U modulo D. The first elements of the factorbase are given (in terms of bnf.gen) by the columns of U_r, with Archimedean component g_a; let also GD_a be the Archimedean components of the generators of the (principal) ideals defined by the bnf.gen[i]^bnf.cyc[i]. Then bnf[9] = [U_r, g_a, GD_a].

bnf[10] is by default unused and set equal to 0. This field is used to store further information about the field as it becomes available, which is rarely needed, hence would be too expensive to compute during the initial bnfinit call. For instance, the generators of the principal ideals bnf.gen[i]^bnf.cyc[i] (during a call to bnrisprincipal), or those corresponding to the relations in W and B (when the bnf internal precision needs to be increased).

bnfisintnorm(bnf, x)

Computes a complete system of solutions (modulo units of positive norm) of the absolute norm equation \mathrm{Norm}(a) = x, where a is an integer in bnf. If bnf has not been certified, the correctness of the result depends on the validity of GRH.

See also bnfisnorm.

bnfisnorm(bnf, x, flag=1)

Tries to tell whether the rational number x is the norm of some element y in bnf. Returns a vector [a,b] where x = Norm(a)*b. Looks for a solution which is an S-unit, with S a certain set of prime ideals containing (among others) all primes dividing x. If bnf is known to be Galois, set flag = 0 (in this case, x is a norm iff b = 1). If flag is non zero the program adds to S the following prime ideals, depending on the sign of flag. If flag > 0, the ideals of norm less than flag. And if flag < 0 the ideals dividing flag.

Assuming GRH, the answer is guaranteed (i.e. x is a norm iff b = 1), if S contains all primes less than 12\log(\mathrm{disc}(Bnf))^2, where Bnf is the Galois closure of bnf.

See also bnfisintnorm.

bnfisprincipal(bnf, x, flag=1)

bnf being the number field data output by bnfinit, and x being an ideal, this function tests whether the ideal is principal or not. The result is more complete than a simple true/false answer and solves general discrete logarithm problem. Assume the class group is \oplus (\mathbb{Z}/d_i\mathbb{Z})g_i (where the generators g_i and their orders d_i are respectively given by bnf.gen and bnf.cyc). The routine returns a row vector [e,t], where e is a vector of exponents 0 <= e_i < d_i, and t is a number field element such that

x = (t) \prod_i g_i^{e_i}.

For given g_i (i.e. for a given bnf), the e_i are unique, and t is unique modulo units.

In particular, x is principal if and only if e is the zero vector. Note that the empty vector, which is returned when the class number is 1, is considered to be a zero vector (of dimension 0).

? K = bnfinit(y^2+23);
? K.cyc
%2 = [3]
? K.gen
%3 = [[2, 0; 0, 1]] \\ a prime ideal above 2
? P = idealprimedec(K,3)[1]; \\ a prime ideal above 3
? v = bnfisprincipal(K, P)
%5 = [[2]~, [3/4, 1/4]~]
? idealmul(K, v[2], idealfactorback(K, K.gen, v[1]))
%6 =
[3 0]

[0 1]
? % == idealhnf(K, P)
%7 = 1

The binary digits of flag mean:

  • 1: If set, outputs [e,t] as explained above, otherwise returns only e, which is much easier to compute. The following idiom only tests whether an ideal is principal:
is_principal(bnf, x) = !bnfisprincipal(bnf,x,0);
  • 2: It may not be possible to recover t, given the initial accuracy to which bnf was computed. In that case, a warning is printed and t is set equal to the empty vector []~. If this bit is set, increase the precision and recompute needed quantities until t can be computed. Warning: setting this may induce very lengthy computations.
bnfissunit(bnf, sfu, x)

bnf being output by bnfinit, sfu by bnfsunit, gives the column vector of exponents of x on the fundamental S-units and the roots of unity. If x is not a unit, outputs an empty vector.

bnfisunit(bnf, x)

bnf being the number field data output by bnfinit and x being an algebraic number (type integer, rational or polmod), this outputs the decomposition of x on the fundamental units and the roots of unity if x is a unit, the empty vector otherwise. More precisely, if u_1,...,:math:u_r are the fundamental units, and \zeta is the generator of the group of roots of unity (bnf.tu), the output is a vector [x_1,...,x_r,x_{r+1}] such that x = u_1^{x_1}...
u_r^{x_r}.\zeta^{x_{r+1}}. The x_i are integers for i <= r and is an integer modulo the order of \zeta for i = r+1.

Note that bnf need not contain the fundamental unit explicitly:

? setrand(1); bnf = bnfinit(x^2-x-100000);
? bnf.fu
 *** at top-level: bnf.fu
 *** ^--
 *** _.fu: missing units in .fu.
? u = [119836165644250789990462835950022871665178127611316131167, \
 379554884019013781006303254896369154068336082609238336]~;
? bnfisunit(bnf, u)
%3 = [-1, Mod(0, 2)]~

The given u is the inverse of the fundamental unit implicitly stored in bnf. In this case, the fundamental unit was not computed and stored in algebraic form since the default accuracy was too low. (Re-run the command at \g1 or higher to see such diagnostics.)

bnfnarrow(bnf)

bnf being as output by bnfinit, computes the narrow class group of bnf. The output is a 3-component row vector v analogous to the corresponding class group component :emphasis:`bnf.clgp` (:emphasis:`bnf`[8][1]): the first component is the narrow class number :math:`v.no`, the second component is a vector containing the SNF cyclic components :math:`v.cyc` of the narrow class group, and the third is a vector giving the generators of the corresponding :math:`v.gen` cyclic groups. Note that this function is a special case of bnrinit.

bnfsignunit(bnf)

bnf being as output by bnfinit, this computes an r_1 x (r_1+r_2-1) matrix having ±1 components, giving the signs of the real embeddings of the fundamental units. The following functions compute generators for the totally positive units:

/* exponents of totally positive units generators on bnf.tufu */
tpuexpo(bnf)=
{ my(S,d,K);

 S = bnfsignunit(bnf); d = matsize(S);
 S = matrix(d[1],d[2], i,j, if (S[i,j] < 0, 1,0));
 S = concat(vectorv(d[1],i,1), S); \\ add sign(-1)
 K = lift(matker(S * Mod(1,2)));
 if (K, mathnfmodid(K, 2), 2*matid(d[1]))
}

/* totally positive units */
tpu(bnf)=
{ my(vu = bnf.tufu, ex = tpuexpo(bnf));

 vector(#ex-1, i, factorback(vu, ex[,i+1])) \\ ex[,1] is 1
}
bnfsunit(bnf, S, precision=0)

Computes the fundamental S-units of the number field bnf (output by bnfinit), where S is a list of prime ideals (output by idealprimedec). The output is a vector v with 6 components.

v[1] gives a minimal system of (integral) generators of the S-unit group modulo the unit group.

v[2] contains technical data needed by bnfissunit.

v[3] is an empty vector (used to give the logarithmic embeddings of the generators in v[1] in version 2.0.16).

v[4] is the S-regulator (this is the product of the regulator, the determinant of v[2] and the natural logarithms of the norms of the ideals in S).

v[5] gives the S-class group structure, in the usual format (a row vector whose three components give in order the S-class number, the cyclic components and the generators).

v[6] is a copy of S.

bnrL1(bnr, H=None, flag=0, precision=0)

Let bnr be the number field data output by bnrinit(,,1) and H be a square matrix defining a congruence subgroup of the ray class group corresponding to bnr (the trivial congruence subgroup if omitted). This function returns, for each character \chi of the ray class group which is trivial on H, the value at s = 1 (or s = 0) of the abelian L-function associated to \chi. For the value at s = 0, the function returns in fact for each \chi a vector [r_\chi, c_\chi] where

L(s, \chi) = c.s^r + O(s^{r + 1})

near 0.

The argument flag is optional, its binary digits mean 1: compute at s = 0 if unset or s = 1 if set, 2: compute the primitive L-function associated to \chi if unset or the L-function with Euler factors at prime ideals dividing the modulus of bnr removed if set (that is L_S(s, \chi), where S is the set of infinite places of the number field together with the finite prime ideals dividing the modulus of bnr), 3: return also the character if set.

K = bnfinit(x^2-229);
bnr = bnrinit(K,1,1);
bnrL1(bnr)

returns the order and the first non-zero term of L(s, \chi) at s = 0 where \chi runs through the characters of the class group of K = \mathbb{Q}(\sqrt{229}). Then

bnr2 = bnrinit(K,2,1);
bnrL1(bnr2,,2)

returns the order and the first non-zero terms of L_S(s, \chi) at s = 0 where \chi runs through the characters of the class group of K and S is the set of infinite places of K together with the finite prime 2. Note that the ray class group modulo 2 is in fact the class group, so bnrL1(bnr2,0) returns the same answer as bnrL1(bnr,0).

This function will fail with the message

*** bnrL1: overflow in zeta_get_N0 [need too many primes].

if the approximate functional equation requires us to sum too many terms (if the discriminant of K is too large).

bnrclassno(A, B=None, C=None)

Let A, B, C define a class field L over a ground field K (of type [:emphasis:`bnr]`, [:emphasis:`bnr, subgroup]`, or [:emphasis:`bnf, modulus]`, or [:emphasis:`bnf, modulus,:emphasis:subgroup]`, CFT (in the PARI manual)); this function returns the relative degree [L:K].

In particular if A is a bnf (with units), and B a modulus, this function returns the corresponding ray class number modulo B. One can input the associated bid (with generators if the subgroup C is non trivial) for B instead of the module itself, saving some time.

This function is faster than bnrinit and should be used if only the ray class number is desired. See bnrclassnolist if you need ray class numbers for all moduli less than some bound.

bnrclassnolist(bnf, list)

bnf being as output by bnfinit, and list being a list of moduli (with units) as output by ideallist or ideallistarch, outputs the list of the class numbers of the corresponding ray class groups. To compute a single class number, bnrclassno is more efficient.

? bnf = bnfinit(x^2 - 2);
? L = ideallist(bnf, 100, 2);
? H = bnrclassnolist(bnf, L);
? H[98]
%4 = [1, 3, 1]
? l = L[1][98]; ids = vector(#l, i, l[i].mod[1])
%5 = [[98, 88; 0, 1], [14, 0; 0, 7], [98, 10; 0, 1]]

The weird l[i].mod[1], is the first component of l[i].mod, i.e. the finite part of the conductor. (This is cosmetic: since by construction the Archimedean part is trivial, I do not want to see it). This tells us that the ray class groups modulo the ideals of norm 98 (printed as %5) have respectively order 1, 3 and 1. Indeed, we may check directly:

? bnrclassno(bnf, ids[2])
%6 = 3
bnrconductor(A, B=None, C=None, flag=0)

Conductor f of the subfield of a ray class field as defined by [A,B,C] (of type [:emphasis:`bnr]`, [:emphasis:`bnr, subgroup]`, [:emphasis:`bnf, modulus]` or [:emphasis:`bnf, modulus, subgroup]`, CFT (in the PARI manual))

If flag = 0, returns f.

If flag = 1, returns [f, Cl_f, H], where Cl_f is the ray class group modulo f, as a finite abelian group; finally H is the subgroup of Cl_f defining the extension.

If flag = 2, returns [f, bnr(f), H], as above except Cl_f is replaced by a bnr structure, as output by bnrinit(,f,1).

bnrconductorofchar(bnr, chi)

bnr being a big ray number field as output by bnrinit, and chi being a row vector representing a character as expressed on the generators of the ray class group, gives the conductor of this character as a modulus.

bnrdisc(A, B=None, C=None, flag=0)

A, B, C defining a class field L over a ground field K (of type [:emphasis:`bnr]`, [:emphasis:`bnr, subgroup]`, [:emphasis:`bnf, modulus]` or [:emphasis:`bnf, modulus, subgroup]`, CFT (in the PARI manual)), outputs data [N,r_1,D] giving the discriminant and signature of L, depending on the binary digits of flag:

  • 1: if this bit is unset, output absolute data related to L/\mathbb{Q}: N is the absolute degree [L:\mathbb{Q}], r_1 the number of real places of L, and D the discriminant of L/\mathbb{Q}. Otherwise, output relative data for L/K: N is the relative degree [L:K], r_1 is the number of real places of K unramified in L (so that the number of real places of L is equal to r_1 times N), and D is the relative discriminant ideal of L/K.
  • 2: if this bit is set and if the modulus is not the conductor of L, only return 0.
bnrdisclist(bnf, bound, arch=None)

bnf being as output by bnfinit (with units), computes a list of discriminants of Abelian extensions of the number field by increasing modulus norm up to bound bound. The ramified Archimedean places are given by arch; all possible values are taken if arch is omitted.

The alternative syntax bnrdisclist(bnf,list) is supported, where list is as output by ideallist or ideallistarch (with units), in which case arch is disregarded.

The output v is a vector of vectors, where v[i][j] is understood to be in fact V[2^{15}(i-1)+j] of a unique big vector V. (This awkward scheme allows for larger vectors than could be otherwise represented.)

V[k] is itself a vector W, whose length is the number of ideals of norm k. We consider first the case where arch was specified. Each component of W corresponds to an ideal m of norm k, and gives invariants associated to the ray class field L of bnf of conductor [m, arch]. Namely, each contains a vector [m,d,r,D] with the following meaning: m is the prime ideal factorization of the modulus, d = [L:\mathbb{Q}] is the absolute degree of L, r is the number of real places of L, and D is the factorization of its absolute discriminant. We set d
= r = D = 0 if m is not the finite part of a conductor.

If arch was omitted, all t = 2^{r_1} possible values are taken and a component of W has the form [m, [[d_1,r_1,D_1],..., [d_t,r_t,D_t]]], where m is the finite part of the conductor as above, and [d_i,r_i,D_i] are the invariants of the ray class field of conductor [m,v_i], where v_i is the i-th Archimedean component, ordered by inverse lexicographic order; so v_1 = [0,...,0], v_2 = [1,0...,0], etc. Again, we set d_i = r_i = D_i = 0 if [m,v_i] is not a conductor.

Finally, each prime ideal pr = [p,\alpha,e,f,\beta] in the prime factorization m is coded as the integer p.n^2+(f-1).n+(j-1), where n is the degree of the base field and j is such that

pr = idealprimedec(:emphasis:`nf,p)[j]`.

m can be decoded using bnfdecodemodule.

Note that to compute such data for a single field, either bnrclassno or bnrdisc is more efficient.

bnrgaloisapply(bnr, mat, H)

Apply the automorphism given by its matrix mat to the congruence subgroup H given as a HNF matrix. The matrix mat can be computed with bnrgaloismatrix.

bnrgaloismatrix(bnr, aut)

Return the matrix of the action of the automorphism aut of the base field bnf.nf on the generators of the ray class field bnr.gen. aut can be given as a polynomial, an algebraic number, or a vector of automorphisms or a Galois group as output by galoisinit, in which case a vector of matrices is returned (in the later case, only for the generators aut.gen).

See bnrisgalois for an example.

bnrinit(bnf, f, flag=0)

bnf is as output by bnfinit, f is a modulus, initializes data linked to the ray class group structure corresponding to this module, a so-called bnr structure. One can input the associated bid with generators for f instead of the module itself, saving some time. (As in idealstar, the finite part of the conductor may be given by a factorization into prime ideals, as produced by idealfactor.)

The following member functions are available on the result: .bnf is the underlying bnf, .mod the modulus, .bid the bid structure associated to the modulus; finally, .clgp, .no, .cyc, .gen refer to the ray class group (as a finite abelian group), its cardinality, its elementary divisors, its generators (only computed if flag = 1).

The last group of functions are different from the members of the underlying bnf, which refer to the class group; use :emphasis:`bnr.bnf.:emphasis:xxx` to access these, e.g. :emphasis:`bnr.bnf.cyc` to get the cyclic decomposition of the class group.

They are also different from the members of the underlying bid, which refer to (\mathbb{Z}_K/f)^*; use :emphasis:`bnr.bid.:emphasis:xxx` to access these, e.g. :emphasis:`bnr.bid.no` to get \phi(f).

If flag = 0 (default), the generators of the ray class group are not computed, which saves time. Hence :emphasis:`bnr.gen` would produce an error.

If flag = 1, as the default, except that generators are computed.

bnrisconductor(A, B=None, C=None)

A, B, C represent an extension of the base field, given by class field theory (see CFT (in the PARI manual)). Outputs 1 if this modulus is the conductor, and 0 otherwise. This is slightly faster than bnrconductor.

bnrisgalois(bnr, gal, H)

Check whether the class field associated to the subgroup H is Galois over the subfield of bnr.nf fixed by the group gal, which can be given as output by galoisinit, or as a matrix or a vector of matrices as output by bnrgaloismatrix, the second option being preferable, since it saves the recomputation of the matrices. Note: The function assumes that the ray class field associated to bnr is Galois, which is not checked.

In the following example, we lists the congruence subgroups of subextension of degree at most 3 of the ray class field of conductor 9 which are Galois over the rationals.

K=bnfinit(a^4-3*a^2+253009);
G=galoisinit(K);
B=bnrinit(K,9,1);
L1=[H|H<-subgrouplist(B,3), bnrisgalois(B,G,H)]
##
M=bnrgaloismatrix(B,G)
L2=[H|H<-subgrouplist(B,3), bnrisgalois(B,M,H)]
##

The second computation is much faster since bnrgaloismatrix(B,G) is computed only once.

bnrisprincipal(bnr, x, flag=1)

bnr being the number field data which is output by bnrinit(,,1) and x being an ideal in any form, outputs the components of x on the ray class group generators in a way similar to bnfisprincipal. That is a 2-component vector v where v[1] is the vector of components of x on the ray class group generators, v[2] gives on the integral basis an element \alpha such that x = \alpha\prod_ig_i^{x_i}.

If flag = 0, outputs only v_1. In that case, bnr need not contain the ray class group generators, i.e. it may be created with bnrinit(,,0) If x is not coprime to the modulus of bnr the result is undefined.

bnrrootnumber(bnr, chi, flag=0, precision=0)

If \chi = chi is a character over bnr, not necessarily primitive, let L(s,\chi) = \sum_{id} \chi(id) N(id)^{-s} be the associated Artin L-function. Returns the so-called Artin root number, i.e. the complex number W(\chi) of modulus 1 such that

\Lambda(1-s,\chi) = W(\chi) \Lambda(s,\\overline{\chi})

where \Lambda(s,\chi) = A(\chi)^{s/2}\gamma_\chi(s) L(s,\chi) is the enlarged L-function associated to L.

The generators of the ray class group are needed, and you can set flag = 1 if the character is known to be primitive. Example:

bnf = bnfinit(x^2 - x - 57);
bnr = bnrinit(bnf, [7,[1,1]], 1);
bnrrootnumber(bnr, [2,1])

returns the root number of the character \chi of \mathrm{Cl}_{7 oo _1 oo _2}(\mathbb{Q}(\sqrt{229})) defined by \chi(g_1^ag_2^b)
= \zeta_1^{2a}\zeta_2^b. Here g_1, g_2 are the generators of the ray-class group given by bnr.gen and \zeta_1 = e^{2i\Pi/N_1},
\zeta_2 = e^{2i\Pi/N_2} where N_1, N_2 are the orders of g_1 and g_2 respectively (N_1 = 6 and N_2 = 3 as bnr.cyc readily tells us).

bnrstark(bnr, subgroup=None, precision=0)

bnr being as output by bnrinit(,,1), finds a relative equation for the class field corresponding to the modulus in bnr and the given congruence subgroup (as usual, omit subgroup if you want the whole ray class group).

The main variable of bnr must not be x, and the ground field and the class field must be totally real. When the base field is \mathbb{Q}, the vastly simpler galoissubcyclo is used instead. Here is an example:

bnf = bnfinit(y^2 - 3);
bnr = bnrinit(bnf, 5, 1);
bnrstark(bnr)

returns the ray class field of \mathbb{Q}(\sqrt{3}) modulo 5. Usually, one wants to apply to the result one of

rnfpolredabs(bnf, pol, 16) \\ compute a reduced relative polynomial
rnfpolredabs(bnf, pol, 16 + 2) \\ compute a reduced absolute polynomial

The routine uses Stark units and needs to find a suitable auxiliary conductor, which may not exist when the class field is not cyclic over the base. In this case bnrstark is allowed to return a vector of polynomials defining independent relative extensions, whose compositum is the requested class field. It was decided that it was more useful to keep the extra information thus made available, hence the user has to take the compositum herself.

Even if it exists, the auxiliary conductor may be so large that later computations become unfeasible. (And of course, Stark’s conjecture may simply be wrong.) In case of difficulties, try rnfkummer:

? bnr = bnrinit(bnfinit(y^8-12*y^6+36*y^4-36*y^2+9,1), 2, 1);
? bnrstark(bnr)
 *** at top-level: bnrstark(bnr)
 *** ^-------------
 *** bnrstark: need 3919350809720744 coefficients in initzeta.
 *** Computation impossible.
? lift( rnfkummer(bnr) )
time = 24 ms.
%2 = x^2 + (1/3*y^6 - 11/3*y^4 + 8*y^2 - 5)
ceil(x)

Ceiling of x. When x is in \mathbb{R}, the result is the smallest integer greater than or equal to x. Applied to a rational function, ceil(x) returns the Euclidean quotient of the numerator by the denominator.

centerlift(x, v=None)

Same as lift, except that t_INTMOD and t_PADIC components are lifted using centered residues:

  • for a t_INTMOD x belongs to \mathbb{Z}/n\mathbb{Z}, the lift y is such that -n/2 < y <= n/2.
  • a t_PADIC x is lifted in the same way as above (modulo p^padicprec(x)) if its valuation v is non-negative; if not, returns the fraction p^v centerlift(x p^{-v}); in particular, rational reconstruction is not attempted. Use bestappr for this.

For backward compatibility, centerlift(x,'v) is allowed as an alias for lift(x,'v).

characteristic(x)

Returns the characteristic of the base ring over which x is defined (as defined by t_INTMOD and t_FFELT components). The function raises an exception if incompatible primes arise from t_FFELT and t_PADIC components.

? characteristic(Mod(1,24)*x + Mod(1,18)*y)
%1 = 6
charpoly(A, v=None, flag=5)

characteristic polynomial of A with respect to the variable v, i.e. determinant of v*I-A if A is a square matrix.

? charpoly([1,2;3,4]);
%1 = x^2 - 5*x - 2
? charpoly([1,2;3,4],, 't)
%2 = t^2 - 5*t - 2

If A is not a square matrix, the function returns the characteristic polynomial of the map “multiplication by A” if A is a scalar:

? charpoly(Mod(x+2, x^3-2))
%1 = x^3 - 6*x^2 + 12*x - 10
? charpoly(I)
%2 = x^2 + 1
? charpoly(quadgen(5))
%3 = x^2 - x - 1
? charpoly(ffgen(ffinit(2,4)))
%4 = Mod(1, 2)*x^4 + Mod(1, 2)*x^3 + Mod(1, 2)*x^2 + Mod(1, 2)*x + Mod(1, 2)

The value of flag is only significant for matrices, and we advise to stick to the default value. Let n be the dimension of A.

If flag = 0, same method (Le Verrier’s) as for computing the adjoint matrix, i.e. using the traces of the powers of A. Assumes that n! is invertible; uses O(n^4) scalar operations.

If flag = 1, uses Lagrange interpolation which is usually the slowest method. Assumes that n! is invertible; uses O(n^4) scalar operations.

If flag = 2, uses the Hessenberg form. Assumes that the base ring is a field. Uses O(n^3) scalar operations, but suffers from coefficient explosion unless the base field is finite or \mathbb{R}.

If flag = 3, uses Berkowitz’s division free algorithm, valid over any ring (commutative, with unit). Uses O(n^4) scalar operations.

If flag = 4, x must be integral. Uses a modular algorithm: Hessenberg form for various small primes, then Chinese remainders.

If flag = 5 (default), uses the “best” method given x. This means we use Berkowitz unless the base ring is \mathbb{Z} (use flag = 4) or a field where coefficient explosion does not occur, e.g. a finite field or the reals (use flag = 2).

chinese(x, y=None)

If x and y are both intmods or both polmods, creates (with the same type) a z in the same residue class as x and in the same residue class as y, if it is possible.

? chinese(Mod(1,2), Mod(2,3))
%1 = Mod(5, 6)
? chinese(Mod(x,x^2-1), Mod(x+1,x^2+1))
%2 = Mod(-1/2*x^2 + x + 1/2, x^4 - 1)

This function also allows vector and matrix arguments, in which case the operation is recursively applied to each component of the vector or matrix.

? chinese([Mod(1,2),Mod(1,3)], [Mod(1,5),Mod(2,7)])
%3 = [Mod(1, 10), Mod(16, 21)]

For polynomial arguments in the same variable, the function is applied to each coefficient; if the polynomials have different degrees, the high degree terms are copied verbatim in the result, as if the missing high degree terms in the polynomial of lowest degree had been Mod(0,1). Since the latter behavior is usually not the desired one, we propose to convert the polynomials to vectors of the same length first:

? P = x+1; Q = x^2+2*x+1;
? chinese(P*Mod(1,2), Q*Mod(1,3))
%4 = Mod(1, 3)*x^2 + Mod(5, 6)*x + Mod(3, 6)
? chinese(Vec(P,3)*Mod(1,2), Vec(Q,3)*Mod(1,3))
%5 = [Mod(1, 6), Mod(5, 6), Mod(4, 6)]
? Pol(%)
%6 = Mod(1, 6)*x^2 + Mod(5, 6)*x + Mod(4, 6)

If y is omitted, and x is a vector, chinese is applied recursively to the components of x, yielding a residue belonging to the same class as all components of x.

Finally chinese(x,x) = x regardless of the type of x; this allows vector arguments to contain other data, so long as they are identical in both vectors.

cmp(x, y)

Gives the result of a comparison between arbitrary objects x and y (as -1, 0 or 1). The underlying order relation is transitive, the function returns 0 if and only if x  ===  y, and its restriction to integers coincides with the customary one. Besides that, it has no useful mathematical meaning.

In case all components are equal up to the smallest length of the operands, the more complex is considered to be larger. More precisely, the longest is the largest; when lengths are equal, we have matrix > vector > scalar. For example:

? cmp(1, 2)
%1 = -1
? cmp(2, 1)
%2 = 1
? cmp(1, 1.0) \\ note that 1 == 1.0, but (1===1.0) is false.
%3 = -1
? cmp(x + Pi, [])
%4 = -1

This function is mostly useful to handle sorted lists or vectors of arbitrary objects. For instance, if v is a vector, the construction vecsort(v, cmp) is equivalent to Set(v).

component(x, n)

Extracts the n-th-component of x. This is to be understood as follows: every PARI type has one or two initial code words. The components are counted, starting at 1, after these code words. In particular if x is a vector, this is indeed the n-th-component of x, if x is a matrix, the n-th column, if x is a polynomial, the n-th coefficient (i.e. of degree n-1), and for power series, the n-th significant coefficient.

For polynomials and power series, one should rather use polcoeff, and for vectors and matrices, the [] operator. Namely, if x is a vector, then x[n] represents the n-th component of x. If x is a matrix, x[m,n] represents the coefficient of row m and column n of the matrix, x[m,] represents the m-th row of x, and x[,n] represents the n-th column of x.

Using of this function requires detailed knowledge of the structure of the different PARI types, and thus it should almost never be used directly. Some useful exceptions:

? x = 3 + O(3^5);
? component(x, 2)
%2 = 81 \\ p^(p-adic accuracy)
? component(x, 1)
%3 = 3 \\ p
? q = Qfb(1,2,3);
? component(q, 1)
%5 = 1
concat(x, y=None)

Concatenation of x and y. If x or y is not a vector or matrix, it is considered as a one-dimensional vector. All types are allowed for x and y, but the sizes must be compatible. Note that matrices are concatenated horizontally, i.e. the number of rows stays the same. Using transpositions, one can concatenate them vertically, but it is often simpler to use matconcat.

? x = matid(2); y = 2*matid(2);
? concat(x,y)
%2 =
[1 0 2 0]

[0 1 0 2]
? concat(x~,y~)~
%3 =
[1 0]

[0 1]

[2 0]

[0 2]
? matconcat([x;y])
%4 =
[1 0]

[0 1]

[2 0]

[0 2]

To concatenate vectors sideways (i.e. to obtain a two-row or two-column matrix), use Mat instead, or matconcat:

? x = [1,2];
? y = [3,4];
? concat(x,y)
%3 = [1, 2, 3, 4]

? Mat([x,y]~)
%4 =
[1 2]

[3 4]
? matconcat([x;y])
%5 =
[1 2]

[3 4]

Concatenating a row vector to a matrix having the same number of columns will add the row to the matrix (top row if the vector is x, i.e. comes first, and bottom row otherwise).

The empty matrix [;] is considered to have a number of rows compatible with any operation, in particular concatenation. (Note that this is not the case for empty vectors [ ] or [ ]~.)

If y is omitted, x has to be a row vector or a list, in which case its elements are concatenated, from left to right, using the above rules.

? concat([1,2], [3,4])
%1 = [1, 2, 3, 4]
? a = [[1,2]~, [3,4]~]; concat(a)
%2 =
[1 3]

[2 4]

? concat([1,2; 3,4], [5,6]~)
%3 =
[1 2 5]

[3 4 6]
? concat([%, [7,8]~, [1,2,3,4]])
%5 =
[1 2 5 7]

[3 4 6 8]

[1 2 3 4]
conj(x)

Conjugate of x. The meaning of this is clear, except that for real quadratic numbers, it means conjugation in the real quadratic field. This function has no effect on integers, reals, intmods, fractions or p-adics. The only forbidden type is polmod (see conjvec for this).

conjvec(z, precision=0)

Conjugate vector representation of z. If z is a polmod, equal to Mod(a,T), this gives a vector of length {degree}(T) containing:

  • the complex embeddings of z if T has rational coefficients, i.e. the a(r[i]) where r = polroots(T);
  • the conjugates of z if T has some intmod coefficients;

if z is a finite field element, the result is the vector of conjugates [z,z^p,z^{p^2},...,z^{p^{n-1}}] where n = {degree}(T).

If z is an integer or a rational number, the result is z. If z is a (row or column) vector, the result is a matrix whose columns are the conjugate vectors of the individual elements of z.

content(x)

Computes the gcd of all the coefficients of x, when this gcd makes sense. This is the natural definition if x is a polynomial (and by extension a power series) or a vector/matrix. This is in general a weaker notion than the ideal generated by the coefficients:

? content(2*x+y)
%1 = 1 \\ = gcd(2,y) over Q[y]

If x is a scalar, this simply returns the absolute value of x if x is rational (t_INT or t_FRAC), and either 1 (inexact input) or x (exact input) otherwise; the result should be identical to gcd(x, 0).

The content of a rational function is the ratio of the contents of the numerator and the denominator. In recursive structures, if a matrix or vector coefficient x appears, the gcd is taken not with x, but with its content:

? content([ [2], 4*matid(3) ])
%1 = 2

The content of a t_VECSMALL is computed assuming the entries are signed integers in [-2^{BIL-1}, 2^{BIL-1}[.

contfrac(x, b=None, nmax=0)

Returns the row vector whose components are the partial quotients of the continued fraction expansion of x. In other words, a result [a_0,...,a_n] means that x ~ a_0+1/(a_1+...+1/a_n). The output is normalized so that a_n != 1 (unless we also have n = 0).

The number of partial quotients n+1 is limited by nmax. If nmax is omitted, the expansion stops at the last significant partial quotient.

? \p19
 realprecision = 19 significant digits
? contfrac(Pi)
%1 = [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2]
? contfrac(Pi,, 3) \\ n = 2
%2 = [3, 7, 15]

x can also be a rational function or a power series.

If a vector b is supplied, the numerators are equal to the coefficients of b, instead of all equal to 1 as above; more precisely, x ~ 
(1/b_0)(a_0+b_1/(a_1+...+b_n/a_n)); for a numerical continued fraction (x real), the a_i are integers, as large as possible; if x is a rational function, they are polynomials with \deg a_i = \deg b_i + 1. The length of the result is then equal to the length of b, unless the next partial quotient cannot be reliably computed, in which case the expansion stops. This happens when a partial remainder is equal to zero (or too small compared to the available significant digits for x a t_REAL).

A direct implementation of the numerical continued fraction contfrac(x,b) described above would be

\\ "greedy" generalized continued fraction
cf(x, b) =
{ my( a= vector(#b), t );

 x *= b[1];
 for (i = 1, #b,
 a[i] = floor(x);
 t = x - a[i]; if (!t || i == #b, break);
 x = b[i+1] / t;
 ); a;
}

There is some degree of freedom when choosing the a_i; the program above can easily be modified to derive variants of the standard algorithm. In the same vein, although no builtin function implements the related Engel expansion (a special kind of Egyptian fraction decomposition: x = 1/a_1 + 1/(a_1a_2) +... ), it can be obtained as follows:

\\ n terms of the Engel expansion of x
engel(x, n = 10) =
{ my( u = x, a = vector(n) );
 for (k = 1, n,
 a[k] = ceil(1/u);
 u = u*a[k] - 1;
 if (!u, break);
 ); a
}

Obsolete hack. (don’t use this): If b is an integer, nmax is ignored and the command is understood as contfrac(:math:`x,, b)`.

contfraceval(CF, t, lim=-1)

Given a continued fraction CF output by contfracinit, evaluate the first lim terms of the continued fraction at t (all terms if lim is negative or omitted; if positive, lim must be less than or equal to the length of CF.

contfracinit(M, lim=-1)

Given M representing the power series S = \sum_{n >= 0} M[n+1]z^n, transform it into a continued fraction; restrict to n <= lim if latter is non-negative. M can be a vector, a power series, a polynomial, or a rational function. The result is a 2-component vector [A,B] such that S = M[1] / (1+A[1]z+B[1]z^2/(1+A[2]z+B[2]z^2/(1+...1/(1+A[lim/2]z)))). Does not work if any coefficient of M vanishes, nor for series for which certain partial denominators vanish.

contfracpnqn(x, n=-1)

When x is a vector or a one-row matrix, x is considered as the list of partial quotients [a_0,a_1,...,a_n] of a rational number, and the result is the 2 by 2 matrix [p_n,p_{n-1};q_n,q_{n-1}] in the standard notation of continued fractions, so p_n/q_n = a_0+1/(a_1+...+1/a_n). If x is a matrix with two rows [b_0,b_1,...,b_n] and [a_0,a_1,...,a_n], this is then considered as a generalized continued fraction and we have similarly p_n/q_n = (1/b_0)(a_0+b_1/(a_1+...+b_n/a_n)). Note that in this case one usually has b_0 = 1.

If n >= 0 is present, returns all convergents from p_0/q_0 up to p_n/q_n. (All convergents if x is too small to compute the n+1 requested convergents.)

? a=contfrac(Pi,20)
%1 = [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2]
? contfracpnqn(a,3)
%2 =
[3 22 333 355]

[1 7 106 113]

? contfracpnqn(a,7)
%3 =
[3 22 333 355 103993 104348 208341 312689]

[1 7 106 113 33102 33215 66317 99532]
core(n, flag=0)

If n is an integer written as n = df^2 with d squarefree, returns d. If flag is non-zero, returns the two-element row vector [d,f]. By convention, we write 0 = 0
x 1^2, so core(0, 1) returns [0,1].

coredisc(n, flag=0)

A fundamental discriminant is an integer of the form t = 1
mod 4 or 4t = 8,12 mod 16, with t squarefree (i.e. 1 or the discriminant of a quadratic number field). Given a non-zero integer n, this routine returns the (unique) fundamental discriminant d such that n = df^2, f a positive rational number. If flag is non-zero, returns the two-element row vector [d,f]. If n is congruent to 0 or 1 modulo 4, f is an integer, and a half-integer otherwise.

By convention, coredisc(0, 1)) returns [0,1].

Note that quaddisc(n) returns the same value as coredisc(n), and also works with rational inputs n belongs to \mathbb{Q}^*.

cos(x, precision=0)

Cosine of x.

cosh(x, precision=0)

Hyperbolic cosine of x.

cotan(x, precision=0)

Cotangent of x.

denominator(x)

Denominator of x. The meaning of this is clear when x is a rational number or function. If x is an integer or a polynomial, it is treated as a rational number or function, respectively, and the result is equal to 1. For polynomials, you probably want to use

denominator( content(x) )

instead. As for modular objects, t_INTMOD and t_PADIC have denominator 1, and the denominator of a t_POLMOD is the denominator of its (minimal degree) polynomial representative.

If x is a recursive structure, for instance a vector or matrix, the lcm of the denominators of its components (a common denominator) is computed. This also applies for t_COMPLEX s and t_QUAD s.

Warning. Multivariate objects are created according to variable priorities, with possibly surprising side effects (x/y is a polynomial, but y/x is a rational function). See priority (in the PARI manual).

deriv(x, v=None)

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.

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))
}
digits(x, b=None)

Outputs the vector of the digits of \|x\| in base b, where x and b are integers. See fromdigits for the reverse operation.

dilog(x, precision=0)

Principal branch of the dilogarithm of x, i.e. analytic continuation of the power series \log_2(x) = \sum_{n >= 1}x^n/n^2.

dirdiv(x, y)

x and y being vectors of perhaps different lengths but with y[1] != 0 considered as Dirichlet series, computes the quotient of x by y, again as a vector.

dirmul(x, y)

x and y being vectors of perhaps different lengths representing the Dirichlet series \sum_n x_n n^{-s} and \sum_n y_n n^{-s}, computes the product of x by y, again as a vector.

? dirmul(vector(10,n,1), vector(10,n,moebius(n)))
%1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

The product length is the minimum of \# x* v(y) and \# y* v(x), where v(x) is the index of the first non-zero coefficient.

? dirmul([0,1], [0,1]);
%2 = [0, 0, 0, 1]
dirzetak(nf, b)

Gives as a vector the first b coefficients of the Dedekind zeta function of the number field nf considered as a Dirichlet series.

divisors(x)

Creates a row vector whose components are the divisors of x. The factorization of x (as output by factor) can be used instead.

By definition, these divisors are the products of the irreducible factors of n, as produced by factor(n), raised to appropriate powers (no negative exponent may occur in the factorization). If n is an integer, they are the positive divisors, in increasing order.

divrem(x, y, v=None)

Creates a column vector with two components, the first being the Euclidean quotient (:math:`x \:math:y`), the second the Euclidean remainder (:math:`x - (x\:math:y)*:math:y`), of the division of x by y. This avoids the need to do two divisions if one needs both the quotient and the remainder. If v is present, and x, y are multivariate polynomials, divide with respect to the variable v.

Beware that divrem(:math:`x,:math:y)[2]` is in general not the same as :math:`x % y`; no GP operator corresponds to it:

? divrem(1/2, 3)[2]
%1 = 1/2
? (1/2) % 3
%2 = 2
? divrem(Mod(2,9), 3)[2]
 *** at top-level: divrem(Mod(2,9),3)[2
 *** ^--------------------
 *** forbidden division t_INTMOD \ t_INT.
? Mod(2,9) % 6
%3 = Mod(2,3)
eint1(x, n=None, precision=0)

Exponential integral \int_x^ oo (e^{-t})/(t)dt = 
incgam(0, x), where the latter expression extends the function definition from real x > 0 to all complex x != 0.

If n is present, we must have x > 0; the function returns the n-dimensional vector [eint1(x),...,eint1(nx)]. Contrary to other transcendental functions, and to the default case (n omitted), the values are correct up to a bounded absolute, rather than relative, error 10^-n, where n is precision(x) if x is a t_REAL and defaults to realprecision otherwise. (In the most important application, to the computation of L-functions via approximate functional equations, those values appear as weights in long sums and small individual relative errors are less useful than controlling the absolute error.) This is faster than repeatedly calling eint1(:math:`i * x)`, but less precise.

ellL1(e, r=0, precision=0)

Returns the value at s = 1 of the derivative of order r of the L-function of the elliptic curve e.

? e = ellinit("11a1"); \\ order of vanishing is 0
? ellL1(e)
%2 = 0.2538418608559106843377589233
? e = ellinit("389a1"); \\ order of vanishing is 2
? ellL1(e)
%4 = -5.384067311837218089235032414 E-29
? ellL1(e, 1)
%5 = 0
? ellL1(e, 2)
%6 = 1.518633000576853540460385214

The main use of this function, after computing at low accuracy the order of vanishing using ellanalyticrank, is to compute the leading term at high accuracy to check (or use) the Birch and Swinnerton-Dyer conjecture:

? \p18
 realprecision = 18 significant digits
? e = ellinit("5077a1"); ellanalyticrank(e)
time = 8 ms.
%1 = [3, 10.3910994007158041]
? \p200
 realprecision = 202 significant digits (200 digits displayed)
? ellL1(e, 3)
time = 104 ms.
%3 = 10.3910994007158041387518505103609170697263563756570092797[...]
elladd(E, z1, z2)

Sum of the points z1 and z2 on the elliptic curve corresponding to E.

ellak(E, n)

Computes the coefficient a_n of the L-function of the elliptic curve E/\mathbb{Q}, i.e. coefficients of a newform of weight 2 by the modularity theorem (Taniyama-Shimura-Weil conjecture). E must be an ell structure over \mathbb{Q} as output by ellinit. E must be given by an integral model, not necessarily minimal, although a minimal model will make the function faster.

? E = ellinit([0,1]);
? ellak(E, 10)
%2 = 0
? e = ellinit([5^4,5^6]); \\ not minimal at 5
? ellak(e, 5) \\ wasteful but works
%3 = -3
? E = ellminimalmodel(e); \\ now minimal
? ellak(E, 5)
%5 = -3

If the model is not minimal at a number of bad primes, then the function will be slower on those n divisible by the bad primes. The speed should be comparable for other n:

? for(i=1,10^6, ellak(E,5))
time = 820 ms.
? for(i=1,10^6, ellak(e,5)) \\ 5 is bad, markedly slower
time = 1,249 ms.

? for(i=1,10^5,ellak(E,5*i))
time = 977 ms.
? for(i=1,10^5,ellak(e,5*i)) \\ still slower but not so much on average
time = 1,008 ms.
ellan(E, n)

Computes the vector of the first n Fourier coefficients a_k corresponding to the elliptic curve E. The curve must be given by an integral model, not necessarily minimal, although a minimal model will make the function faster.

ellanalyticrank(e, eps=None, precision=0)

Returns the order of vanishing at s = 1 of the L-function of the elliptic curve e and the value of the first non-zero derivative. To determine this order, it is assumed that any value less than eps is zero. If no value of eps is given, a value of half the current precision is used.

? e = ellinit("11a1"); \\ rank 0
? ellanalyticrank(e)
%2 = [0, 0.2538418608559106843377589233]
? e = ellinit("37a1"); \\ rank 1
? ellanalyticrank(e)
%4 = [1, 0.3059997738340523018204836835]
? e = ellinit("389a1"); \\ rank 2
? ellanalyticrank(e)
%6 = [2, 1.518633000576853540460385214]
? e = ellinit("5077a1"); \\ rank 3
? ellanalyticrank(e)
%8 = [3, 10.39109940071580413875185035]
ellap(E, p=None)

Let E be an ell structure as output by ellinit, defined over \mathbb{Q} or a finite field \mathbb{F}_q. The argument p is best left omitted if the curve is defined over a finite field, and must be a prime number otherwise. This function computes the trace of Frobenius t for the elliptic curve E, defined by the equation \#E(\mathbb{F}_q) = q+1 - t.

If the curve is defined over \mathbb{Q}, p must be explicitly given and the function computes the trace of the reduction over \mathbb{F}_p. The trace of Frobenius is also the a_p coefficient in the curve L-series L(E,s) = \sum_n a_n n^{-s}, whence the function name. The equation must be integral at p but need not be minimal at p; of course, a minimal model will be more efficient.

? E = ellinit([0,1]); \\ y^2 = x^3 + 0.x + 1, defined over Q
? ellap(E, 7) \\ 7 necessary here
%2 = -4 \\ #E(F_7) = 7+1-(-4) = 12
? ellcard(E, 7)
%3 = 12 \\ OK

? E = ellinit([0,1], 11); \\ defined over F_11
? ellap(E) \\ no need to repeat 11
%4 = 0
? ellap(E, 11) \\ ... but it also works
%5 = 0
? ellgroup(E, 13) \\ ouch, inconsistent input!
 *** at top-level: ellap(E,13)
 *** ^-----------
 *** ellap: inconsistent moduli in Rg_to_Fp:
 11
 13

? Fq = ffgen(ffinit(11,3), 'a); \\ defines F_q := F_{11^3}
? E = ellinit([a+1,a], Fq); \\ y^2 = x^3 + (a+1)x + a, defined over F_q
? ellap(E)
%8 = -3

Algorithms used. If E/\mathbb{F}_q has CM by a principal imaginary quadratic order we use a fast explicit formula (involving essentially Kronecker symbols and Cornacchia’s algorithm), in O(\log q)^2. Otherwise, we use Shanks-Mestre’s baby-step/giant-step method, which runs in time ~{O}(q^{1/4}) using ~{O}(q^{1/4}) storage, hence becomes unreasonable when q has about 30 digits. If the seadata package is installed, the SEA algorithm becomes available, heuristically in ~{O}(\log q)^4, and primes of the order of 200 digits become feasible. In very small characteristic (2,3,5,7 or 13), we use Harley’s algorithm.

ellbil(E, z1, z2, precision=0)

Deprecated alias for ellheight(E,P,Q).

ellcard(E, p=None)

Let E be an ell structure as output by ellinit, defined over \mathbb{Q} or a finite field \mathbb{F}_q. The argument p is best left omitted if the curve is defined over a finite field, and must be a prime number otherwise. This function computes the order of the group E(\mathbb{F}_q) (as would be computed by ellgroup).

If the curve is defined over \mathbb{Q}, p must be explicitly given and the function computes the cardinality of the reduction over \mathbb{F}_p; the equation need not be minimal at p, but a minimal model will be more efficient. The reduction is allowed to be singular, and we return the order of the group of non-singular points in this case.

ellchangecurve(E, v)

Changes the data for the elliptic curve E by changing the coordinates using the vector v = [u,r,s,t], i.e. if x' and y' are the new coordinates, then x = u^2x'+r, y = u^3y'+su^2x'+t. E must be an ell structure as output by ellinit. The special case v = 1 is also used instead of [1,0,0,0] to denote the trivial coordinate change.

ellchangepoint(x, v)

Changes the coordinates of the point or vector of points x using the vector v = [u,r,s,t], i.e. if x' and y' are the new coordinates, then x = u^2x'+r, y = u^3y'+su^2x'+t (see also ellchangecurve).

? E0 = ellinit([1,1]); P0 = [0,1]; v = [1,2,3,4];
? E = ellchangecurve(E0, v);
? P = ellchangepoint(P0,v)
%3 = [-2, 3]
? ellisoncurve(E, P)
%4 = 1
? ellchangepointinv(P,v)
%5 = [0, 1]
ellchangepointinv(x, v)

Changes the coordinates of the point or vector of points x using the inverse of the isomorphism associated to v = [u,r,s,t], i.e. if x' and y' are the old coordinates, then x = u^2x'+r, y = u^3y'+su^2x'+t (inverse of ellchangepoint).

? E0 = ellinit([1,1]); P0 = [0,1]; v = [1,2,3,4];
? E = ellchangecurve(E0, v);
? P = ellchangepoint(P0,v)
%3 = [-2, 3]
? ellisoncurve(E, P)
%4 = 1
? ellchangepointinv(P,v)
%5 = [0, 1] \\ we get back P0
ellconvertname(name)

Converts an elliptic curve name, as found in the elldata database, from a string to a triplet [conductor, isogeny class,
index]. It will also convert a triplet back to a curve name. Examples:

? ellconvertname("123b1")
%1 = [123, 1, 1]
? ellconvertname(%)
%2 = "123b1"
elldivpol(E, n, v=None)

n-division polynomial f_n for the curve E in the variable v. In standard notation, for any affine point P = (X,Y) on the curve, we have

[n]P = (\phi_n(P)\psi_n(P) : \omega_n(P) : \psi_n(P)^3)

for some polynomials \phi_n,\omega_n,\psi_n in \mathbb{Z}[a_1,a_2,a_3,a_4,a_6][X,Y]. We have f_n(X) = \psi_n(X) for n odd, and f_n(X) = \psi_n(X,Y) (2Y + a_1X+a_3) for n even. We have

f_1 = 1, f_2 = 4X^3 + b_2X^2 + 2b_4 X + b_6, f_3 = 3 X^4 + b_2 X^3 + 3b_4 X^2 + 3 b_6 X + b8,

f_4 = f_2(2X^6 + b_2 X^5 + 5b_4 X^4 + 10 b_6 X^3 + 10 b_8 X^2 +
(b_2b_8-b_4b_6)X + (b_8b_4 - b_6^2)),...

For n >= 2, the roots of f_n are the X-coordinates of points in E[n].

elleisnum(w, k, flag=0, precision=0)

k being an even positive integer, computes the numerical value of the Eisenstein series of weight k at the lattice w, as given by ellperiods, namely

(2i \Pi/\omega_2)^k
(1 + 2/\zeta(1-k) \sum_{n >= 1} n^{k-1}q^n / (1-q^n)),

where q = \exp(2i\Pi \tau) and \tau := \omega_1/\omega_2 belongs to the complex upper half-plane. It is also possible to directly input w = 
[\omega_1,\omega_2], or an elliptic curve E as given by ellinit.

? w = ellperiods([1,I]);
? elleisnum(w, 4)
%2 = 2268.8726415508062275167367584190557607
? elleisnum(w, 6)
%3 = -3.977978632282564763 E-33
? E = ellinit([1, 0]);
? elleisnum(E, 4, 1)
%5 = -47.999999999999999999999999999999999998

When flag is non-zero and k = 4 or 6, returns the elliptic invariants g_2 or g_3, such that

y^2 = 4x^3 - g_2 x - g_3

is a Weierstrass equation for E.

elleta(w, precision=0)

Returns the quasi-periods [\eta_1,\eta_2] associated to the lattice basis w = [\omega_1, \omega_2]. Alternatively, w can be an elliptic curve E as output by ellinit, in which case, the quasi periods associated to the period lattice basis :math:`E.omega` (namely, :math:`E.eta`) are returned.

? elleta([1, I])
%1 = [3.141592653589793238462643383, 9.424777960769379715387930149*I]
ellformaldifferential(E, serprec=-1, n=None)

Let \omega := dx / (2y+a_1x+a_3 be the invariant differential form associated to the model E of some elliptic curve (ellinit form), and \eta := x(t)\omega. Return n terms (seriesprecision by default) of f(t),g(t) two power series in the formal parameter t = -x/y such that \omega = f(t) dt, \eta = g(t) dt:

f(t) = 1+a_1 t + (a_1^2 + a_2) t^2 +..., 
g(t) = t^{-2} +...

? E = ellinit([-1,1/4]); [f,g] = ellformaldifferential(E,7,'t);
? f
%2 = 1 - 2*t^4 + 3/4*t^6 + O(t^7)
? g
%3 = t^-2 - t^2 + 1/2*t^4 + O(t^5)
ellformalexp(E, serprec=-1, n=None)

The elliptic formal exponential Exp attached to E is the isomorphism from the formal additive law to the formal group of E. It is normalized so as to be the inverse of the elliptic logarithm (see ellformallog): Exp o L = \mathrm{Id}. Return n terms of this power series:

? E=ellinit([-1,1/4]); Exp = ellformalexp(E,10,'z)
%1 = z + 2/5*z^5 - 3/28*z^7 + 2/15*z^9 + O(z^11)
? L = ellformallog(E,10,'t);
? subst(Exp,z,L)
%3 = t + O(t^11)
ellformallog(E, serprec=-1, n=None)

The formal elliptic logarithm is a series L in t K[[t]] such that d L = \omega = dx / (2y + a_1x + a_3, the canonical invariant differential attached to the model E. It gives an isomorphism from the formal group of E to the additive formal group.

? E = ellinit([-1,1/4]); L = ellformallog(E, 9, 't)
%1 = t - 2/5*t^5 + 3/28*t^7 + 2/3*t^9 + O(t^10)
? [f,g] = ellformaldifferential(E,8,'t);
? L' - f
%3 = O(t^8)
ellformalpoint(E, serprec=-1, n=None)

If E is an elliptic curve, return the coordinates x(t), y(t) in the formal group of the elliptic curve E in the formal parameter t = -x/y at oo:

x = t^{-2} -a_1 t^{-1} - a_2 - a_3 t +...

y = - t^{-3} -a_1 t^{-2} - a_2t^{-1} -a_3 +...

Return n terms (seriesprecision by default) of these two power series, whose coefficients are in \mathbb{Z}[a_1,a_2,a_3,a_4,a_6].

? E = ellinit([0,0,1,-1,0]); [x,y] = ellformalpoint(E,8);
? x
%2 = x^-2 - x + x^2 - x^4 + 2*x^5 + O(x^6)
? y
%3 = -x^-3 + 1 - x + x^3 - 2*x^4 + O(x^5)
? E = ellinit([0,1/2]); ellformalpoint(E,7)
%4 = [x^-2 - 1/2*x^4 + O(x^5), -x^-3 + 1/2*x^3 + O(x^4)]
ellformalw(E, serprec=-1, n=None)

Return the formal power series w associated to the elliptic curve E, in the variable t:

w(t) = t^3 + a_1 t^4 + (a_2 + a_1^2) t^5 +...+ O(t^{n+3}),

which is the formal expansion of -1/y in the formal parameter t := -x/y at oo (take n = seriesprecision if n is omitted). The coefficients of w belong to \mathbb{Z}[a_1,a_2,a_3,a_4,a_6].

? E=ellinit([3,2,-4,-2,5]); ellformalw(E, 5, 't)
%1 = t^3 + 3*t^4 + 11*t^5 + 35*t^6 + 101*t^7 + O(t^8)
ellfromeqn(P)

Given a genus 1 plane curve, defined by the affine equation f(x,y) = 0, return the coefficients [a_1,a_2,a_3,a_4,a_6] of a Weierstrass equation for its Jacobian. This allows to recover a Weierstrass model for an elliptic curve given by a general plane cubic or by a binary quartic or biquadratic model.

The function implements the f :---> f^* formulae of Artin, Tate and Villegas (Advances in Math. 198 (2005), pp. 366–382).

In the example below, the function is used to convert between twisted Edward coordinates and Weierstrass coordinates.

? e = ellfromeqn(a*x^2+y^2-(1+d*x^2*y^2))
%1 = [0,-a-d,0,-4*d*a,4*d*a^2+4*d^2*a]
? E = ellinit(ellfromeqn(y^2-x^2 - 1 +(121665/121666*x^2*y^2)),2^255-19);
? ellcard(E)
%2 = 57896044618658097711785492504343953926856930875039260848015607506283634007912

The elliptic curve associated to the sum of two cubes is given by

? ellfromeqn(x^3+y^3-a)
%1 = [0,0,-9*a,0,-27*a^2]

Congruent number problem: Let n be an integer, if a^2+b^2 = c^2 and a b = 2 n, then by substituting b by 2 n/a in the first equation, we get ((a^2+(2 n/a)^2)-c^2)*a^2 = 0. We set x = a, y = a*c.

? ellfromeqn((x^2+(2*n/x)^2-(y/x)^2)*x^2)
%1 = [0,0,0,-16*n^2,0]

For example 23 is congruent since the curve has a point of infinite order, namely:

? ellheegner(ellinit(subst([0,0,0,-16*n^2,0],n,23)))
%2 = [168100/289,68053440/4913]
ellfromj(j)

Returns the coefficients [a_1,a_2,a_3,a_4,a_6] of a fixed elliptic curve with j-invariant j.

ellgenerators(E)

If E is an elliptic curve over the rationals, return a \mathbb{Z}-basis of the free part of the Mordell-Weil group associated to E. This relies on the elldata database being installed and referencing the curve, and so is only available for curves over \mathbb{Z} of small conductors. If E is an elliptic curve over a finite field \mathbb{F}_q as output by ellinit, return a minimal set of generators for the group E(\mathbb{F}_q).

ellglobalred(E)

Calculates the arithmetic conductor, the global minimal model of E and the global Tamagawa number c. E must be an ell structure as output by ellinit, defined over \mathbb{Q}. The result is a vector [N,v,c,F,L], where

  • N is the arithmetic conductor of the curve,
  • v gives the coordinate change for E over \mathbb{Q} to the minimal integral model (see ellminimalmodel),
  • c is the product of the local Tamagawa numbers c_p, a quantity which enters in the Birch and Swinnerton-Dyer conjecture,
  • F is the factorization of N over \mathbb{Z}.
  • L is a vector, whose i-th entry contains the local data at the i-th prime divisor of N, i.e. L[i] = elllocalred(E,F[i,1]), where the local coordinate change has been deleted, and replaced by a 0.
ellgroup(E, p=None, flag=0)

Let E be an ell structure as output by ellinit, defined over \mathbb{Q} or a finite field \mathbb{F}_q. The argument p is best left omitted if the curve is defined over a finite field, and must be a prime number otherwise. This function computes the structure of the group E(\mathbb{F}_q) ~ \mathbb{Z}/d_1\mathbb{Z}
x \mathbb{Z}/d_2\mathbb{Z}, with d_2 \| d_1.

If the curve is defined over \mathbb{Q}, p must be explicitly given and the function computes the structure of the reduction over \mathbb{F}_p; the equation need not be minimal at p, but a minimal model will be more efficient. The reduction is allowed to be singular, and we return the structure of the (cyclic) group of non-singular points in this case.

If the flag is 0 (default), return [d_1] or [d_1, d_2], if d_2 > 1. If the flag is 1, return a triple [h,cyc,gen], where h is the curve cardinality, cyc gives the group structure as a product of cyclic groups (as per flag = 0). More precisely, if d_2 > 1, the output is [d_1d_2, [d_1,d_2],[P,Q]] where P is of order d_1 and [P,Q] generates the curve. Caution. It is not guaranteed that Q has order d_2, which in the worst case requires an expensive discrete log computation. Only that ellweilpairing(E, P, Q, d1) has order d_2.

? E = ellinit([0,1]); \\ y^2 = x^3 + 0.x + 1, defined over Q
? ellgroup(E, 7)
%2 = [6, 2] \\ Z/6 x Z/2, non-cyclic
? E = ellinit([0,1] * Mod(1,11)); \\ defined over F_11
? ellgroup(E) \\ no need to repeat 11
%4 = [12]
? ellgroup(E, 11) \\ ... but it also works
%5 = [12]
? ellgroup(E, 13) \\ ouch, inconsistent input!
 *** at top-level: ellgroup(E,13)
 *** ^--------------
 *** ellgroup: inconsistent moduli in Rg_to_Fp:
 11
 13
? ellgroup(E, 7, 1)
%6 = [12, [6, 2], [[Mod(2, 7), Mod(4, 7)], [Mod(4, 7), Mod(4, 7)]]]

If E is defined over \mathbb{Q}, we allow singular reduction and in this case we return the structure of the group of non-singular points, satisfying \#E_{ns}(\mathbb{F}_p) = p - a_p.

? E = ellinit([0,5]);
? ellgroup(E, 5, 1)
%2 = [5, [5], [[Mod(4, 5), Mod(2, 5)]]]
? ellap(E, 5)
%3 = 0 \\ additive reduction at 5
? E = ellinit([0,-1,0,35,0]);
? ellgroup(E, 5, 1)
%5 = [4, [4], [[Mod(2, 5), Mod(2, 5)]]]
? ellap(E, 5)
%6 = 1 \\ split multiplicative reduction at 5
? ellgroup(E, 7, 1)
%7 = [8, [8], [[Mod(3, 7), Mod(5, 7)]]]
? ellap(E, 7)
%8 = -1 \\ non-split multiplicative reduction at 7
ellheegner(E)

Let E be an elliptic curve over the rationals, assumed to be of (analytic) rank 1. This returns a non-torsion rational point on the curve, whose canonical height is equal to the product of the elliptic regulator by the analytic Sha.

This uses the Heegner point method, described in Cohen GTM 239; the complexity is proportional to the product of the square root of the conductor and the height of the point (thus, it is preferable to apply it to strong Weil curves).

? E = ellinit([-157^2,0]);
? u = ellheegner(E); print(u[1], "\n", u[2])
69648970982596494254458225/166136231668185267540804
538962435089604615078004307258785218335/67716816556077455999228495435742408
? ellheegner(ellinit([0,1])) \\ E has rank 0 !
 *** at top-level: ellheegner(E=ellinit
 *** ^--------------------
 *** ellheegner: The curve has even analytic rank.
ellheight(E, P, Q=None, precision=0)

Global Néron-Tate height h(P) of the point P on the elliptic curve E/\mathbb{Q}, using the normalization in Cremona’s Algorithms for modular elliptic curves. E must be an ell as output by ellinit; it needs not be given by a minimal model although the computation will be faster if it is.

If the argument Q is present, computes the value of the bilinear form (h(P+Q)-h(P-Q)) / 4.

ellheightmatrix(E, x, precision=0)

x being a vector of points, this function outputs the Gram matrix of x with respect to the Néron-Tate height, in other words, the (i,j) component of the matrix is equal to ellbil(:math:`E,x[i],x[j])`. The rank of this matrix, at least in some approximate sense, gives the rank of the set of points, and if x is a basis of the Mordell-Weil group of E, its determinant is equal to the regulator of E. Note our height normalization follows Cremona’s Algorithms for modular elliptic curves: this matrix should be divided by 2 to be in accordance with, e.g., Silverman’s normalizations.

ellidentify(E)

Look up the elliptic curve E, defined by an arbitrary model over \mathbb{Q}, in the elldata database. Return [[N, M, G], C] where N is the curve name in Cremona’s elliptic curve database, M is the minimal model, G is a \mathbb{Z}-basis of the free part of the Mordell-Weil group E(\mathbb{Q}) and C is the change of coordinates change, suitable for ellchangecurve.

ellinit(x, D=None, precision=0)

Initialize an ell structure, associated to the elliptic curve E. E is either

  • a 5-component vector [a_1,a_2,a_3,a_4,a_6] defining the elliptic curve with Weierstrass equation

Y^2 + a_1 XY + a_3 Y = X^3 + a_2 X^2 + a_4 X + a_6,

  • a 2-component vector [a_4,a_6] defining the elliptic curve with short Weierstrass equation

Y^2 = X^3 + a_4 X + a_6,

  • a character string in Cremona’s notation, e.g. "11a1", in which case the curve is retrieved from the elldata database if available.

The optional argument D describes the domain over which the curve is defined:

  • the t_INT 1 (default): the field of rational numbers \mathbb{Q}.
  • a t_INT p, where p is a prime number: the prime finite field \mathbb{F}_p.
  • an t_INTMOD Mod(a, p), where p is a prime number: the prime finite field \mathbb{F}_p.
  • a t_FFELT, as returned by ffgen: the corresponding finite field \mathbb{F}_q.
  • a t_PADIC, O(p^n): the field \mathbb{Q}_p, where p-adic quantities will be computed to a relative accuracy of n digits. We advise to input a model defined over \mathbb{Q} for such curves. In any case, if you input an approximate model with t_PADIC coefficients, it will be replaced by a lift to \mathbb{Q} (an exact model “close” to the one that was input) and all quantities will then be computed in terms of this lifted model, at the given accuracy.
  • a t_REAL x: the field \mathbb{C} of complex numbers, where floating point quantities are by default computed to a relative accuracy of precision(x). If no such argument is given, the value of realprecision at the time ellinit is called will be used.
  • a number field K, given by a nf or bnf structure.
  • a prime ideal p, given by a prid structure; valid if x is a curve defined over a number field K and the equation is integral and minimal at p.

This argument D is indicative: the curve coefficients are checked for compatibility, possibly changing D; for instance if D = 1 and an t_INTMOD is found. If inconsistencies are detected, an error is raised:

? ellinit([1 + O(5), 1], O(7));
 *** at top-level: ellinit([1+O(5),1],O
 *** ^--------------------
 *** ellinit: inconsistent moduli in ellinit: 7 != 5

If the curve coefficients are too general to fit any of the above domain categories, only basic operations, such as point addition, will be supported later.

If the curve (seen over the domain D) is singular, fail and return an empty vector [].

? E = ellinit([0,0,0,0,1]); \\ y^2 = x^3 + 1, over Q
? E = ellinit([0,1]); \\ the same curve, short form
? E = ellinit("36a1"); \\ sill the same curve, Cremona's notations
? E = ellinit([0,1], 2) \\ over F2: singular curve
%4 = []
? E = ellinit(['a4,'a6] * Mod(1,5)); \\ over F_5[a4,a6], basic support !

The result of ellinit is an ell structure. It contains at least the following information in its components:

a_1,a_2,a_3,a_4,a_6,b_2,b_4,b_6,b_8,c_4,c_6,\Delta,j.

All are accessible via member functions. In particular, the discriminant is :math:`E.disc`, and the j-invariant is :math:`E.j`.

? E = ellinit([a4, a6]);
? E.disc
%2 = -64*a4^3 - 432*a6^2
? E.j
%3 = -6912*a4^3/(-4*a4^3 - 27*a6^2)

Further components contain domain-specific data, which are in general dynamic: only computed when needed, and then cached in the structure.

? E = ellinit([2,3], 10^60+7); \\ E over F_p, p large
? ellap(E)
time = 4,440 ms.
%2 = -1376268269510579884904540406082
? ellcard(E); \\ now instantaneous !
time = 0 ms.
? ellgenerators(E);
time = 5,965 ms.
? ellgenerators(E); \\ second time instantaneous
time = 0 ms.

See the description of member functions related to elliptic curves at the beginning of this section.

ellisogeny(E, G, only_image=0, x=None, y=None)

Given an elliptic curve E, a finite subgroup G of E is given either as a generating point P (for a cyclic G) or as a polynomial whose roots vanish on the x-coordinates of the non-zero elements of G (general case and more efficient if available). This function returns the [a_1,a_2,a_3,a_4,a_6] invariants of the quotient elliptic curve E/G and (if only_image is zero (the default)) a vector of rational functions [f, g, h] such that the isogeny E \\to E/G is given by (x,y)
:--->(f(x)/h(x)^2, g(x,y)/h(x)^3).

? E = ellinit([0,1]);
? elltors(E)
%2 = [6, [6], [[2, 3]]]
? ellisogeny(E, [2,3], 1) \\ Weierstrass model for E/<P>
%3 = [0, 0, 0, -135, -594]
? ellisogeny(E,[-1,0])
%4 = [[0,0,0,-15,22], [x^3+2*x^2+4*x+3, y*x^3+3*y*x^2-2*y, x+1]]
ellisogenyapply(f, g)

Given an isogeny of elliptic curves f:E'\\to E (being the result of a call to ellisogeny), apply f to x:

  • if x is a point P in the domain of f, return the image f(P);
  • if x is a compatible isogeny g:E"\\to E', return the composite isogeny f o g: E"\to E.
? one = ffgen(101, 't)^0;
? E = ellinit([6, 53, 85, 32, 34] * one);
? P = [84, 71] * one;
? ellorder(E, P)
%4 = 5
? [F, f] = ellisogeny(E, P); \\ f: E->F = E/<P>
? ellisogenyapply(f, P)
%6 = [0]
? F = ellinit(F);
? Q = [89, 44] * one;
? ellorder(F, Q)
%9 = 2;
? [G, g] = ellisogeny(F, Q); \\ g: F->G = F/<Q>
? gof = ellisogenyapply(g, f); \\ gof: E -> G
ellisoncurve(E, z)

Gives 1 (i.e. true) if the point z is on the elliptic curve E, 0 otherwise. If E or z have imprecise coefficients, an attempt is made to take this into account, i.e. an imprecise equality is checked, not a precise one. It is allowed for z to be a vector of points in which case a vector (of the same type) is returned.

ellissupersingular(E, p=None)

Return 1 if the elliptic curve E defined over Q or a finite field is supersingular at p, and 0 otherwise. If the curve is defined over \mathbb{Q}, p must be explicitly given and have good reduction at p. Alternatively, E can be given byt its j-invariant in a finite field. In this case p must be omitted.

? g = ffprimroot(ffgen(7^5))
%1 = x^3 + 2*x^2 + 3*x + 1
? [g^n | n <- [1 .. 7^5 - 1], ellissupersingular(g^n)]
%2 = [6]
ellj(x, precision=0)

Elliptic j-invariant. x must be a complex number with positive imaginary part, or convertible into a power series or a p-adic number with positive valuation.

elllocalred(E, p)

Calculates the Kodaira type of the local fiber of the elliptic curve E at p. E must be an ell structure as output by ellinit, over \mathbb{Q} (p a rational prime) or a number field K (p a maximal ideal given by a prid structure), and is assumed to have all its coefficients a_i integral. The result is a 4-component vector [f,kod,v,c]. Here f is the exponent of p in the arithmetic conductor of E, and kod is the Kodaira type which is coded as follows:

1 means good reduction (type I:math:_0), 2, 3 and 4 mean types II, III and IV respectively, 4+\nu with \nu > 0 means type I:math:_\nu; finally the opposite values -1, -2, etc. refer to the starred types I:math:_0^*, II:math:^*, etc. The third component v is itself a vector [u,r,s,t] giving the coordinate changes done during the local reduction; u = 1 if and only if the given equation was already minimal at p. Finally, the last component c is the local Tamagawa number c_p.

Caveat. If E is not defined over \mathbb{Q}, the current implementation requires that p be above a prime >= 5.

elllog(E, P, G, o=None)

Given two points P and G on the elliptic curve E/\mathbb{F}_q, returns the discrete logarithm of P in base G, i.e. the smallest non-negative integer n such that P = [n]G. See znlog for the limitations of the underlying discrete log algorithms. If present, o represents the order of G, see DLfun (in the PARI manual); the preferred format for this parameter is [N, factor(N)], where N is the order of G.

If no o is given, assume that G generates the curve. The function also assumes that P is a multiple of G.

? a = ffgen(ffinit(2,8),'a);
? E = ellinit([a,1,0,0,1]); \\ over F_{2^8}
? x = a^3; y = ellordinate(E,x)[1];
? P = [x,y]; G = ellmul(E, P, 113);
? ord = [242, factor(242)]; \\ P generates a group of order 242. Initialize.
? ellorder(E, G, ord)
%4 = 242
? e = elllog(E, P, G, ord)
%5 = 15
? ellmul(E,G,e) == P
%6 = 1
elllseries(E, s, A=None, precision=0)

E being an elliptic curve, given by an arbitrary model over \mathbb{Q} as output by ellinit, this function computes the value of the L-series of E at the (complex) point s. This function uses an O(N^{1/2}) algorithm, where N is the conductor.

The optional parameter A fixes a cutoff point for the integral and is best left omitted; the result must be independent of A, up to realprecision, so this allows to check the function’s accuracy.

ellmul(E, z, n)

Computes [n]z, where z is a point on the elliptic curve E. The exponent n is in \mathbb{Z}, or may be a complex quadratic integer if the curve E has complex multiplication by n (if not, an error message is issued).

? Ei = ellinit([1,0]); z = [0,0];
? ellmul(Ei, z, 10)
%2 = [0] \\ unsurprising: z has order 2
? ellmul(Ei, z, I)
%3 = [0, 0] \\ Ei has complex multiplication by Z[i]
? ellmul(Ei, z, quadgen(-4))
%4 = [0, 0] \\ an alternative syntax for the same query
? Ej = ellinit([0,1]); z = [-1,0];
? ellmul(Ej, z, I)
 *** at top-level: ellmul(Ej,z,I)
 *** ^--------------
 *** ellmul: not a complex multiplication in ellmul.
? ellmul(Ej, z, 1+quadgen(-3))
%6 = [1 - w, 0]

The simple-minded algorithm for the CM case assumes that we are in characteristic 0, and that the quadratic order to which n belongs has small discriminant.

ellneg(E, z)

Opposite of the point z on elliptic curve E.

ellnonsingularmultiple(E, P)

Given an elliptic curve E/\mathbb{Q} (more precisely, a model defined over \mathbb{Q} of a curve) and a rational point P belongs to E(\mathbb{Q}), returns the pair [R,n], where n is the least positive integer such that R := [n]P has good reduction at every prime. More precisely, its image in a minimal model is everywhere non-singular.

? e = ellinit("57a1"); P = [2,-2];
? ellnonsingularmultiple(e, P)
%2 = [[1, -1], 2]
? e = ellinit("396b2"); P = [35, -198];
? [R,n] = ellnonsingularmultiple(e, P);
? n
%5 = 12
ellorder(E, z, o=None)

Gives the order of the point z on the elliptic curve E, defined over a finite field or a number field. Return (the impossible value) zero if the point has infinite order.

? E = ellinit([-157^2,0]); \\ the "157-is-congruent" curve
? P = [2,2]; ellorder(E, P)
%2 = 2
? P = ellheegner(E); ellorder(E, P) \\ infinite order
%3 = 0
? K = nfinit(polcyclo(11,t)); E=ellinit("11a3", K); T = elltors(E);
? ellorder(E, T.gen[1])
%5 = 25
? E = ellinit(ellfromj(ffgen(5^10)));
? ellcard(E)
%7 = 9762580
? P = random(E); ellorder(E, P)
%8 = 4881290
? p = 2^160+7; E = ellinit([1,2], p);
? N = ellcard(E)
%9 = 1461501637330902918203686560289225285992592471152
? o = [N, factor(N)];
? for(i=1,100, ellorder(E,random(E)))
time = 260 ms.

The parameter o, is now mostly useless, and kept for backward compatibility. If present, it represents a non-zero multiple of the order of z, see DLfun (in the PARI manual); the preferred format for this parameter is [ord, factor(ord)], where ord is the cardinality of the curve. It is no longer needed since PARI is now able to compute it over large finite fields (was restricted to small prime fields at the time this feature was introduced), and caches the result in E so that it is computed and factored only once. Modifying the last example, we see that including this extra parameter provides no improvement:

? o = [N, factor(N)];
? for(i=1,100, ellorder(E,random(E),o))
time = 260 ms.
ellordinate(E, x, precision=0)

Gives a 0, 1 or 2-component vector containing the y-coordinates of the points of the curve E having x as x-coordinate.

ellpadicL(E, p, n, r=0, D=None, character=None)

The p-adic L function is defined on the set of continuous characters of {Gal}(\mathbb{Q}(\mu_{p^{ oo }})/ \mathbb{Q}), identified to \mathbb{Z}_p^* via the cyclotomic character \chi_p with values in \\overline{Q_p}^*. Denote by tau:\mathbb{Z}_p^*\\to\mathbb{Z}_p^* the Teichmüller character.

When E has good supersingular reduction, the L function takes its values in \mathbb{Q}_p \\otimes H^1_{dR}(E/\mathbb{Q}) and satisfies

(1-p^{-1} F)^{-2} L_p(E, \tau^0) = (L(E,1) / \Omega).\omega

where F is the Frobenius, L(E,1) is the value of the complex L function at 1, \omega is the Néron differential and \Omega its associated period on E(\mathbb{R}). Here, \tau^0 represents the trivial character.

The derivative is taken at s = 1 along <\chi_p^s>. In other words, the function L_p is defined as \int_{\mathbb{Z}_p^*} d \mu for a certain p-adic distribution \mu on \mathbb{Z}_p^*, and we have

L_p^{(r)}(E, \tau^0) = \int_{\mathbb{Z}_p^*} \log_p^r(a) d\mu(a).

The function returns the components of L_p{(r)}(E,\tau^0) in the basis (\omega, F(\omega)).

When E has ordinary good reduction, this method only defines the projection of L_p(E,\tau^0) on the \alpha-eigenspace, where \alpha is the unit eigenvalue for F. This is what the function returns. This value satisfies

(1- \alpha^{-1})^{-2} L_{p,\alpha}(E,\tau^0) = L(E,1) / \Omega.

? cxL(e) = bestappr( ellL1(e,0) / e.omega[1] );

? e = ellinit("17a1"); p=3; \\ supersingular
? L = ellpadicL(e,p,4);
? F = [0,-p;1,ellap(e,p)]; \\ Frobenius matrix in the basis (omega,F(omega)
? (1-p^(-1)*F)^-2 * L~ / cxL(e)
%4 = [1 + O(3^4), O(3^4)]~

? p=5; ap = ellap(e,p); \\ ordinary
? L = ellpadicL(e,p,4);
? al = padicappr(x^2 - ap*x + p, ap + O(p^7))[1];
? (1-al^(-1))^(-2) * L / cxL(e)
%8 = 1 + O(5^4)

? e = ellinit("116a1"); p=3; \\ supersingular
? L = ellpadicL(e,p,4);
? F = [0,-p; 1,ellap(e,p)];
? (1-p^(-1)*F)^-2*L~ / cxL(e)
%12 = [1 + O(3^4), O(3^5)]~

? e = ellinit("26b1"); p=3;
? L = ellpadicL(e,p,4);
? F = [0,-p;1,ellap(e,p)];
? (1-p^(-1)*F)^-2*L~ / cxL(e)
%16 = [1 + O(3^4), O(3^5)]~
ellpadicfrobenius(E, p, n)

If p > 2 is a prime and E is a elliptic curve on \mathbb{Q} with good reduction at p, return the matrix of the Frobenius endomorphism \varphi on the crystalline module D_p(E) = \mathbb{Q}_p \\otimes H^1_{dR}(E/\mathbb{Q}) with respect to the basis of the given model (\omega, \eta = x \omega), where \omega = dx/(2 y+a_1 x+a_3) is the invariant differential. The characteristic polynomial of \varphi is x^2 - a_p x + p. The matrix is computed to absolute p-adic precision p^n.

? E = ellinit([1,-1,1,0,0]);
? F = ellpadicfrobenius(E,5,3);
? lift(F)
%3 =
[120 29]

[ 55 5]
? charpoly(F)
%4 = x^2 + O(5^3)*x + (5 + O(5^3))
? ellap(E, 5)
%5 = 0
ellpadicheight(E, p, n, P, Q=None)

Cyclotomic p-adic height of the rational point P on the elliptic curve E (defined over \mathbb{Q}), given to n p-adic digits. If the argument Q is present, computes the value of the bilinear form (h(P+Q)-h(P-Q)) / 4.

Let D_{dR}(E) := H^1_{dR}(E) \\otimes_\mathbb{Q} \mathbb{Q}_p be the \mathbb{Q}_p vector space spanned by \omega (invariant differential dx/(2y+a_1x+a3) related to the given model) and \eta = x \omega. Then the cyclotomic p-adic height associates to P belongs to E(\mathbb{Q}) an element f \omega + g\eta in D_{dR}. This routine returns the vector [f, g] to n p-adic digits.

If P belongs to E(\mathbb{Q}) is in the kernel of reduction mod p and if its reduction at all finite places is non singular, then g = -(\log_E P)^2, where \log_E is the logarithm for the formal group of E at p.

If furthermore the model is of the form Y^2 = X^3 + a X + b and P = (x,y), then

f = \log_p(denominator(x)) - 2 \log_p(\sigma(P))

where \sigma(P) is given by ellsigma(E,P).

Recall (Advanced topics in the arithmetic of elliptic curves, Theorem 3.2) that the local height function over the complex numbers is of the form

\lambda(z) = -\log (\|E.disc\|) / 6 + \Re(z \eta(z)) - 2 \log(
\sigma(z).

(N.B. our normalization for local and global heights is twice that of Silverman’s).

? E = ellinit([1,-1,1,0,0]); P = [0,0];
? ellpadicheight(E,5,4, P)
%2 = [3*5 + 5^2 + 2*5^3 + O(5^4), 5^2 + 4*5^4 + O(5^6)]
? E = ellinit("11a1"); P = [5,5]; \\ torsion point
? ellpadicheight(E,19,6, P)
%4 = O(19^6)
? E = ellinit([0,0,1,-4,2]); P = [-2,1];
? ellpadicheight(E,3,5, P)
%6 = [2*3^2 + 2*3^3 + 3^4 + O(3^5), 2*3^2 + 3^4 + 2*3^5 + 3^6 + O(3^7)]
? ellpadicheight(E,3,5, P, elladd(E,P,P))

One can replace the parameter p prime by a vector [p,[a,b]], in which case the routine returns the p-adic number af + bg.

When E has good ordinary reduction at p, the “canonical” p-adic height is given by

s2 = ellpadics2(E,p,n);
ellpadicheight(E, [p,[1,-s2]], n, P)

Since s_2 does not depend on P, it is preferable to compute it only once:

? E = ellinit("5077a1"); p = 5; n = 7;
? s2 = ellpadics2(E,p,n);
? M = ellpadicheightmatrix(E,[p,[1,-s2]], n, E.gen);
? matdet(M) \\ p-adic regulator
%4 = 5 + 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 5^6 + O(5^7)
ellpadicheightmatrix(E, p, n, v)

v being a vector of points, this function outputs the Gram matrix of v with respect to the cyclotomic p-adic height, given to n p-adic digits; in other words, the (i,j) component of the matrix is equal to ellpadicheight(E,p,n, v[i],v[j]) = [f,g].

See ellpadicheight; in particular one can replace the parameter p prime by a vector [p,[a,b]], in which case the routine returns the matrix containing the p-adic numbers af + bg.

ellpadiclog(E, p, n, P)

Given E defined over K = \mathbb{Q} or \mathbb{Q}_p and P = [x,y] on E(K) in the kernel of reduction mod p, let t(P) = -x/y be the formal group parameter; this function returns L(t), where L denotes the formal logarithm (mapping the formal group of E to the additive formal group) attached to the canonical invariant differential: dL = dx/(2y + a_1x + a_3).

ellpadics2(E, p, n)

If p > 2 is a prime and E/\mathbb{Q} is a elliptic curve with ordinary good reduction at p, returns the slope of the unit eigenvector of ellpadicfrobenius(E,p,n), i.e. the action of Frobenius \varphi on the crystalline module D_p(E) = \mathbb{Q}_p \\otimes H^1_{dR}(E/\mathbb{Q}) in the basis of the given model (\omega, \eta = x \omega), where \omega is the invariant differential dx/(2 y+a_1 x+a_3). In other words, \eta + s_2\omega is an eigenvector for the unit eigenvalue of \varphi.

This slope is the unique c belongs to 3^{-1}\mathbb{Z}_p such that the odd solution \sigma(t) = t + O(t^2) of

- d((1)/(\sigma) (d \sigma)/(\omega))
= (x(t) + c) \omega

is in t\mathbb{Z}_p[[t]].

It is equal to b_2/12 - E_2/12 where E_2 is the value of the Katz p-adic Eisenstein series of weight 2 on (E,\omega). This is used to construct a canonical p-adic height when E has good ordinary reduction at p as follows

s2 = ellpadics2(E,p,n);
h(E,p,n, P, s2) = ellpadicheight(E, [p,[1,-s2]],n, P);

Since s_2 does not depend on the point P, we compute it only once.

ellperiods(w, flag=0, precision=0)

Let w describe a complex period lattice (w = [w_1,w_2] or an ellinit structure). Returns normalized periods [W_1,W_2] generating the same lattice such that \tau := W_1/W_2 has positive imaginary part and lies in the standard fundamental domain for {SL}_2(\mathbb{Z}).

If flag = 1, the function returns [[W_1,W_2], [\eta_1,\eta_2]], where \eta_1 and \eta_2 are the quasi-periods associated to [W_1,W_2], satisfying \eta_1 W_2 - \eta_2 W_1 = 2 i \Pi.

The output of this function is meant to be used as the first argument given to ellwp, ellzeta, ellsigma or elleisnum. Quasi-periods are needed by ellzeta and ellsigma only.

ellpointtoz(E, P, precision=0)

If E/\mathbb{C} ~ \mathbb{C}/\Lambda is a complex elliptic curve (\Lambda = 
E.omega), computes a complex number z, well-defined modulo the lattice \Lambda, corresponding to the point P; i.e. such that P = [\wp_\Lambda(z),\wp'_\Lambda(z)] satisfies the equation

y^2 = 4x^3 - g_2 x - g_3,

where g_2, g_3 are the elliptic invariants.

If E is defined over \mathbb{R} and P belongs to E(\mathbb{R}), we have more precisely, 0 \\leq
\Re(t) < w1 and 0 <= \Im(t) < \Im(w2), where (w1,w2) are the real and complex periods of E.

? E = ellinit([0,1]); P = [2,3];
? z = ellpointtoz(E, P)
%2 = 3.5054552633136356529375476976257353387
? ellwp(E, z)
%3 = 2.0000000000000000000000000000000000000
? ellztopoint(E, z) - P
%4 = [6.372367644529809109 E-58, 7.646841173435770930 E-57]
? ellpointtoz(E, [0]) \\ the point at infinity
%5 = 0

If E/\mathbb{Q}_p has multiplicative reduction, then E/\\bar{\mathbb{Q}_p} is analytically isomorphic to \\bar{\mathbb{Q}}_p^*/q^\mathbb{Z} (Tate curve) for some p-adic integer q. The behaviour is then as follows:

  • If the reduction is split (E.tate[2] is a t_PADIC), we have an isomorphism \phi: E(\mathbb{Q}_p) ~ \mathbb{Q}_p^*/q^\mathbb{Z} and the function returns \phi(P) belongs to \mathbb{Q}_p.
  • If the reduction is not split (E.tate[2] is a t_POLMOD), we only have an isomorphism \phi: E(K) ~ K^*/q^\mathbb{Z} over the unramified quadratic extension K/\mathbb{Q}_p. In this case, the output \phi(P) belongs to K is a t_POLMOD.
? E = ellinit([0,-1,1,0,0], O(11^5)); P = [0,0];
? [u2,u,q] = E.tate; type(u) \\ split multiplicative reduction
%2 = "t_PADIC"
? ellmul(E, P, 5) \\ P has order 5
%3 = [0]
? z = ellpointtoz(E, [0,0])
%4 = 3 + 11^2 + 2*11^3 + 3*11^4 + O(11^5)
? z^5
%5 = 1 + O(11^5)
? E = ellinit(ellfromj(1/4), O(2^6)); x=1/2; y=ellordinate(E,x)[1];
? z = ellpointtoz(E,[x,y]); \\ t_POLMOD of t_POL with t_PADIC coeffs
? liftint(z) \\ lift all p-adics
%8 = Mod(8*u + 7, u^2 + 437)
ellpow(E, z, n)

Deprecated alias for ellmul.

ellrootno(E, p=None)

E being an ell structure over \mathbb{Q} as output by ellinit, this function computes the local root number of its L-series at the place p (at the infinite place if p = 0). If p is omitted, return the global root number. Note that the global root number is the sign of the functional equation and conjecturally is the parity of the rank of the \idx{Mordell-Weil group}. The equation for E needs not be minimal at p, but if the model is already minimal the function will run faster.

ellsearch(N)

This function finds all curves in the elldata database satisfying the constraint defined by the argument N:

  • if N is a character string, it selects a given curve, e.g. "11a1", or curves in the given isogeny class, e.g. "11a", or curves with given conductor, e.g. "11";
  • if N is a vector of integers, it encodes the same constraints as the character string above, according to the ellconvertname correspondance, e.g. [11,0,1] for "11a1", [11,0] for "11a" and [11] for "11";
  • if N is an integer, curves with conductor N are selected.

If N is a full curve name, e.g. "11a1" or [11,0,1], the output format is [N, [a_1,a_2,a_3,a_4,a_6], G] where [a_1,a_2,a_3,a_4,a_6] are the coefficients of the Weierstrass equation of the curve and G is a \mathbb{Z}-basis of the free part of the \idx{Mordell-Weil group} associated to the curve.

? ellsearch("11a3")
%1 = ["11a3", [0, -1, 1, 0, 0], []]
? ellsearch([11,0,3])
%2 = ["11a3", [0, -1, 1, 0, 0], []]

If N is not a full curve name, then the output is a vector of all matching curves in the above format:

? ellsearch("11a")
%1 = [["11a1", [0, -1, 1, -10, -20], []],
 ["11a2", [0, -1, 1, -7820, -263580], []],
 ["11a3", [0, -1, 1, 0, 0], []]]
? ellsearch("11b")
%2 = []
ellsigma(L, z=None, flag=0, precision=0)

Computes the value at z of the Weierstrass \sigma function attached to the lattice L as given by ellperiods(,1): including quasi-periods is useful, otherwise there are recomputed from scratch for each new z.

\sigma(z, L) = z \prod_{\omega belongs to L^*} (1 -
(z)/(\omega))e^{(z)/(\omega) + (z^2)/(2\omega^2)}.

It is also possible to directly input L = [\omega_1,\omega_2], or an elliptic curve E as given by ellinit (L = E.omega).

? w = ellperiods([1,I], 1);
? ellsigma(w, 1/2)
%2 = 0.47494937998792065033250463632798296855
? E = ellinit([1,0]);
? ellsigma(E) \\ at 'x, implicitly at default seriesprecision
%4 = x + 1/60*x^5 - 1/10080*x^9 - 23/259459200*x^13 + O(x^17)

If flag = 1, computes an arbitrary determination of \log(\sigma(z)).

ellsub(E, z1, z2)

Difference of the points z1 and z2 on the elliptic curve corresponding to E.

elltaniyama(E, serprec=-1)

Computes the modular parametrization of the elliptic curve E/\mathbb{Q}, where E is an ell structure as output by ellinit. This returns a two-component vector [u,v] of power series, given to d significant terms (seriesprecision by default), characterized by the following two properties. First the point (u,v) satisfies the equation of the elliptic curve. Second, let N be the conductor of E and \Phi: X_0(N)\\to E be a modular parametrization; the pullback by \Phi of the Néron differential du/(2v+a_1u+a_3) is equal to 2i\Pi
f(z)dz, a holomorphic differential form. The variable used in the power series for u and v is x, which is implicitly understood to be equal to \exp(2i\Pi z).

The algorithm assumes that E is a strong Weil curve and that the Manin constant is equal to 1: in fact, f(x) = \sum_{n > 0}
ellan(E, n) x^n.

elltatepairing(E, P, Q, m)

Computes the Tate pairing of the two points P and Q on the elliptic curve E. The point P must be of m-torsion.

elltors(E)

If E is an elliptic curve defined over a number field or a finite field, outputs the torsion subgroup of E as a 3-component vector [t,v1,v2], where t is the order of the torsion group, v1 gives the structure of the torsion group as a product of cyclic groups (sorted by decreasing order), and v2 gives generators for these cyclic groups. E must be an ell structure as output by ellinit.

? E = ellinit([-1,0]);
? elltors(E)
%1 = [4, [2, 2], [[0, 0], [1, 0]]]

Here, the torsion subgroup is isomorphic to \mathbb{Z}/2\mathbb{Z} x \mathbb{Z}/2\mathbb{Z}, with generators [0,0] and [1,0].

ellweilpairing(E, P, Q, m)

Computes the Weil pairing of the two points of m-torsion P and Q on the elliptic curve E.

ellwp(w, z=None, flag=0, precision=0)

Computes the value at z of the Weierstrass \wp function attached to the lattice w as given by ellperiods. It is also possible to directly input w = [\omega_1,\omega_2], or an elliptic curve E as given by ellinit (w = E.omega).

? w = ellperiods([1,I]);
? ellwp(w, 1/2)
%2 = 6.8751858180203728274900957798105571978
? E = ellinit([1,1]);
? ellwp(E, 1/2)
%4 = 3.9413112427016474646048282462709151389

One can also compute the series expansion around z = 0:

? E = ellinit([1,0]);
? ellwp(E) \\ 'x implicitly at default seriesprecision
%5 = x^-2 - 1/5*x^2 + 1/75*x^6 - 2/4875*x^10 + O(x^14)
? ellwp(E, x + O(x^12)) \\ explicit precision
%6 = x^-2 - 1/5*x^2 + 1/75*x^6 + O(x^9)

Optional flag means 0 (default): compute only \wp(z), 1: compute [\wp(z),\wp'(z)].

ellxn(E, n, v=None)

In standard notation, for any affine point P = (v,w) on the curve E, we have

[n]P = (\phi_n(P)\psi_n(P) : \omega_n(P) : \psi_n(P)^3)

for some polynomials \phi_n,\omega_n,\psi_n in \mathbb{Z}[a_1,a_2,a_3,a_4,a_6][v,w]. This function returns [\phi_n(P),\psi_n(P)^2], which give the numerator and denominator of the abcissa of [n]P and depend only on v.

ellzeta(w, z=None, precision=0)

Computes the value at z of the Weierstrass \zeta function attached to the lattice w as given by ellperiods(,1): including quasi-periods is useful, otherwise there are recomputed from scratch for each new z.

\zeta(z, L) = (1)/(z) + z^2\sum_{\omega belongs to L^*}
(1)/(\omega^2(z-\omega)).

It is also possible to directly input w = [\omega_1,\omega_2], or an elliptic curve E as given by ellinit (w = E.omega). The quasi-periods of \zeta, such that

\zeta(z + a\omega_1 + b\omega_2) = \zeta(z) + a\eta_1 + b\eta_2

for integers a and b are obtained as \eta_i = 2\zeta(\omega_i/2). Or using directly elleta.

? w = ellperiods([1,I],1);
? ellzeta(w, 1/2)
%2 = 1.5707963267948966192313216916397514421
? E = ellinit([1,0]);
? ellzeta(E, E.omega[1]/2)
%4 = 0.84721308479397908660649912348219163647

One can also compute the series expansion around z = 0 (the quasi-periods are useless in this case):

? E = ellinit([0,1]);
? ellzeta(E) \\ at 'x, implicitly at default seriesprecision
%4 = x^-1 + 1/35*x^5 - 1/7007*x^11 + O(x^15)
? ellzeta(E, x + O(x^20)) \\ explicit precision
%5 = x^-1 + 1/35*x^5 - 1/7007*x^11 + 1/1440257*x^17 + O(x^18)
ellztopoint(E, z, precision=0)

E being an ell as output by ellinit, computes the coordinates [x,y] on the curve E corresponding to the complex number z. Hence this is the inverse function of ellpointtoz. In other words, if the curve is put in Weierstrass form y^2 = 4x^3 - g_2x - g_3, [x,y] represents the Weierstrass \wp-function and its derivative. More precisely, we have

x = \wp(z) - b_2/12, y = \wp'(z) - (a_1 x + a_3)/2.

If z is in the lattice defining E over \mathbb{C}, the result is the point at infinity [0].

erfc(x, precision=0)

Complementary error function, analytic continuation of (2/\sqrt\Pi)\int_x^ oo e^{-t^2}dt = incgam(1/2,x^2)/\sqrt\Pi, where the latter expression extends the function definition from real x to all complex x != 0.

errname(E)

Returns the type of the error message E as a string.

eta(z, flag=0, precision=0)

Variants of Dedekind’s \eta function. If flag = 0, return \prod_{n = 1}^ oo (1-q^n), where q depends on x in the following way:

  • q = e^{2i\Pi x} if x is a complex number (which must then have positive imaginary part); notice that the factor q^{1/24} is missing!
  • q = x if x is a t_PADIC, or can be converted to a power series (which must then have positive valuation).

If flag is non-zero, x is converted to a complex number and we return the true \eta function, q^{1/24}\prod_{n = 1}^ oo (1-q^n), where q = e^{2i\Pi x}.

eulerphi(x)

Euler’s \phi (totient) function of the integer \|x\|, in other words \|(\mathbb{Z}/x\mathbb{Z})^*\|.

? eulerphi(40)
%1 = 16

According to this definition we let \phi(0) := 2, since \mathbb{Z}^ *= {-1,1}; this is consistent with znstar(0): we have \kbd{znstar:math:(n).no = eulerphi(n)} for all n belongs to \mathbb{Z}.

exp(x, precision=0)

Exponential of x. p-adic arguments with positive valuation are accepted.

expm1(x, precision=0)

Return \exp(x)-1, computed in a way that is also accurate when the real part of x is near 0. A naive direct computation would suffer from catastrophic cancellation; PARI’s direct computation of \exp(x) alleviates this well known problem at the expense of computing \exp(x) to a higher accuracy when x is small. Using expm1 is recommended instead:

? default(realprecision, 10000); x = 1e-100;
? a = expm1(x);
time = 4 ms.
? b = exp(x)-1;
time = 28 ms.
? default(realprecision, 10040); x = 1e-100;
? c = expm1(x); \\ reference point
? abs(a-c)/c \\ relative error in expm1(x)
%7 = 0.E-10017
? abs(b-c)/c \\ relative error in exp(x)-1
%8 = 1.7907031188259675794 E-9919

As the example above shows, when x is near 0, expm1 is both faster and more accurate than exp(x)-1.

factor(x, lim=None)

General factorization function, where x is a rational (including integers), a complex number with rational real and imaginary parts, or a rational function (including polynomials). The result is a two-column matrix: the first contains the irreducibles dividing x (rational or Gaussian primes, irreducible polynomials), and the second the exponents. By convention, 0 is factored as 0^1.

:math:mathbb{Q}` and \mathbb{Q}(i).` See factorint for more information about the algorithms used. The rational or Gaussian primes are in fact pseudoprimes (see ispseudoprime), a priori not rigorously proven primes. In fact, any factor which is <= 2^{64} (whose norm is <= 2^{64} for an irrational Gaussian prime) is a genuine prime. Use isprime to prove primality of other factors, as in

? fa = factor(2^2^7 + 1)
%1 =
[59649589127497217 1]

[5704689200685129054721 1]

? isprime( fa[,1] )
%2 = [1, 1]~ \\ both entries are proven primes

Another possibility is to set the global default factor_proven, which will perform a rigorous primality proof for each pseudoprime factor.

A t_INT argument lim can be added, meaning that we look only for prime factors p < lim. The limit lim must be non-negative. In this case, all but the last factor are proven primes, but the remaining factor may actually be a proven composite! If the remaining factor is less than lim^2, then it is prime.

? factor(2^2^7 +1, 10^5)
%3 =
[340282366920938463463374607431768211457 1]

Deprecated feature. Setting lim = 0 is the same as setting it to primelimit + 1. Don’t use this: it is unwise to rely on global variables when you can specify an explicit argument.

This routine uses trial division and perfect power tests, and should not be used for huge values of lim (at most 10^9, say): factorint(, 1 + 8) will in general be faster. The latter does not guarantee that all small prime factors are found, but it also finds larger factors, and in a much more efficient way.

? F = (2^2^7 + 1) * 1009 * 100003; factor(F, 10^5) \\ fast, incomplete
time = 0 ms.
%4 =
[1009 1]

[34029257539194609161727850866999116450334371 1]

? factor(F, 10^9) \\ very slow
time = 6,892 ms.
%6 =
[1009 1]

[100003 1]

[340282366920938463463374607431768211457 1]

? factorint(F, 1+8) \\ much faster, all small primes were found
time = 12 ms.
%7 =
[1009 1]

[100003 1]

[340282366920938463463374607431768211457 1]

? factor(F) \\ complete factorisation
time = 112 ms.
%8 =
[1009 1]

[100003 1]

[59649589127497217 1]

[5704689200685129054721 1]

Over \mathbb{Q}, the prime factors are sorted in increasing order.

Rational functions. The polynomials or rational functions to be factored must have scalar coefficients. In particular PARI does not know how to factor multivariate polynomials. The following domains are currently supported: \mathbb{Q}, \mathbb{R}, \mathbb{C}, \mathbb{Q}_p, finite fields and number fields. See factormod and factorff for the algorithms used over finite fields, factornf for the algorithms over number fields. Over \mathbb{Q}, van Hoeij’s method is used, which is able to cope with hundreds of modular factors.

The routine guesses a sensible ring over which to factor: the smallest ring containing all coefficients, taking into account quotient structures induced by t_INTMOD s and t_POLMOD s (e.g. if a coefficient in \mathbb{Z}/n\mathbb{Z} is known, all rational numbers encountered are first mapped to \mathbb{Z}/n\mathbb{Z}; different moduli will produce an error). Factoring modulo a non-prime number is not supported; to factor in \mathbb{Q}_p, use t_PADIC coefficients not t_INTMOD modulo p^n.

? T = x^2+1;
? factor(T); \\ over Q
? factor(T*Mod(1,3)) \\ over F_3
? factor(T*ffgen(ffinit(3,2,'t))^0) \\ over F_{3^2}
? factor(T*Mod(Mod(1,3), t^2+t+2)) \\ over F_{3^2}, again
? factor(T*(1 + O(3^6)) \\ over Q_3, precision 6
? factor(T*1.) \\ over R, current precision
? factor(T*(1.+0.*I)) \\ over C
? factor(T*Mod(1, y^3-2)) \\ over Q(2^{1/3})

In most cases, it is clearer and simpler to call an explicit variant than to rely on the generic factor function and the above detection mechanism:

? factormod(T, 3) \\ over F_3
? factorff(T, 3, t^2+t+2)) \\ over F_{3^2}
? factorpadic(T, 3,6) \\ over Q_3, precision 6
? nffactor(y^3-2, T) \\ over Q(2^{1/3})
? polroots(T) \\ over C

Note that factorization of polynomials is done up to multiplication by a constant. In particular, the factors of rational polynomials will have integer coefficients, and the content of a polynomial or rational function is discarded and not included in the factorization. If needed, you can always ask for the content explicitly:

? factor(t^2 + 5/2*t + 1)
%1 =
[2*t + 1 1]

[t + 2 1]

? content(t^2 + 5/2*t + 1)
%2 = 1/2

The irreducible factors are sorted by increasing degree. See also nffactor.

factorback(f, e=None)

Gives back the factored object corresponding to a factorization. The integer 1 corresponds to the empty factorization.

If e is present, e and f must be vectors of the same length (e being integral), and the corresponding factorization is the product of the f[i]^{e[i]}.

If not, and f is vector, it is understood as in the preceding case with e a vector of 1s: we return the product of the f[i]. Finally, f can be a regular factorization, as produced with any factor command. A few examples:

? factor(12)
%1 =
[2 2]

[3 1]

? factorback(%)
%2 = 12
? factorback([2,3], [2,1]) \\ 2^3 * 3^1
%3 = 12
? factorback([5,2,3])
%4 = 30
factorcantor(x, p)

Factors the polynomial x modulo the prime p, using distinct degree plus Cantor-Zassenhaus. The coefficients of x must be operation-compatible with \mathbb{Z}/p\mathbb{Z}. The result is a two-column matrix, the first column being the irreducible polynomials dividing x, and the second the exponents. If you want only the degrees of the irreducible polynomials (for example for computing an L-function), use factormod(x,p,1). Note that the factormod algorithm is usually faster than factorcantor.

factorff(x, p=None, a=None)

Factors the polynomial x in the field \mathbb{F}_q defined by the irreducible polynomial a over \mathbb{F}_p. The coefficients of x must be operation-compatible with \mathbb{Z}/p\mathbb{Z}. The result is a two-column matrix: the first column contains the irreducible factors of x, and the second their exponents. If all the coefficients of x are in \mathbb{F}_p, a much faster algorithm is applied, using the computation of isomorphisms between finite fields.

Either a or p can omitted (in which case both are ignored) if x has t_FFELT coefficients; the function then becomes identical to factor:

? factorff(x^2 + 1, 5, y^2+3) \\ over F_5[y]/(y^2+3) ~ F_25
%1 =
[Mod(Mod(1, 5), Mod(1, 5)*y^2 + Mod(3, 5))*x
 + Mod(Mod(2, 5), Mod(1, 5)*y^2 + Mod(3, 5)) 1]

[Mod(Mod(1, 5), Mod(1, 5)*y^2 + Mod(3, 5))*x
 + Mod(Mod(3, 5), Mod(1, 5)*y^2 + Mod(3, 5)) 1]
? t = ffgen(y^2 + Mod(3,5), 't); \\ a generator for F_25 as a t_FFELT
? factorff(x^2 + 1) \\ not enough information to determine the base field
 *** at top-level: factorff(x^2+1)
 *** ^---------------
 *** factorff: incorrect type in factorff.
? factorff(x^2 + t^0) \\ make sure a coeff. is a t_FFELT
%3 =
[x + 2 1]

[x + 3 1]
? factorff(x^2 + t + 1)
%11 =
[x + (2*t + 1) 1]

[x + (3*t + 4) 1]

Notice that the second syntax is easier to use and much more readable.

factorint(x, flag=0)

Factors the integer n into a product of pseudoprimes (see ispseudoprime), using a combination of the Shanks SQUFOF and Pollard Rho method (with modifications due to Brent), Lenstra’s ECM (with modifications by Montgomery), and MPQS (the latter adapted from the LiDIA code with the kind permission of the LiDIA maintainers), as well as a search for pure powers. The output is a two-column matrix as for factor: the first column contains the “prime” divisors of n, the second one contains the (positive) exponents.

By convention 0 is factored as 0^1, and 1 as the empty factorization; also the divisors are by default not proven primes is they are larger than 2^{64}, they only failed the BPSW compositeness test (see ispseudoprime). Use isprime on the result if you want to guarantee primality or set the factor_proven default to 1. Entries of the private prime tables (see addprimes) are also included as is.

This gives direct access to the integer factoring engine called by most arithmetical functions. flag is optional; its binary digits mean 1: avoid MPQS, 2: skip first stage ECM (we may still fall back to it later), 4: avoid Rho and SQUFOF, 8: don’t run final ECM (as a result, a huge composite may be declared to be prime). Note that a (strong) probabilistic primality test is used; thus composites might not be detected, although no example is known.

You are invited to play with the flag settings and watch the internals at work by using gp‘s debug default parameter (level 3 shows just the outline, 4 turns on time keeping, 5 and above show an increasing amount of internal details).

factormod(x, p, flag=0)

Factors the polynomial x modulo the prime integer p, using Berlekamp. The coefficients of x must be operation-compatible with \mathbb{Z}/p\mathbb{Z}. The result is a two-column matrix, the first column being the irreducible polynomials dividing x, and the second the exponents. If flag is non-zero, outputs only the degrees of the irreducible polynomials (for example, for computing an L-function). A different algorithm for computing the mod p factorization is factorcantor which is sometimes faster.

factornf(x, t)

Factorization of the univariate polynomial x over the number field defined by the (univariate) polynomial t. x may have coefficients in \mathbb{Q} or in the number field. The algorithm reduces to factorization over \mathbb{Q} (Trager’s trick). The direct approach of nffactor, which uses van Hoeij’s method in a relative setting, is in general faster.

The main variable of t must be of lower priority than that of x (see priority (in the PARI manual)). However if non-rational number field elements occur (as polmods or polynomials) as coefficients of x, the variable of these polmods must be the same as the main variable of t. For example

? factornf(x^2 + Mod(y, y^2+1), y^2+1);
? factornf(x^2 + y, y^2+1); \\ these two are OK
? factornf(x^2 + Mod(z,z^2+1), y^2+1)
 *** at top-level: factornf(x^2+Mod(z,z
 *** ^--------------------
 *** factornf: inconsistent data in rnf function.
? factornf(x^2 + z, y^2+1)
 *** at top-level: factornf(x^2+z,y^2+1
 *** ^--------------------
 *** factornf: incorrect variable in rnf function.
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 \mathbb{Z}/p^r\mathbb{Z} (polynomials over that ring do not form a unique factorization domain, anyway), but approximations in \mathbb{Q}/p^r\mathbb{Z} of the true factorization in \mathbb{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 \mathbb{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.

ffgen(q, v=None)

Return a t_FFELT generator for the finite field with q elements; q = p^f must be a prime power. This functions computes an irreducible monic polynomial P belongs to \mathbb{F}_p[X] of degree f (via ffinit) and returns g = X (mod P(X)). If v is given, the variable name is used to display g, else the variable x is used.

? g = ffgen(8, 't);
? g.mod
%2 = t^3 + t^2 + 1
? g.p
%3 = 2
? g.f
%4 = 3
? ffgen(6)
 *** at top-level: ffgen(6)
 *** ^--------
 *** ffgen: not a prime number in ffgen: 6.

Alternative syntax: instead of a prime power q = p^f, one may input the pair [p,f]:

? g = ffgen([2,4], 't);
? g.p
%2 = 2
? g.mod
%3 = t^4 + t^3 + t^2 + t + 1

Finally, one may input directly the polynomial P (monic, irreducible, with t_INTMOD coefficients), and the function returns the generator g = X (mod P(X)), inferring p from the coefficients of P. If v is given, the variable name is used to display g, else the variable of the polynomial P is used. If P is not irreducible, we create an invalid object and behaviour of functions dealing with the resulting t_FFELT is undefined; in fact, it is much more costly to test P for irreducibility than it would be to produce it via ffinit.

ffinit(p, n, v=None)

Computes a monic polynomial of degree n which is irreducible over \mathbb{F}_p, where p is assumed to be prime. This function uses a fast variant of Adleman and Lenstra’s algorithm.

It is useful in conjunction with ffgen; for instance if P = ffinit(3,2), you can represent elements in \mathbb{F}_{3^2} in term of g = ffgen(P,'t). This can be abbreviated as g = ffgen(3^2, 't), where the defining polynomial P can be later recovered as g.mod.

fflog(x, g, o=None)

Discrete logarithm of the finite field element x in base g, i.e.  an e in \mathbb{Z} such that g^e = o. If present, o represents the multiplicative order of g, see DLfun (in the PARI manual); the preferred format for this parameter is [ord, factor(ord)], where ord is the order of g. It may be set as a side effect of calling ffprimroot.

If no o is given, assume that g is a primitive root. The result is undefined if e does not exist. This function uses

  • a combination of generic discrete log algorithms (see znlog)
  • a cubic sieve index calculus algorithm for large fields of degree at least 5.
  • Coppersmith’s algorithm for fields of characteristic at most 5.
? t = ffgen(ffinit(7,5));
? o = fforder(t)
%2 = 5602 \\ not a primitive root.
? fflog(t^10,t)
%3 = 10
? fflog(t^10,t, o)
%4 = 10
? g = ffprimroot(t, &o);
? o \\ order is 16806, bundled with its factorization matrix
%6 = [16806, [2, 1; 3, 1; 2801, 1]]
? fforder(g, o)
%7 = 16806
? fflog(g^10000, g, o)
%8 = 10000
ffnbirred(q, n, fl=0)

Computes the number of monic irreducible polynomials over \mathbb{F}_q of degree exactly n, (flag = 0 or omitted) or at most n (flag = 1).

fforder(x, o=None)

Multiplicative order of the finite field element x. If o is present, it represents a multiple of the order of the element, see DLfun (in the PARI manual); the preferred format for this parameter is [N, factor(N)], where N is the cardinality of the multiplicative group of the underlying finite field.

? t = ffgen(ffinit(nextprime(10^8), 5));
? g = ffprimroot(t, &o); \\ o will be useful!
? fforder(g^1000000, o)
time = 0 ms.
%5 = 5000001750000245000017150000600250008403
? fforder(g^1000000)
time = 16 ms. \\ noticeably slower, same result of course
%6 = 5000001750000245000017150000600250008403
floor(x)

Floor of x. When x is in \mathbb{R}, the result is the largest integer smaller than or equal to x. Applied to a rational function, floor(x) returns the Euclidean quotient of the numerator by the denominator.

fold(f, A)

Apply the t_CLOSURE f of arity 2 to the entries of A to return f(...f(f(A[1],A[2]),A[3])...,A[#A]).

? fold((x,y)->x*y, [1,2,3,4])
%1 = 24
? fold((x,y)->[x,y], [1,2,3,4])
%2 = [[[1, 2], 3], 4]
? fold((x,f)->f(x), [2,sqr,sqr,sqr])
%3 = 256
? fold((x,y)->(x+y)/(1-x*y),[1..5])
%4 = -9/19
? bestappr(tan(sum(i=1,5,atan(i))))
%5 = -9/19
frac(x)

Fractional part of x. Identical to x-{floor}(x). If x is real, the result is in [0,1[.

fromdigits(x, b=None)

Gives the integer formed by the elements of x seen as the digits of a number in base b. This is the reverse of digits:

? digits(1234,5)
%1 = [1,4,4,1,4]
? fromdigits([1,4,4,1,4],5)
%2 = 1234
galoisexport(gal, flag=0)

gal being be a Galois group as output by galoisinit, export the underlying permutation group as a string suitable for (no flags or flag = 0) GAP or (flag = 1) Magma. The following example compute the index of the underlying abstract group in the GAP library:

? G = galoisinit(x^6+108);
? s = galoisexport(G)
%2 = "Group((1, 2, 3)(4, 5, 6), (1, 4)(2, 6)(3, 5))"
? extern("echo \"IdGroup("s");\" | gap -q")
%3 = [6, 1]
? galoisidentify(G)
%4 = [6, 1]

This command also accepts subgroups returned by galoissubgroups.

To import a GAP permutation into gp (for galoissubfields for instance), the following GAP function may be useful:

PermToGP := function(p, n)
 return Permuted([1..n],p);
end;

gap> p:= (1,26)(2,5)(3,17)(4,32)(6,9)(7,11)(8,24)(10,13)(12,15)(14,27)
 (16,22)(18,28)(19,20)(21,29)(23,31)(25,30)
gap> PermToGP(p,32);
[ 26, 5, 17, 32, 2, 9, 11, 24, 6, 13, 7, 15, 10, 27, 12, 22, 3, 28, 20, 19,
 29, 16, 31, 8, 30, 1, 14, 18, 21, 25, 23, 4 ]
galoisfixedfield(gal, perm, flag=0, v=None)

gal being be a Galois group as output by galoisinit and perm an element of gal.group, a vector of such elements or a subgroup of gal as returned by galoissubgroups, computes the fixed field of gal by the automorphism defined by the permutations perm of the roots gal.roots. P is guaranteed to be squarefree modulo gal.p.

If no flags or flag = 0, output format is the same as for nfsubfield, returning [P,x] such that P is a polynomial defining the fixed field, and x is a root of P expressed as a polmod in gal.pol.

If flag = 1 return only the polynomial P.

If flag = 2 return [P,x,F] where P and x are as above and F is the factorization of gal.pol over the field defined by P, where variable v (y by default) stands for a root of P. The priority of v must be less than the priority of the variable of gal.pol (see priority (in the PARI manual)). Example:

? G = galoisinit(x^4+1);
? galoisfixedfield(G,G.group[2],2)
%2 = [x^2 + 2, Mod(x^3 + x, x^4 + 1), [x^2 - y*x - 1, x^2 + y*x - 1]]

computes the factorization x^4+1 = (x^2-\sqrt{-2}x-1)(x^2+\sqrt{-2}x-1)

galoisidentify(gal)

gal being be a Galois group as output by galoisinit, output the isomorphism class of the underlying abstract group as a two-components vector [o,i], where o is the group order, and i is the group index in the GAP4 Small Group library, by Hans Ulrich Besche, Bettina Eick and Eamonn O’Brien.

This command also accepts subgroups returned by galoissubgroups.

The current implementation is limited to degree less or equal to 127. Some larger “easy” orders are also supported.

The output is similar to the output of the function IdGroup in GAP4. Note that GAP4 IdGroup handles all groups of order less than 2000 except 1024, so you can use galoisexport and GAP4 to identify large Galois groups.

galoisinit(pol, den=None)

Computes the Galois group and all necessary information for computing the fixed fields of the Galois extension K/\mathbb{Q} where K is the number field defined by pol (monic irreducible polynomial in \mathbb{Z}[X] or a number field as output by nfinit). The extension K/\mathbb{Q} must be Galois with Galois group “weakly” super-solvable, see below; returns 0 otherwise. Hence this permits to quickly check whether a polynomial of order strictly less than 36 is Galois or not.

The algorithm used is an improved version of the paper “An efficient algorithm for the computation of Galois automorphisms”, Bill Allombert, Math. Comp, vol. 73, 245, 2001, pp. 359–375.

A group G is said to be “weakly” super-solvable if there exists a normal series

{1} = H_0 \\triangleleft H_1 \\triangleleft...\\triangleleft H_{n-1}
\triangleleft H_n

such that each H_i is normal in G and for i < n, each quotient group H_{i+1}/H_i is cyclic, and either H_n = G (then G is super-solvable) or G/H_n is isomorphic to either A_4 or S_4.

In practice, almost all small groups are WKSS, the exceptions having order 36(1 exception), 48(2), 56(1), 60(1), 72(5), 75(1), 80(1), 96(10) and \\geq
108.

This function is a prerequisite for most of the galoisxxx routines. For instance:

P = x^6 + 108;
G = galoisinit(P);
L = galoissubgroups(G);
vector(#L, i, galoisisabelian(L[i],1))
vector(#L, i, galoisidentify(L[i]))

The output is an 8-component vector gal.

gal[1] contains the polynomial pol (:emphasis:`gal.pol`).

gal[2] is a three-components vector [p,e,q] where p is a prime number (:emphasis:`gal.p`) such that pol totally split modulo p , e is an integer and q = p^e (:emphasis:`gal.mod`) is the modulus of the roots in :emphasis:`gal.roots`.

gal[3] is a vector L containing the p-adic roots of pol as integers implicitly modulo :emphasis:`gal.mod`. (:emphasis:`gal.roots`).

gal[4] is the inverse of the Vandermonde matrix of the p-adic roots of pol, multiplied by gal[5].

gal[5] is a multiple of the least common denominator of the automorphisms expressed as polynomial in a root of pol.

gal[6] is the Galois group G expressed as a vector of permutations of L (:emphasis:`gal.group`).

gal[7] is a generating subset S = [s_1,...,s_g] of G expressed as a vector of permutations of L (:emphasis:`gal.gen`).

gal[8] contains the relative orders [o_1,...,o_g] of the generators of S (:emphasis:`gal.orders`).

Let H_n be as above, we have the following properties:

  * if G/H_n ~ A_4 then [o_1,...,o_g] ends by [2,2,3].

  * if G/H_n ~ S_4 then [o_1,...,o_g] ends by [2,2,3,2].

  * for 1 <= i <= g the subgroup of G generated by [s_1,...,s_g] is normal, with the exception of i = g-2 in the A_4 case and of i = g-3 in the S_A case.

  * the relative order o_i of s_i is its order in the quotient group G/< s_1,...,s_{i-1}>, with the same exceptions.

  * for any x belongs to G there exists a unique family [e_1,...,e_g] such that (no exceptions):

– for 1 <= i <= g we have 0 <= e_i < o_i

x = g_1^{e_1}g_2^{e_2}...g_n^{e_n}

If present den must be a suitable value for gal[5].

galoisisabelian(gal, flag=0)

gal being as output by galoisinit, return 0 if gal is not an abelian group, and the HNF matrix of gal over gal.gen if fl = 0, 1 if fl = 1.

This command also accepts subgroups returned by galoissubgroups.

galoisisnormal(gal, subgrp)

gal being as output by galoisinit, and subgrp a subgroup of gal as output by galoissubgroups,return 1 if subgrp is a normal subgroup of gal, else return 0.

This command also accepts subgroups returned by galoissubgroups.

galoispermtopol(gal, perm)

gal being a Galois group as output by galoisinit and perm a element of gal.group, return the polynomial defining the Galois automorphism, as output by nfgaloisconj, associated with the permutation perm of the roots gal.roots. perm can also be a vector or matrix, in this case, galoispermtopol is applied to all components recursively.

Note that

G = galoisinit(pol);
galoispermtopol(G, G[6])~

is equivalent to nfgaloisconj(pol), if degree of pol is greater or equal to 2.

galoissubcyclo(N, H=None, fl=0, v=None)

Computes the subextension of \mathbb{Q}(\zeta_n) fixed by the subgroup H \\subset (\mathbb{Z}/n\mathbb{Z})^*. By the Kronecker-Weber theorem, all abelian number fields can be generated in this way (uniquely if n is taken to be minimal).

The pair (n, H) is deduced from the parameters (N, H) as follows

  • N an integer: then n = N; H is a generator, i.e. an integer or an integer modulo n; or a vector of generators.
  • N the output of znstar(:math:`n)`. H as in the first case above, or a matrix, taken to be a HNF left divisor of the SNF for (\mathbb{Z}/n\mathbb{Z})^* (of type :math:`N.cyc`), giving the generators of H in terms of :math:`N.gen`.
  • N the output of bnrinit(bnfinit(y), :math:`m, 1)` where m is a module. H as in the first case, or a matrix taken to be a HNF left divisor of the SNF for the ray class group modulo m (of type :math:`N.cyc`), giving the generators of H in terms of :math:`N.gen`.

In this last case, beware that H is understood relatively to N; in particular, if the infinite place does not divide the module, e.g if m is an integer, then it is not a subgroup of (\mathbb{Z}/n\mathbb{Z})^*, but of its quotient by {± 1}.

If fl = 0, compute a polynomial (in the variable v) defining the the subfield of \mathbb{Q}(\zeta_n) fixed by the subgroup H of (\mathbb{Z}/n\mathbb{Z})^*.

If fl = 1, compute only the conductor of the abelian extension, as a module.

If fl = 2, output [pol, N], where pol is the polynomial as output when fl = 0 and N the conductor as output when fl = 1.

The following function can be used to compute all subfields of \mathbb{Q}(\zeta_n) (of exact degree d, if d is set):

polsubcyclo(n, d = -1)=
{ my(bnr,L,IndexBound);
 IndexBound = if (d < 0, n, [d]);
 bnr = bnrinit(bnfinit(y), [n,[1]], 1);
 L = subgrouplist(bnr, IndexBound, 1);
 vector(#L,i, galoissubcyclo(bnr,L[i]));
}

Setting L = subgrouplist(bnr, IndexBound) would produce subfields of exact conductor n oo.

galoissubfields(G, flags=0, v=None)

Outputs all the subfields of the Galois group G, as a vector. This works by applying galoisfixedfield to all subgroups. The meaning of the flag fl is the same as for galoisfixedfield.

galoissubgroups(G)

Outputs all the subgroups of the Galois group gal. A subgroup is a vector [gen, orders], with the same meaning as for gal.gen and gal.orders. Hence gen is a vector of permutations generating the subgroup, and orders is the relatives orders of the generators. The cardinality of a subgroup is the product of the relative orders. Such subgroup can be used instead of a Galois group in the following command: galoisisabelian, galoissubgroups, galoisexport and galoisidentify.

To get the subfield fixed by a subgroup sub of gal, use

galoisfixedfield(gal,sub[1])
gamma(s, precision=0)

For s a complex number, evaluates Euler’s gamma function

\Gamma(s) = \int_0^ oo t^{s-1}\exp(-t)dt.

Error if s is a non-positive integer, where \Gamma has a pole.

For s a t_PADIC, evaluates the Morita gamma function at s, that is the unique continuous p-adic function on the p-adic integers extending \Gamma_p(k) = (-1)^k \prod_{j < k}'j, where the prime means that p does not divide j.

? gamma(1/4 + O(5^10))
%1= 1 + 4*5 + 3*5^4 + 5^6 + 5^7 + 4*5^9 + O(5^10)
? algdep(%,4)
%2 = x^4 + 4*x^2 + 5
gammah(x, precision=0)

Gamma function evaluated at the argument x+1/2.

gammamellininv(G, t, m=0, precision=0)

Returns the value at t of the inverse Mellin transform G initialized by gammamellininvinit.

? G = gammamellininvinit([0]);
? gammamellininv(G, 2) - 2*exp(-Pi*2^2)
%2 = -4.484155085839414627 E-44

The alternative shortcut

gammamellininv(A,t,m)

for

gammamellininv(gammamellininvinit(A,m), t)

is available.

gammamellininvasymp(A, serprec=-1, n=0)

Return the first n terms of the asymptotic expansion at infinity of the m-th derivative K^{(m)}(t) of the inverse Mellin transform of the function

f(s) = \Gamma_\mathbb{R}(s+a_1)...\Gamma_\mathbb{R}(s+a_d) ,

where A is the vector [a_1,...,a_d] and \Gamma_\mathbb{R}(s) = \Pi^{-s/2} \Gamma(s/2). The result is a vector [M[1]...M[n]] with M[1] = 1, such that

K^{(m)}(t) = \sqrt(2^{d+1}/d)t^{1-d+a+m(2/d-1)}e^{-d\Pi t^{2/d}}
\sum_{n >= 0} M[n+1]t^{-2n/d}

with a = (1-d+\sum_{1 <= j <= d}a_j)/d.

gammamellininvinit(A, m=0, precision=0)

Initialize data for the computation by gammamellininv of the m-th derivative of the inverse Mellin transform of the function

f(s) = \Gamma_\mathbb{R}(s+a_1)...\Gamma_\mathbb{R}(s+a_d)

where A is the vector [a_1,...,a_d] and \Gamma_\mathbb{R}(s) = \Pi^{-s/2} \Gamma(s/2). This is the special case of Meijer’s G functions used to compute L-values via the approximate functional equation.

Caveat. Contrary to the PARI convention, this function guarantees an absolute (rather than relative) error bound.

For instance, the inverse Mellin transform of \Gamma_\mathbb{R}(s) is 2\exp(-\Pi z^2):

? G = gammamellininvinit([0]);
? gammamellininv(G, 2) - 2*exp(-Pi*2^2)
%2 = -4.484155085839414627 E-44

The inverse Mellin transform of \Gamma_\mathbb{R}(s+1) is 2 z\exp(-\Pi z^2), and its second derivative is 4\Pi z \exp(-\Pi z^2)(2\Pi z^2 - 3):

? G = gammamellininvinit([1], 2);
? a(z) = 4*Pi*z*exp(-Pi*z^2)*(2*Pi*z^2-3);
? b(z) = gammamellininv(G,z);
? t(z) = b(z) - a(z);
? t(3/2)
%3 = -1.4693679385278593850 E-39
gcd(x, y=None)

Creates the greatest common divisor of x and y. If you also need the u and v such that x*u + y*v = \mathrm{gcd}(x,y), use the bezout function. x and y can have rather quite general types, for instance both rational numbers. If y is omitted and x is a vector, returns the {gcd} of all components of x, i.e. this is equivalent to content(x).

When x and y are both given and one of them is a vector/matrix type, the GCD is again taken recursively on each component, but in a different way. If y is a vector, resp. matrix, then the result has the same type as y, and components equal to gcd(x, y[i]), resp. gcd(x, y[,i]). Else if x is a vector/matrix the result has the same type as x and an analogous definition. Note that for these types, gcd is not commutative.

The algorithm used is a naive Euclid except for the following inputs:

  • integers: use modified right-shift binary (“plus-minus” variant).
  • univariate polynomials with coefficients in the same number field (in particular rational): use modular gcd algorithm.
  • general polynomials: use the subresultant algorithm if coefficient explosion is likely (non modular coefficients).

If u and v are polynomials in the same variable with inexact coefficients, their gcd is defined to be scalar, so that

? a = x + 0.0; gcd(a,a)
%1 = 1
? b = y*x + O(y); gcd(b,b)
%2 = y
? c = 4*x + O(2^3); gcd(c,c)
%3 = 4

A good quantitative check to decide whether such a gcd “should be” non-trivial, is to use polresultant: a value close to 0 means that a small deformation of the inputs has non-trivial gcd. You may also use gcdext, which does try to compute an approximate gcd d and provides u, v to check whether u x + v y is close to d.

gcdext(x, y)

Returns [u,v,d] such that d is the gcd of x,y, x*u+y*v = \mathrm{gcd}(x,y), and u and v minimal in a natural sense. The arguments must be integers or polynomials.

? [u, v, d] = gcdext(32,102)
%1 = [16, -5, 2]
? d
%2 = 2
? gcdext(x^2-x, x^2+x-2)
%3 = [-1/2, 1/2, x - 1]

If x,y are polynomials in the same variable and inexact coefficients, then compute u,v,d such that x*u+y*v = d, where d approximately divides both and x and y; in particular, we do not obtain gcd(x,y) which is defined to be a scalar in this case:

? a = x + 0.0; gcd(a,a)
%1 = 1

? gcdext(a,a)
%2 = [0, 1, x + 0.E-28]

? gcdext(x-Pi, 6*x^2-zeta(2))
%3 = [-6*x - 18.8495559, 1, 57.5726923]

For inexact inputs, the output is thus not well defined mathematically, but you obtain explicit polynomials to check whether the approximation is close enough for your needs.

genus2red(P, p=None)

Let P be a polynomial with integer coefficients. Determines the reduction at p > 2 of the (proper, smooth) genus 2 curve C/\mathbb{Q}, defined by the hyperelliptic equation y^2 = P. (The special fiber X_p of the minimal regular model X of C over \mathbb{Z}.) The special syntax genus2red([P,Q]) is also allowed, where the polynomials P and Q have integer coefficients, to represent the model y^2 + Q(x)y = P(x).

If p is omitted, determines the reduction type for all (odd) prime divisors of the discriminant.

This function was rewritten from an implementation of Liu’s algorithm by Cohen and Liu (1994), genus2reduction-0.3, see http://www.math.u-bordeaux1.fr/~liu/G2R/.

CAVEAT. The function interface may change: for the time being, it returns [N,FaN, T, V] where N is either the local conductor at p or the global conductor, FaN is its factorization, y^2 = T defines a minimal model over \mathbb{Z}[1/2] and V describes the reduction type at the various considered p. Unfortunately, the program is not complete for p = 2, and we may return the odd part of the conductor only: this is the case if the factorization includes the (impossible) term 2^{-1}; if the factorization contains another power of 2, then this is the exact local conductor at 2 and N is the global conductor.

? default(debuglevel, 1);
? genus2red(x^6 + 3*x^3 + 63, 3)
(potential) stable reduction: [1, []]
reduction at p: [III{9}] page 184, [3, 3], f = 10
%1 = [59049, Mat([3, 10]), x^6 + 3*x^3 + 63, [3, [1, []],
 ["[III{9}] page 184", [3, 3]]]]
? [N, FaN, T, V] = genus2red(x^3-x^2-1, x^2-x); \\ X_1(13), global reduction
p = 13
(potential) stable reduction: [5, [Mod(0, 13), Mod(0, 13)]]
reduction at p: [I{0}-II-0] page 159, [], f = 2
? N
%3 = 169
? FaN
%4 = Mat([13, 2]) \\ in particular, good reduction at 2 !
? T
%5 = x^6 + 58*x^5 + 1401*x^4 + 18038*x^3 + 130546*x^2 + 503516*x + 808561
? V
%6 = [[13, [5, [Mod(0, 13), Mod(0, 13)]], ["[I{0}-II-0] page 159", []]]]

We now first describe the format of the vector V = V_p in the case where p was specified (local reduction at p): it is a triple [p, stable,
red]. The component stable = [type, vecj] contains information about the stable reduction after a field extension; depending on type s, the stable reduction is

  • 1: smooth (i.e. the curve has potentially good reduction). The Jacobian J(C) has potentially good reduction.
  • 2: an elliptic curve E with an ordinary double point; vecj contains j mod p, the modular invariant of E. The (potential) semi-abelian reduction of J(C) is the extension of an elliptic curve (with modular invariant j mod p) by a torus.
  • 3: a projective line with two ordinary double points. The Jacobian J(C) has potentially multiplicative reduction.
  • 4: the union of two projective lines crossing transversally at three points. The Jacobian J(C) has potentially multiplicative reduction.
  • 5: the union of two elliptic curves E_1 and E_2 intersecting transversally at one point; vecj contains their modular invariants j_1 and j_2, which may live in a quadratic extension of \mathbb{F}_p are need not be distinct. The Jacobian J(C) has potentially good reduction, isomorphic to the product of the reductions of E_1 and E_2.
  • 6: the union of an elliptic curve E and a projective line which has an ordinary double point, and these two components intersect transversally at one point; vecj contains j mod p, the modular invariant of E. The (potential) semi-abelian reduction of J(C) is the extension of an elliptic curve (with modular invariant j mod p) by a torus.
  • 7: as in type 6, but the two components are both singular. The Jacobian J(C) has potentially multiplicative reduction.

The component red = [NUtype, neron] contains two data concerning the reduction at p without any ramified field extension.

The NUtype is a t_STR describing the reduction at p of C, following Namikawa-Ueno, The complete classification of fibers in pencils of curves of genus two, Manuscripta Math., vol. 9, (1973), pages 143-186. The reduction symbol is followed by the corresponding page number in this article.

The second datum neron is the group of connected components (over an algebraic closure of \mathbb{F}_p) of the Néron model of J(C), given as a finite abelian group (vector of elementary divisors).

If p = 2, the red component may be omitted altogether (and replaced by [], in the case where the program could not compute it. When p was not specified, V is the vector of all V_p, for all considered p.

Notes about Namikawa-Ueno types.

  • A lower index is denoted between braces: for instance, \kbd{[I{ 2}-II-5]} means [I_2-II-5].
  • If K and K' are Kodaira symbols for singular fibers of elliptic curves, [:math:`K-K'-m]` and [:math:`K'-K-m]` are the same.
  • [:math:`K-K'--1]` is [:math:`K'-K-\alpha]` in the notation of Namikawa-Ueno.
  • The figure [2I_0-m] in Namikawa-Ueno, page 159, must be denoted by [2I_0-(m+1)].
hammingweight(x)

If x is a t_INT, return the binary Hamming weight of \|x\|. Otherwise x must be of type t_POL, t_VEC, t_COL, t_VECSMALL, or t_MAT and the function returns the number of non-zero coefficients of x.

? hammingweight(15)
%1 = 4
? hammingweight(x^100 + 2*x + 1)
%2 = 3
? hammingweight([Mod(1,2), 2, Mod(0,3)])
%3 = 2
? hammingweight(matid(100))
%4 = 100
hilbert(x, y, p=None)

Hilbert symbol of x and y modulo the prime p, p = 0 meaning the place at infinity (the result is undefined if p != 0 is not prime).

It is possible to omit p, in which case we take p = 0 if both x and y are rational, or one of them is a real number. And take p = q if one of x, y is a t_INTMOD modulo q or a q-adic. (Incompatible types will raise an error.)

hyperellcharpoly(X)

X being a non-singular hyperelliptic curve defined over a finite field, return the characteristic polynomial of the Frobenius automorphism. X can be given either by a squarefree polynomial P such that X: y^2 = P(x) or by a vector [P,Q] such that X: y^2 + Q(x) y = P(x) and Q^2+4 P is squarefree.

hyperellpadicfrobenius(Q, p, n)

Let X be the curve defined by y^2 = Q(x), where Q is a polynomial of degree d over \mathbb{Q} and p >= d a prime such that X has good reduction at p return the matrix of the Frobenius endomorphism \varphi on the crystalline module D_p(E) = \mathbb{Q}_p \\otimes H^1_{dR}(E/\mathbb{Q}) with respect to the basis of the given model (\omega, x \omega,...,x^{g-1} \omega), where \omega = dx/(2 y) is the invariant differential, where g is the genus of X (either d = 2 g+1 or d = 2 g+2). The characteristic polynomial of \varphi is the numerator of the zeta-function of the reduction of the curve X modlo p. The matrix is computed to absolute p-adic precision p^n.

hyperu(a, b, x, precision=0)

U-confluent hypergeometric function with parameters a and b. The parameters a and b can be complex but the present implementation requires x to be positive.

idealadd(nf, x, y)

Sum of the two ideals x and y in the number field nf. The result is given in HNF.

? K = nfinit(x^2 + 1);
? a = idealadd(K, 2, x + 1) \\ ideal generated by 2 and 1+I
%2 =
[2 1]

[0 1]
? pr = idealprimedec(K, 5)[1]; \\ a prime ideal above 5
? idealadd(K, a, pr) \\ coprime, as expected
%4 =
[1 0]

[0 1]

This function cannot be used to add arbitrary \mathbb{Z}-modules, since it assumes that its arguments are ideals:

? b = Mat([1,0]~);
? idealadd(K, b, b) \\ only square t_MATs represent ideals
*** idealadd: non-square t_MAT in idealtyp.
? c = [2, 0; 2, 0]; idealadd(K, c, c) \\ non-sense
%6 =
[2 0]

[0 2]
? d = [1, 0; 0, 2]; idealadd(K, d, d) \\ non-sense
%7 =
[1 0]

[0 1]

In the last two examples, we get wrong results since the matrices c and d do not correspond to an ideal: the \mathbb{Z}-span of their columns (as usual interpreted as coordinates with respect to the integer basis K.zk) is not an O_K-module. To add arbitrary \mathbb{Z}-modules generated by the columns of matrices A and B, use mathnf(concat(A,B)).

idealaddtoone(nf, x, y=None)

x and y being two co-prime integral ideals (given in any form), this gives a two-component row vector [a,b] such that a belongs to x, b belongs to y and a+b = 1.

The alternative syntax idealaddtoone(nf,v), is supported, where v is a k-component vector of ideals (given in any form) which sum to \mathbb{Z}_K. This outputs a k-component vector e such that e[i] belongs to x[i] for 1 <= i <= k and \sum_{1 <= i <= k}e[i] = 1.

idealappr(nf, x, flag=0)

If x is a fractional ideal (given in any form), gives an element \alpha in nf such that for all prime ideals p such that the valuation of x at p is non-zero, we have v_{p}(\alpha) = v_{p}(x), and v_{p}(\alpha) >= 0 for all other p.

If flag is non-zero, x must be given as a prime ideal factorization, as output by idealfactor, but possibly with zero or negative exponents. This yields an element \alpha such that for all prime ideals p occurring in x, v_{p}(\alpha) is equal to the exponent of p in x, and for all other prime ideals, v_{p}(\alpha) >= 0. This generalizes idealappr(nf,x,0) since zero exponents are allowed. Note that the algorithm used is slightly different, so that

idealappr(nf, idealfactor(nf,x))

may not be the same as idealappr(nf,x,1).

idealchinese(nf, x, y)

x being a prime ideal factorization (i.e. a 2 by 2 matrix whose first column contains prime ideals, and the second column integral exponents), y a vector of elements in nf indexed by the ideals in x, computes an element b such that

v_{p}(b - y_{p}) >= v_{p}(x) for all prime ideals in x and v_{p}(b) >= 0 for all other p.

idealcoprime(nf, x, y)

Given two integral ideals x and y in the number field nf, returns a \beta in the field, such that \beta.x is an integral ideal coprime to y.

idealdiv(nf, x, y, flag=0)

Quotient x.y^{-1} of the two ideals x and y in the number field nf. The result is given in HNF.

If flag is non-zero, the quotient x.y^{-1} is assumed to be an integral ideal. This can be much faster when the norm of the quotient is small even though the norms of x and y are large.

idealfactor(nf, x)

Factors into prime ideal powers the ideal x in the number field nf. The output format is similar to the factor function, and the prime ideals are represented in the form output by the idealprimedec function, i.e. as 5-element vectors.

idealfactorback(nf, f, e=None, flag=0)

Gives back the ideal corresponding to a factorization. The integer 1 corresponds to the empty factorization. If e is present, e and f must be vectors of the same length (e being integral), and the corresponding factorization is the product of the f[i]^{e[i]}.

If not, and f is vector, it is understood as in the preceding case with e a vector of 1s: we return the product of the f[i]. Finally, f can be a regular factorization, as produced by idealfactor.

? nf = nfinit(y^2+1); idealfactor(nf, 4 + 2*y)
%1 =
[[2, [1, 1]~, 2, 1, [1, 1]~] 2]

[[5, [2, 1]~, 1, 1, [-2, 1]~] 1]

? idealfactorback(nf, %)
%2 =
[10 4]

[0 2]

? f = %1[,1]; e = %1[,2]; idealfactorback(nf, f, e)
%3 =
[10 4]

[0 2]

? % == idealhnf(nf, 4 + 2*y)
%4 = 1

If flag is non-zero, perform ideal reductions (idealred) along the way. This is most useful if the ideals involved are all extended ideals (for instance with trivial principal part), so that the principal parts extracted by idealred are not lost. Here is an example:

? f = vector(#f, i, [f[i], [;]]); \\ transform to extended ideals
? idealfactorback(nf, f, e, 1)
%6 = [[1, 0; 0, 1], [2, 1; [2, 1]~, 1]]
? nffactorback(nf, %[2])
%7 = [4, 2]~

The extended ideal returned in %6 is the trivial ideal 1, extended with a principal generator given in factored form. We use nffactorback to recover it in standard form.

idealfrobenius(nf, gal, pr)

Let K be the number field defined by nf and assume K/\mathbb{Q} be a Galois extension with Galois group given gal = galoisinit(nf), and that pr is the prime ideal P in prid format, and that P is unramified. This function returns a permutation of gal.group which defines the automorphism \sigma = (P\\over K/\mathbb{Q} ), i.e the Frobenius element associated to P. If p is the unique prime number in P, then \sigma(x) = x^p mod \\P for all x belongs to \mathbb{Z}_K.

? nf = nfinit(polcyclo(31));
? gal = galoisinit(nf);
? pr = idealprimedec(nf,101)[1];
? g = idealfrobenius(nf,gal,pr);
? galoispermtopol(gal,g)
%5 = x^8

This is correct since 101 = 8 mod 31.

idealhnf(nf, u, v=None)

Gives the Hermite normal form of the ideal u\mathbb{Z}_K+v\mathbb{Z}_K, where u and v are elements of the number field K defined by nf.

? nf = nfinit(y^3 - 2);
? idealhnf(nf, 2, y+1)
%2 =
[1 0 0]

[0 1 0]

[0 0 1]
? idealhnf(nf, y/2, [0,0,1/3]~)
%3 =
[1/3 0 0]

[0 1/6 0]

[0 0 1/6]

If b is omitted, returns the HNF of the ideal defined by u: u may be an algebraic number (defining a principal ideal), a maximal ideal (as given by idealprimedec or idealfactor), or a matrix whose columns give generators for the ideal. This last format is a little complicated, but useful to reduce general modules to the canonical form once in a while:

  • if strictly less than N = [K:\mathbb{Q}] generators are given, u is the \mathbb{Z}_K-module they generate,
  • if N or more are given, it is assumed that they form a \mathbb{Z}-basis of the ideal, in particular that the matrix has maximal rank N. This acts as mathnf since the \mathbb{Z}_K-module structure is (taken for granted hence) not taken into account in this case.
? idealhnf(nf, idealprimedec(nf,2)[1])
%4 =
[2 0 0]

[0 1 0]

[0 0 1]
? idealhnf(nf, [1,2;2,3;3,4])
%5 =
[1 0 0]

[0 1 0]

[0 0 1]

Finally, when K is quadratic with discriminant D_K, we allow u = Qfb(a,b,c), provided b^2 - 4ac = D_K. As usual, this represents the ideal a \mathbb{Z} + (1/2)(-b + \sqrt{D_K}) \mathbb{Z}.

? K = nfinit(x^2 - 60); K.disc
%1 = 60
? idealhnf(K, qfbprimeform(60,2))
%2 =
[2 1]

[0 1]
? idealhnf(K, Qfb(1,2,3))
 *** at top-level: idealhnf(K,Qfb(1,2,3
 *** ^--------------------
 *** idealhnf: Qfb(1, 2, 3) has discriminant != 60 in idealhnf.
idealintersect(nf, A, B)

Intersection of the two ideals A and B in the number field nf. The result is given in HNF.

? nf = nfinit(x^2+1);
? idealintersect(nf, 2, x+1)
%2 =
[2 0]

[0 2]

This function does not apply to general \mathbb{Z}-modules, e.g. orders, since its arguments are replaced by the ideals they generate. The following script intersects \mathbb{Z}-modules A and B given by matrices of compatible dimensions with integer coefficients:

ZM_intersect(A,B) =
{ my(Ker = matkerint(concat(A,B)));
 mathnf( A * Ker[1..#A,] )
}
idealinv(nf, x)

Inverse of the ideal x in the number field nf, given in HNF. If x is an extended ideal, its principal part is suitably updated: i.e. inverting [I,t], yields [I^{-1}, 1/t].

ideallist(nf, bound, flag=4)

Computes the list of all ideals of norm less or equal to bound in the number field nf. The result is a row vector with exactly bound components. Each component is itself a row vector containing the information about ideals of a given norm, in no specific order, depending on the value of flag:

The possible values of flag are:

  0: give the bid associated to the ideals, without generators.

  1: as 0, but include the generators in the bid.

  2: in this case, nf must be a bnf with units. Each component is of the form [bid,U], where bid is as case 0 and U is a vector of discrete logarithms of the units. More precisely, it gives the ideallog s with respect to bid of bnf.tufu. This structure is technical, and only meant to be used in conjunction with bnrclassnolist or bnrdisclist.

  3: as 2, but include the generators in the bid.

  4: give only the HNF of the ideal.

? nf = nfinit(x^2+1);
? L = ideallist(nf, 100);
? L[1]
%3 = [[1, 0; 0, 1]] \\ A single ideal of norm 1
? #L[65]
%4 = 4 \\ There are 4 ideals of norm 4 in Z[i]

If one wants more information, one could do instead:

? nf = nfinit(x^2+1);
? L = ideallist(nf, 100, 0);
? l = L[25]; vector(#l, i, l[i].clgp)
%3 = [[20, [20]], [16, [4, 4]], [20, [20]]]
? l[1].mod
%4 = [[25, 18; 0, 1], []]
? l[2].mod
%5 = [[5, 0; 0, 5], []]
? l[3].mod
%6 = [[25, 7; 0, 1], []]

where we ask for the structures of the (\mathbb{Z}[i]/I)^* for all three ideals of norm 25. In fact, for all moduli with finite part of norm 25 and trivial Archimedean part, as the last 3 commands show. See ideallistarch to treat general moduli.

ideallistarch(nf, list, arch)

list is a vector of vectors of bid’s, as output by ideallist with flag 0 to 3. Return a vector of vectors with the same number of components as the original list. The leaves give information about moduli whose finite part is as in original list, in the same order, and Archimedean part is now arch (it was originally trivial). The information contained is of the same kind as was present in the input; see ideallist, in particular the meaning of flag.

? bnf = bnfinit(x^2-2);
? bnf.sign
%2 = [2, 0] \\ two places at infinity
? L = ideallist(bnf, 100, 0);
? l = L[98]; vector(#l, i, l[i].clgp)
%4 = [[42, [42]], [36, [6, 6]], [42, [42]]]
? La = ideallistarch(bnf, L, [1,1]); \\ add them to the modulus
? l = La[98]; vector(#l, i, l[i].clgp)
%6 = [[168, [42, 2, 2]], [144, [6, 6, 2, 2]], [168, [42, 2, 2]]]

Of course, the results above are obvious: adding t places at infinity will add t copies of \mathbb{Z}/2\mathbb{Z} to the ray class group. The following application is more typical:

? L = ideallist(bnf, 100, 2); \\ units are required now
? La = ideallistarch(bnf, L, [1,1]);
? H = bnrclassnolist(bnf, La);
? H[98];
%6 = [2, 12, 2]
ideallog(nf, x, bid)

nf is a number field, bid is as output by idealstar(nf, D,...) and x a non-necessarily integral element of nf which must have valuation equal to 0 at all prime ideals in the support of D. This function computes the discrete logarithm of x on the generators given in :emphasis:`bid.gen`. In other words, if g_i are these generators, of orders d_i respectively, the result is a column vector of integers (x_i) such that 0 <= x_i < d_i and

x = \prod_i g_i^{x_i} (mod ^*D) .

Note that when the support of D contains places at infinity, this congruence implies also sign conditions on the associated real embeddings. See znlog for the limitations of the underlying discrete log algorithms.

idealmin(nf, ix, vdir=None)

This function is useless and kept for backward compatibility only, use :literal:`idealred`. Computes a pseudo-minimum of the ideal x in the direction vdir in the number field nf.

idealmul(nf, x, y, flag=0)

Ideal multiplication of the ideals x and y in the number field nf; the result is the ideal product in HNF. If either x or y are extended ideals, their principal part is suitably updated: i.e. multiplying [I,t], [J,u] yields [IJ, tu]; multiplying I and [J, u] yields [IJ, u].

? nf = nfinit(x^2 + 1);
? idealmul(nf, 2, x+1)
%2 =
[4 2]

[0 2]
? idealmul(nf, [2, x], x+1) \\ extended ideal * ideal
%4 = [[4, 2; 0, 2], x]
? idealmul(nf, [2, x], [x+1, x]) \\ two extended ideals
%5 = [[4, 2; 0, 2], [-1, 0]~]

If flag is non-zero, reduce the result using idealred.

idealnorm(nf, x)

Computes the norm of the ideal x in the number field nf.

idealnumden(nf, x)

Returns [A,B], where A,B are coprime integer ideals such that x = A/B, in the number field nf.

? nf = nfinit(x^2+1);
? idealnumden(nf, (x+1)/2)
%2 = [[1, 0; 0, 1], [2, 1; 0, 1]]
idealpow(nf, x, k, flag=0)

Computes the k-th power of the ideal x in the number field nf; k belongs to \mathbb{Z}. If x is an extended ideal, its principal part is suitably updated: i.e. raising [I,t] to the k-th power, yields [I^k, t^k].

If flag is non-zero, reduce the result using idealred, throughout the (binary) powering process; in particular, this is not the same as as idealpow(nf,x,k) followed by reduction.

idealprimedec(nf, p, f=0)

Computes the prime ideal decomposition of the (positive) prime number p in the number field K represented by nf. If a non-prime p is given the result is undefined. If f is present and non-zero, restrict the result to primes of residue degree <= f.

The result is a vector of prid structures, each representing one of the prime ideals above p in the number field nf. The representation pr = [p,a,e,f,mb] of a prime ideal means the following: a and is an algebraic integer in the maximal order \mathbb{Z}_K and the prime ideal is equal to p = p\mathbb{Z}_K + a\mathbb{Z}_K; e is the ramification index; f is the residual index; finally, mb is the multiplication table associated to the algebraic integer b is such that p^{-1} = \mathbb{Z}_K+ b/ p\mathbb{Z}_K, which is used internally to compute valuations. In other words if p is inert, then mb is the integer 1, and otherwise it’s a square t_MAT whose j-th column is b.nf.zk[j].

The algebraic number a is guaranteed to have a valuation equal to 1 at the prime ideal (this is automatic if e > 1).

The components of pr should be accessed by member functions: pr.p, pr.e, pr.f, and pr.gen (returns the vector [p,a]):

? K = nfinit(x^3-2);
? P = idealprimedec(K, 5);
? #P \\ 2 primes above 5 in Q(2^(1/3))
%3 = 2
? [p1,p2] = P;
? [p1.e, p1.f] \\ the first is unramified of degree 1
%4 = [1, 1]
? [p2.e, p2.f] \\ the second is unramified of degree 2
%5 = [1, 2]
? p1.gen
%6 = [5, [2, 1, 0]~]
? nfbasistoalg(K, %[2]) \\ a uniformizer for p1
%7 = Mod(x + 2, x^3 - 2)
? #idealprimedec(K, 5, 1) \\ restrict to f = 1
%8 = 1 \\ now only p1
idealprincipalunits(nf, pr, k)

Given a prime ideal in idealprimedec format, returns the multiplicative group (1 + pr) / (1 + pr^k) as an abelian group. This function is much faster than idealstar when the norm of pr is large, since it avoids (useless) work in the multiplicative group of the residue field.

? K = nfinit(y^2+1);
? P = idealprimedec(K,2)[1];
? G = idealprincipalunits(K, P, 20);
? G.cyc
[512, 256, 4] \\ Z/512 x Z/256 x Z/4
? G.gen
%5 = [[-1, -2]~, 1021, [0, -1]~] \\ minimal generators of given order
idealramgroups(nf, gal, pr)

Let K be the number field defined by nf and assume that K/\mathbb{Q} is Galois with Galois group G given by gal = galoisinit(nf). Let pr be the prime ideal P in prid format. This function returns a vector g of subgroups of gal as follow:

  • g[1] is the decomposition group of P,
  • g[2] is G_0(P), the inertia group of P,

and for i >= 2,

  • g[i] is G_{i-2}(P), the i-2-th \idx{ramification group} of P.

The length of g is the number of non-trivial groups in the sequence, thus is 0 if e = 1 and f = 1, and 1 if f > 1 and e = 1. The following function computes the cardinality of a subgroup of G, as given by the components of g:

card(H) =my(o=H[2]); prod(i=1,#o,o[i]);
? nf=nfinit(x^6+3); gal=galoisinit(nf); pr=idealprimedec(nf,3)[1];
? g = idealramgroups(nf, gal, pr);
? apply(card,g)
%4 = [6, 6, 3, 3, 3] \\ cardinalities of the G_i
? nf=nfinit(x^6+108); gal=galoisinit(nf); pr=idealprimedec(nf,2)[1];
? iso=idealramgroups(nf,gal,pr)[2]
%4 = [[Vecsmall([2, 3, 1, 5, 6, 4])], Vecsmall([3])]
? nfdisc(galoisfixedfield(gal,iso,1))
%5 = -3

The field fixed by the inertia group of 2 is not ramified at 2.

idealred(nf, I, v=None)

LLL reduction of the ideal I in the number field nf, along the direction v. The v parameter is best left omitted, but if it is present, it must be an nf.r1 + nf.r2-component vector of non-negative integers. (What counts is the relative magnitude of the entries: if all entries are equal, the effect is the same as if the vector had been omitted.)

This function finds a “small” a in I (see the end for technical details). The result is the Hermite normal form of the “reduced” ideal J = r I/a, where r is the unique rational number such that J is integral and primitive. (This is usually not a reduced ideal in the sense of Buchmann.)

? K = nfinit(y^2+1);
? P = idealprimedec(K,5)[1];
? idealred(K, P)
%3 =
[1 0]

[0 1]

More often than not, a principal ideal yields the unit ideal as above. This is a quick and dirty way to check if ideals are principal, but it is not a necessary condition: a non-trivial result does not prove that the ideal is non-principal. For guaranteed results, see bnfisprincipal, which requires the computation of a full bnf structure.

If the input is an extended ideal [I,s], the output is [J,sa/r]; this way, one can keep track of the principal ideal part:

? idealred(K, [P, 1])
%5 = [[1, 0; 0, 1], [-2, 1]~]

meaning that P is generated by [-2, 1] . The number field element in the extended part is an algebraic number in any form or a factorization matrix (in terms of number field elements, not ideals!). In the latter case, elements stay in factored form, which is a convenient way to avoid coefficient explosion; see also idealpow.

Technical note. The routine computes an LLL-reduced basis for the lattice I equipped with the quadratic form

\|\| x \|\|_v^2 = \sum_{i = 1}^{r_1+r_2} 2^{v_i}\varepsilon_i\|\sigma_i(x)\|^2,

where as usual the \sigma_i are the (real and) complex embeddings and \varepsilon_i = 1, resp. 2, for a real, resp. complex place. The element a is simply the first vector in the LLL basis. The only reason you may want to try to change some directions and set some v_i != 0 is to randomize the elements found for a fixed ideal, which is heuristically useful in index calculus algorithms like bnfinit and bnfisprincipal.

Even more technical note. In fact, the above is a white lie. We do not use \|\|.\|\|_v exactly but a rescaled rounded variant which gets us faster and simpler LLLs. There’s no harm since we are not using any theoretical property of a after all, except that it belongs to I and is “expected to be small”.

idealstar(nf, I, flag=1)

Outputs a bid structure, necessary for computing in the finite abelian group G = (\mathbb{Z}_K/I)^*. Here, nf is a number field and I is a modulus: either an ideal in any form, or a row vector whose first component is an ideal and whose second component is a row vector of r_1 0 or 1. Ideals can also be given by a factorization into prime ideals, as produced by idealfactor.

This bid is used in ideallog to compute discrete logarithms. It also contains useful information which can be conveniently retrieved as :emphasis:`bid.mod` (the modulus), :emphasis:`bid.clgp` (G as a finite abelian group), :emphasis:`bid.no` (the cardinality of G), :emphasis:`bid.cyc` (elementary divisors) and :emphasis:`bid.gen` (generators).

If flag = 1 (default), the result is a bid structure without generators.

If flag = 2, as flag = 1, but including generators, which wastes some time.

If flag = 0, only outputs (\mathbb{Z}_K/I)^* as an abelian group, i.e as a 3-component vector [h,d,g]: h is the order, d is the vector of SNF cyclic components and g the corresponding generators.

idealtwoelt(nf, x, a=None)

Computes a two-element representation of the ideal x in the number field nf, combining a random search and an approximation theorem; x is an ideal in any form (possibly an extended ideal, whose principal part is ignored)

  • When called as idealtwoelt(nf,x), the result is a row vector [a,\alpha] with two components such that x = a\mathbb{Z}_K+\alpha\mathbb{Z}_K and a is chosen to be the positive generator of x\cap\mathbb{Z}, unless x was given as a principal ideal (in which case we may choose a = 0). The algorithm uses a fast lazy factorization of x\cap \mathbb{Z} and runs in randomized polynomial time.
  • When called as idealtwoelt(nf,x,a) with an explicit non-zero a supplied as third argument, the function assumes that a belongs to x and returns \alpha belongs to x such that x = a\mathbb{Z}_K + \alpha\mathbb{Z}_K. Note that we must factor a in this case, and the algorithm is generally much slower than the default variant.
idealval(nf, x, pr)

Gives the valuation of the ideal x at the prime ideal pr in the number field nf, where pr is in idealprimedec format. The valuation of the 0 ideal is +oo.

imag(x)

Imaginary part of x. When x is a quadratic number, this is the coefficient of \omega in the “canonical” integral basis (1,\omega).

incgam(s, x, g=None, precision=0)

Incomplete gamma function \int_x^ oo e^{-t}t^{s-1}dt, extended by analytic continuation to all complex x, s not both 0. The relative error is bounded in terms of the precision of s (the accuracy of x is ignored when determining the output precision). When g is given, assume that g = \Gamma(s). For small \|x\|, this will speed up the computation.

incgamc(s, x, precision=0)

Complementary incomplete gamma function. The arguments x and s are complex numbers such that s is not a pole of \Gamma and \|x\|/(\|s\|+1) is not much larger than 1 (otherwise the convergence is very slow). The result returned is \int_0^x
e^{-t}t^{s-1}dt.

intformal(x, v=None)

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
intnuminit(a, b, m=0, precision=0)

Initialize tables for integration from a to b, where a and b are coded as in intnum. Only the compactness, the possible existence of singularities, the speed of decrease or the oscillations at infinity are taken into account, and not the values. For instance intnuminit(-1,1) is equivalent to intnuminit(0,Pi), and intnuminit([0,-1/2],oo) is equivalent to intnuminit([-1,-1/2], -oo); on the other hand, the order matters and intnuminit([0,-1/2], [1,-1/3]) is not equivalent to intnuminit([0,-1/3], [1,-1/2]) !

If m is multiply the default number of sampling points by 2^m (increasing the running time by a similar factor).

The result is technical and liable to change in the future, but we document it here for completeness. Let x = \phi(t), t belongs to ]- oo , oo [ be an internally chosen change of variable, achieving double exponential decrease of the integrand at infinity. The integrator intnum will compute

h \sum_{\|n\| < N} \phi'(nh) F(\phi(nh))

for some integration step h and truncation parameter N. In basic use, let

[h, x0, w0, xp, wp, xm, wm] = intnuminit(a,b);
  • h is the integration step
  • x_0 = \phi(0) and w_0 = \phi'(0),
  • xp contains the \phi(nh), 0 < n < N,
  • xm contains the \phi(nh), 0 < -n < N, or is empty.
  • wp contains the \phi'(nh), 0 < n < N,
  • wm contains the \phi'(nh), 0 < -n < N, or is empty.

The arrays xm and wm are left empty when \phi is an odd function. In complicated situations when non-default behaviour is specified at end points, intnuminit may return up to 3 such arrays, corresponding to a splitting of up to 3 integrals of basic type.

If the functions to be integrated later are of the form F = f(t) k(t,z) for some kernel k (e.g. Fourier, Laplace, Mellin,...), it is useful to also precompute the values of f(\phi(nh)), which is accomplished by intfuncinit. The hard part is to determine the behaviour of F at endpoints, depending on z.

isfundamental(x)

True (1) if x is equal to 1 or to the discriminant of a quadratic field, false (0) otherwise.

ispowerful(x)

True (1) if x is a powerful integer, false (0) if not; an integer is powerful if and only if its valuation at all primes dividing x is greater than 1.

? ispowerful(50)
%1 = 0
? ispowerful(100)
%2 = 1
? ispowerful(5^3*(10^1000+1)^2)
%3 = 1
isprime(x, flag=0)

True (1) if x is a prime number, false (0) otherwise. A prime number is a positive integer having exactly two distinct divisors among the natural numbers, namely 1 and itself.

This routine proves or disproves rigorously that a number is prime, which can be very slow when x is indeed prime and has more than 1000 digits, say. Use ispseudoprime to quickly check for compositeness. See also factor. It accepts vector/matrices arguments, and is then applied componentwise.

If flag = 0, use a combination of Baillie-PSW pseudo primality test (see ispseudoprime), Selfridge “p-1” test if x-1 is smooth enough, and Adleman-Pomerance-Rumely-Cohen-Lenstra (APRCL) for general x.

If flag = 1, use Selfridge-Pocklington-Lehmer “p-1” test and output a primality certificate as follows: return

  • 0 if x is composite,
  • 1 if x is small enough that passing Baillie-PSW test guarantees its primality (currently x < 2^{64}, as checked by Jan Feitsma),
  • 2 if x is a large prime whose primality could only sensibly be proven (given the algorithms implemented in PARI) using the APRCL test.
  • Otherwise (x is large and x-1 is smooth) output a three column matrix as a primality certificate. The first column contains prime divisors p of x-1 (such that \prod p^{v_p(x-1)} > x^{1/3}), the second the corresponding elements a_p as in Proposition 8.3.1 in GTM 138 , and the third the output of isprime(p,1).

The algorithm fails if one of the pseudo-prime factors is not prime, which is exceedingly unlikely and well worth a bug report. Note that if you monitor isprime at a high enough debug level, you may see warnings about untested integers being declared primes. This is normal: we ask for partial factorisations (sufficient to prove primality if the unfactored part is not too large), and factor warns us that the cofactor hasn’t been tested. It may or may not be tested later, and may or may not be prime. This does not affect the validity of the whole isprime procedure.

If flag = 2, use APRCL.

ispseudoprime(x, flag=0)

True (1) if x is a strong pseudo prime (see below), false (0) otherwise. If this function returns false, x is not prime; if, on the other hand it returns true, it is only highly likely that x is a prime number. Use isprime (which is of course much slower) to prove that x is indeed prime. The function accepts vector/matrices arguments, and is then applied componentwise.

If flag = 0, checks whether x is a Baillie-Pomerance-Selfridge-Wagstaff pseudo prime (strong Rabin-Miller pseudo prime for base 2, followed by strong Lucas test for the sequence (P,-1), P smallest positive integer such that P^2 - 4 is not a square mod x).

There are no known composite numbers passing this test, although it is expected that infinitely many such numbers exist. In particular, all composites <= 2^{64} are correctly detected (checked using http://www.cecm.sfu.ca/Pseudoprimes/index-2-to-64.html).

If flag > 0, checks whether x is a strong Miller-Rabin pseudo prime for flag randomly chosen bases (with end-matching to catch square roots of -1).

issquarefree(x)

True (1) if x is squarefree, false (0) if not. Here x can be an integer or a polynomial.

kronecker(x, y)

Kronecker symbol (x\|y), where x and y must be of type integer. By definition, this is the extension of Legendre symbol to \mathbb{Z} x \mathbb{Z} by total multiplicativity in both arguments with the following special rules for y = 0, -1 or 2:

  • (x\|0) = 1 if \|x \|= 1 and 0 otherwise.
  • (x\|-1) = 1 if x >= 0 and -1 otherwise.
  • (x\|2) = 0 if x is even and 1 if x = 1,-1 mod 8 and -1 if x = 3,-3 mod 8.
lambertw(y, precision=0)

Lambert W function, solution of the implicit equation xe^x = y, for y > 0.

lcm(x, y=None)

Least common multiple of x and y, i.e. such that \mathrm{lcm}(x,y)*\mathrm{gcd}(x,y) = x*y, up to units. If y is omitted and x is a vector, returns the {lcm} of all components of x. For integer arguments, return the non-negative {lcm}.

When x and y are both given and one of them is a vector/matrix type, the LCM is again taken recursively on each component, but in a different way. If y is a vector, resp. matrix, then the result has the same type as y, and components equal to lcm(x, y[i]), resp. lcm(x, y[,i]). Else if x is a vector/matrix the result has the same type as x and an analogous definition. Note that for these types, lcm is not commutative.

Note that lcm(v) is quite different from

l = v[1]; for (i = 1, #v, l = lcm(l, v[i]))

Indeed, lcm(v) is a scalar, but l may not be (if one of the v[i] is a vector/matrix). The computation uses a divide-conquer tree and should be much more efficient, especially when using the GMP multiprecision kernel (and more subquadratic algorithms become available):

? v = vector(10^5, i, random);
? lcm(v);
time = 546 ms.
? l = v[1]; for (i = 1, #v, l = lcm(l, v[i]))
time = 4,561 ms.
length(x)

Length of x; #x is a shortcut for length(x). This is mostly useful for

  • vectors: dimension (0 for empty vectors),
  • lists: number of entries (0 for empty lists),
  • matrices: number of columns,
  • character strings: number of actual characters (without trailing 0, should you expect it from C char*).
? #"a string"
%1 = 8
? #[3,2,1]
%2 = 3
? #[]
%3 = 0
? #matrix(2,5)
%4 = 5
? L = List([1,2,3,4]); #L
%5 = 4

The routine is in fact defined for arbitrary GP types, but is awkward and useless in other cases: it returns the number of non-code words in x, e.g. the effective length minus 2 for integers since the t_INT type has two code words.

lex(x, y)

Gives the result of a lexicographic comparison between x and y (as -1, 0 or 1). This is to be interpreted in quite a wide sense: It is admissible to compare objects of different types (scalars, vectors, matrices), provided the scalars can be compared, as well as vectors/matrices of different lengths. The comparison is recursive.

In case all components are equal up to the smallest length of the operands, the more complex is considered to be larger. More precisely, the longest is the largest; when lengths are equal, we have matrix > vector > scalar. For example:

? lex([1,3], [1,2,5])
%1 = 1
? lex([1,3], [1,3,-1])
%2 = -1
? lex([1], [[1]])
%3 = -1
? lex([1], [1]~)
%4 = 0
lift(x, v=None)

If v is omitted, lifts intmods from \mathbb{Z}/n\mathbb{Z} in \mathbb{Z}, p-adics from \mathbb{Q}_p to \mathbb{Q} (as truncate), and polmods to polynomials. Otherwise, lifts only polmods whose modulus has main variable v. t_FFELT are not lifted, nor are List elements: you may convert the latter to vectors first, or use apply(lift,L). More generally, components for which such lifts are meaningless (e.g. character strings) are copied verbatim.

? lift(Mod(5,3))
%1 = 2
? lift(3 + O(3^9))
%2 = 3
? lift(Mod(x,x^2+1))
%3 = x
? lift(Mod(x,x^2+1))
%4 = x

Lifts are performed recursively on an object components, but only by one level: once a t_POLMOD is lifted, the components of the result are not lifted further.

? lift(x * Mod(1,3) + Mod(2,3))
%4 = x + 2
? lift(x * Mod(y,y^2+1) + Mod(2,3))
%5 = y*x + Mod(2, 3) \\ do you understand this one?
? lift(x * Mod(y,y^2+1) + Mod(2,3), 'x)
%6 = Mod(y, y^2 + 1)*x + Mod(Mod(2, 3), y^2 + 1)
? lift(%, y)
%7 = y*x + Mod(2, 3)

To recursively lift all components not only by one level, but as long as possible, use liftall. To lift only t_INTMOD s and t_PADIC s components, use liftint. To lift only t_POLMOD s components, use liftpol. Finally, centerlift allows to lift t_INTMOD s and t_PADIC s using centered residues (lift of smallest absolute value).

liftall(x)

Recursively lift all components of x from \mathbb{Z}/n\mathbb{Z} to \mathbb{Z}, from \mathbb{Q}_p to \mathbb{Q} (as truncate), and polmods to polynomials. t_FFELT are not lifted, nor are List elements: you may convert the latter to vectors first, or use apply(liftall,L). More generally, components for which such lifts are meaningless (e.g. character strings) are copied verbatim.

? liftall(x * (1 + O(3)) + Mod(2,3))
%1 = x + 2
? liftall(x * Mod(y,y^2+1) + Mod(2,3)*Mod(z,z^2))
%2 = y*x + 2*z
liftint(x)

Recursively lift all components of x from \mathbb{Z}/n\mathbb{Z} to \mathbb{Z} and from \mathbb{Q}_p to \mathbb{Q} (as truncate). t_FFELT are not lifted, nor are List elements: you may convert the latter to vectors first, or use apply(liftint,L). More generally, components for which such lifts are meaningless (e.g. character strings) are copied verbatim.

? liftint(x * (1 + O(3)) + Mod(2,3))
%1 = x + 2
? liftint(x * Mod(y,y^2+1) + Mod(2,3)*Mod(z,z^2))
%2 = Mod(y, y^2 + 1)*x + Mod(Mod(2*z, z^2), y^2 + 1)
liftpol(x)

Recursively lift all components of x which are polmods to polynomials. t_FFELT are not lifted, nor are List elements: you may convert the latter to vectors first, or use apply(liftpol,L). More generally, components for which such lifts are meaningless (e.g. character strings) are copied verbatim.

? liftpol(x * (1 + O(3)) + Mod(2,3))
%1 = (1 + O(3))*x + Mod(2, 3)
? liftpol(x * Mod(y,y^2+1) + Mod(2,3)*Mod(z,z^2))
%2 = y*x + Mod(2, 3)*z
lindep(v, flag=0)

finds a small non-trivial integral linear combination between components of v. If none can be found return an empty vector.

If v is a vector with real/complex entries we use a floating point (variable precision) LLL algorithm. If flag = 0 the accuracy is chosen internally using a crude heuristic. If flag > 0 the computation is done with an accuracy of flag decimal digits. To get meaningful results in the latter case, the parameter flag should be smaller than the number of correct decimal digits in the input.

? lindep([sqrt(2), sqrt(3), sqrt(2)+sqrt(3)])
%1 = [-1, -1, 1]~

If v is p-adic, flag is ignored and the algorithm LLL-reduces a suitable (dual) lattice.

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

If v is a matrix, flag is ignored and the function returns a non trivial kernel vector (combination of the columns).

? lindep([1,2,3;4,5,6;7,8,9])
%3 = [1, -2, 1]~

If v contains polynomials or power series over some base field, finds a linear relation with coefficients in the field.

? lindep([x*y, x^2 + y, x^2*y + x*y^2, 1])
%4 = [y, y, -1, -y^2]~

For better control, it is preferable to use t_POL rather than t_SER in the input, otherwise one gets a linear combination which is t-adically small, but not necessarily 0. Indeed, power series are first converted to the minimal absolute accuracy occurring among the entries of v (which can cause some coefficients to be ignored), then truncated to polynomials:

? v = [t^2+O(t^4), 1+O(t^2)]; L=lindep(v)
%1 = [1, 0]~
? v*L
%2 = t^2+O(t^4) \\ small but not 0
lngamma(x, precision=0)

Principal branch of the logarithm of the gamma function of x. This function is analytic on the complex plane with non-positive integers removed, and can have much larger arguments than gamma itself.

For x a power series such that x(0) is not a pole of gamma, compute the Taylor expansion. (PARI only knows about regular power series and can’t include logarithmic terms.)

? lngamma(1+x+O(x^2))
%1 = -0.57721566490153286060651209008240243104*x + O(x^2)
? lngamma(x+O(x^2))
 *** at top-level: lngamma(x+O(x^2))
 *** ^-----------------
 *** lngamma: domain error in lngamma: valuation != 0
? lngamma(-1+x+O(x^2))
 *** lngamma: Warning: normalizing a series with 0 leading term.
 *** at top-level: lngamma(-1+x+O(x^2))
 *** ^--------------------
 *** lngamma: domain error in intformal: residue(series, pole) != 0
log(x, precision=0)

Principal branch of the natural logarithm of x belongs to \mathbb{C}^*, i.e. such that {Im(log}(x)) belongs to ]-\Pi,\Pi]. The branch cut lies along the negative real axis, continuous with quadrant 2, i.e. such that \lim_{b\\to 0^+} \log (a+bi) = \log a for a belongs to \mathbb{R}^*. The result is complex (with imaginary part equal to \Pi) if x belongs to \mathbb{R} and x < 0. In general, the algorithm uses the formula

\log(x) ~ (\Pi)/(2{agm}(1, 4/s)) - m \log 2,

if s = x 2^m is large enough. (The result is exact to B bits provided s > 2^{B/2}.) At low accuracies, the series expansion near 1 is used.

p-adic arguments are also accepted for x, with the convention that \log(p) = 0. Hence in particular \exp(\log(x))/x is not in general equal to 1 but to a (p-1)-th root of unity (or ±1 if p = 2) times a power of p.

mapdelete(M, x)

Remove x from the domain of the map M.

? M = Map(["a",1; "b",3; "c",7]);
? mapdelete(M,"b");
? Mat(M)
["a" 1]

["c" 7]
mapget(M, x)

Return the image of x by the map M.

? M=Map(["a",23;"b",43]);
? mapget(M,"a")
%2 = 23
? mapget(M,"b")
%3 = 43

Raises an exception when the key x is not present in M

? mapget(M,"c")
 *** at top-level: mapget(M,"c")
 *** ^-------------
 *** mapget: non-existent component in mapget: index not in map
matadjoint(M, flag=0)

adjoint matrix of M, i.e. a matrix N of cofactors of M, satisfying M*N = \det(M)*\mathrm{Id}. M must be a (non-necessarily invertible) square matrix of dimension n. If flag is 0 or omitted, we try to use Leverrier-Faddeev’s algorithm, which assumes that n! invertible. If it fails or flag = 1, compute T = charpoly(M) independently first and return (-1)^{n-1} (T(x)-T(0))/x evaluated at M.

? a = [1,2,3;3,4,5;6,7,8] * Mod(1,4);
%2 =
[Mod(1, 4) Mod(2, 4) Mod(3, 4)]

[Mod(3, 4) Mod(0, 4) Mod(1, 4)]

[Mod(2, 4) Mod(3, 4) Mod(0, 4)]

Both algorithms use O(n^4) operations in the base ring, and are usually slower than computing the characteristic polynomial or the inverse of M directly.

matalgtobasis(nf, x)

nf being a number field in nfinit format, and x a (row or column) vector or matrix, apply nfalgtobasis to each entry of x.

matbasistoalg(nf, x)

nf being a number field in nfinit format, and x a (row or column) vector or matrix, apply nfbasistoalg to each entry of x.

matcompanion(x)

The left companion matrix to the non-zero polynomial x.

matconcat(v)

Returns a t_MAT built from the entries of v, which may be a t_VEC (concatenate horizontally), a t_COL (concatenate vertically), or a t_MAT (concatenate vertically each column, and concatenate vertically the resulting matrices). The entries of v are always considered as matrices: they can themselves be t_VEC (seen as a row matrix), a t_COL seen as a column matrix), a t_MAT, or a scalar (seen as an 1 x 1 matrix).

? A=[1,2;3,4]; B=[5,6]~; C=[7,8]; D=9;
? matconcat([A, B]) \\ horizontal
%1 =
[1 2 5]

[3 4 6]
? matconcat([A, C]~) \\ vertical
%2 =
[1 2]

[3 4]

[7 8]
? matconcat([A, B; C, D]) \\ block matrix
%3 =
[1 2 5]

[3 4 6]

[7 8 9]

If the dimensions of the entries to concatenate do not match up, the above rules are extended as follows:

  • each entry v_{i,j} of v has a natural length and height: 1 x 
1 for a scalar, 1 x n for a t_VEC of length n, n x 1 for a t_COL, m x n for an m x n t_MAT
  • let H_i be the maximum over j of the lengths of the v_{i,j}, let L_j be the maximum over i of the heights of the v_{i,j}. The dimensions of the (i,j)-th block in the concatenated matrix are H_i x L_j.
  • a scalar s = v_{i,j} is considered as s times an identity matrix of the block dimension \min (H_i,L_j)
  • blocks are extended by 0 columns on the right and 0 rows at the bottom, as needed.
? matconcat([1, [2,3]~, [4,5,6]~]) \\ horizontal
%4 =
[1 2 4]

[0 3 5]

[0 0 6]
? matconcat([1, [2,3], [4,5,6]]~) \\ vertical
%5 =
[1 0 0]

[2 3 0]

[4 5 6]
? matconcat([B, C; A, D]) \\ block matrix
%6 =
[5 0 7 8]

[6 0 0 0]

[1 2 9 0]

[3 4 0 9]
? U=[1,2;3,4]; V=[1,2,3;4,5,6;7,8,9];
? matconcat(matdiagonal([U, V])) \\ block diagonal
%7 =
[1 2 0 0 0]

[3 4 0 0 0]

[0 0 1 2 3]

[0 0 4 5 6]

[0 0 7 8 9]
matdet(x, flag=0)

Determinant of the square matrix x.

If flag = 0, uses an appropriate algorithm depending on the coefficients:

  • integer entries: modular method due to Dixon, Pernet and Stein.
  • real or p-adic entries: classical Gaussian elimination using maximal pivot.
  • intmod entries: classical Gaussian elimination using first non-zero pivot.
  • other cases: Gauss-Bareiss.

If flag = 1, uses classical Gaussian elimination with appropriate pivoting strategy (maximal pivot for real or p-adic coefficients). This is usually worse than the default.

matdetint(B)

Let B be an m x n matrix with integer coefficients. The determinant D of the lattice generated by the columns of B is the square root of \det(B^T B) if B has maximal rank m, and 0 otherwise.

This function uses the Gauss-Bareiss algorithm to compute a positive multiple of D. When B is square, the function actually returns D = \|\det B\|.

This function is useful in conjunction with mathnfmod, which needs to know such a multiple. If the rank is maximal and the matrix non-square, you can obtain D exactly using

matdet( mathnfmod(B, matdetint(B)) )

Note that as soon as one of the dimensions gets large (m or n is larger than 20, say), it will often be much faster to use mathnf(B, 1) or mathnf(B, 4) directly.

matdiagonal(x)

x being a vector, creates the diagonal matrix whose diagonal entries are those of x.

? matdiagonal([1,2,3]);
%1 =
[1 0 0]

[0 2 0]

[0 0 3]

Block diagonal matrices are easily created using matconcat:

? U=[1,2;3,4]; V=[1,2,3;4,5,6;7,8,9];
? matconcat(matdiagonal([U, V]))
%1 =
[1 2 0 0 0]

[3 4 0 0 0]

[0 0 1 2 3]

[0 0 4 5 6]

[0 0 7 8 9]
mateigen(x, flag=0, precision=0)

Returns the (complex) eigenvectors of x as columns of a matrix. If flag = 1, return [L,H], where L contains the eigenvalues and H the corresponding eigenvectors; multiple eigenvalues are repeated according to the eigenspace dimension (which may be less than the eigenvalue multiplicity in the characteristic polynomial).

This function first computes the characteristic polynomial of x and approximates its complex roots (\lambda_i), then tries to compute the eigenspaces as kernels of the x - \lambda_i. This algorithm is ill-conditioned and is likely to miss kernel vectors if some roots of the characteristic polynomial are close, in particular if it has multiple roots.

? A = [13,2; 10,14]; mateigen(A)
%1 =
[-1/2 2/5]

[ 1 1]
? [L,H] = mateigen(A, 1);
? L
%3 = [9, 18]
? H
%4 =
[-1/2 2/5]

[ 1 1]

For symmetric matrices, use qfjacobi instead; for Hermitian matrices, compute

A = real(x);
B = imag(x);
y = matconcat([A, -B; B, A]);

and apply qfjacobi to y.

matfrobenius(M, flag=0, v=None)

Returns the Frobenius form of the square matrix M. If flag = 1, returns only the elementary divisors as a vector of polynomials in the variable v. If flag = 2, returns a two-components vector [F,B] where F is the Frobenius form and B is the basis change so that M = B^{-1}FB.

mathess(x)

Returns a matrix similar to the square matrix x, which is in upper Hessenberg form (zero entries below the first subdiagonal).

mathnf(M, flag=0)

Let R be a Euclidean ring, equal to \mathbb{Z} or to K[X] for some field K. If M is a (not necessarily square) matrix with entries in R, this routine finds the upper triangular Hermite normal form of M. If the rank of M is equal to its number of rows, this is a square matrix. In general, the columns of the result form a basis of the R-module spanned by the columns of M.

The values 0,1,2,3 of flag have a binary meaning, analogous to the one in matsnf; in this case, binary digits of flag mean:

  • 1 (complete output): if set, outputs [H,U], where H is the Hermite normal form of M, and U is a transformation matrix such that MU = [0|H]. The matrix U belongs to {GL}(R). When M has a large kernel, the entries of U are in general huge.
  • 2 (generic input): Deprecated. If set, assume that R = K[X] is a polynomial ring; otherwise, assume that R = \mathbb{Z}. This flag is now useless since the routine always checks whether the matrix has integral entries.

For these 4 values, we use a naive algorithm, which behaves well in small dimension only. Larger values correspond to different algorithms, are restricted to integer matrices, and all output the unimodular matrix U. From now on all matrices have integral entries.

  • flag = 4, returns [H,U] as in “complete output” above, using a variant of LLL reduction along the way. The matrix U is provably small in the L_2 sense, and in general close to optimal; but the reduction is in general slow, although provably polynomial-time.

If flag = 5, uses Batut’s algorithm and output [H,U,P], such that H and U are as before and P is a permutation of the rows such that P applied to MU gives H. This is in general faster than flag = 4 but the matrix U is usually worse; it is heuristically smaller than with the default algorithm.

When the matrix is dense and the dimension is large (bigger than 100, say), flag = 4 will be fastest. When M has maximal rank, then

H = mathnfmod(M, matdetint(M))

will be even faster. You can then recover U as M^{-1}H.

? M = matrix(3,4,i,j,random([-5,5]))
%1 =
[ 0 2 3 0]

[-5 3 -5 -5]

[ 4 3 -5 4]

? [H,U] = mathnf(M, 1);
? U
%3 =
[-1 0 -1 0]

[ 0 5 3 2]

[ 0 3 1 1]

[ 1 0 0 0]

? H
%5 =
[19 9 7]

[ 0 9 1]

[ 0 0 1]

? M*U
%6 =
[0 19 9 7]

[0 0 9 1]

[0 0 0 1]

For convenience, M is allowed to be a t_VEC, which is then automatically converted to a t_MAT, as per the Mat function. For instance to solve the generalized extended gcd problem, one may use

? v = [116085838, 181081878, 314252913,10346840];
? [H,U] = mathnf(v, 1);
? U
%2 =
[ 103 -603 15 -88]

[-146 13 -1208 352]

[ 58 220 678 -167]

[-362 -144 381 -101]
? v*U
%3 = [0, 0, 0, 1]

This also allows to input a matrix as a t_VEC of t_COL s of the same length (which Mat would concatenate to the t_MAT having those columns):

? v = [[1,0,4]~, [3,3,4]~, [0,-4,-5]~]; mathnf(v)
%1 =
[47 32 12]

[ 0 1 0]

[ 0 0 1]
mathnfmod(x, d)

If x is a (not necessarily square) matrix of maximal rank with integer entries, and d is a multiple of the (non-zero) determinant of the lattice spanned by the columns of x, finds the upper triangular Hermite normal form of x.

If the rank of x is equal to its number of rows, the result is a square matrix. In general, the columns of the result form a basis of the lattice spanned by the columns of x. Even when d is known, this is in general slower than mathnf but uses much less memory.

mathnfmodid(x, d)

Outputs the (upper triangular) Hermite normal form of x concatenated with the diagonal matrix with diagonal d. Assumes that x has integer entries. Variant: if d is an integer instead of a vector, concatenate d times the identity matrix.

? m=[0,7;-1,0;-1,-1]
%1 =
[ 0 7]

[-1 0]

[-1 -1]
? mathnfmodid(m, [6,2,2])
%2 =
[2 1 1]

[0 1 0]

[0 0 1]
? mathnfmodid(m, 10)
%3 =
[10 7 3]

[ 0 1 0]

[ 0 0 1]
mathouseholder(Q, v)

applies a sequence Q of Householder transforms, as returned by matqr(M,1) to the vector or matrix v.

matimage(x, flag=0)

Gives a basis for the image of the matrix x as columns of a matrix. A priori the matrix can have entries of any type. If flag = 0, use standard Gauss pivot. If flag = 1, use matsupplement (much slower: keep the default flag!).

matimagecompl(x)

Gives the vector of the column indices which are not extracted by the function matimage, as a permutation (t_VECSMALL). Hence the number of components of matimagecompl(x) plus the number of columns of matimage(x) is equal to the number of columns of the matrix x.

matindexrank(x)

x being a matrix of rank r, returns a vector with two t_VECSMALL components y and z of length r giving a list of rows and columns respectively (starting from 1) such that the extracted matrix obtained from these two vectors using vecextract(x,y,z) is invertible.

matintersect(x, y)

x and y being two matrices with the same number of rows each of whose columns are independent, finds a basis of the \mathbb{Q}-vector space equal to the intersection of the spaces spanned by the columns of x and y respectively. The faster function idealintersect can be used to intersect fractional ideals (projective \mathbb{Z}_K modules of rank 1); the slower but much more general function nfhnf can be used to intersect general \mathbb{Z}_K-modules.

matinverseimage(x, y)

Given a matrix x and a column vector or matrix y, returns a preimage z of y by x if one exists (i.e such that x z = y), an empty vector or matrix otherwise. The complete inverse image is z + {Ker} x, where a basis of the kernel of x may be obtained by matker.

? M = [1,2;2,4];
? matinverseimage(M, [1,2]~)
%2 = [1, 0]~
? matinverseimage(M, [3,4]~)
%3 = []~ \\ no solution
? matinverseimage(M, [1,3,6;2,6,12])
%4 =
[1 3 6]

[0 0 0]
? matinverseimage(M, [1,2;3,4])
%5 = [;] \\ no solution
? K = matker(M)
%6 =
[-2]

[1]
matisdiagonal(x)

Returns true (1) if x is a diagonal matrix, false (0) if not.

matker(x, flag=0)

Gives a basis for the kernel of the matrix x as columns of a matrix. The matrix can have entries of any type, provided they are compatible with the generic arithmetic operations (+, x and /).

If x is known to have integral entries, set flag = 1.

matkerint(x, flag=0)

Gives an LLL-reduced \mathbb{Z}-basis for the lattice equal to the kernel of the matrix x with rational entries.

flag is deprecated, kept for backward compatibility.

matmuldiagonal(x, d)

Product of the matrix x by the diagonal matrix whose diagonal entries are those of the vector d. Equivalent to, but much faster than x*matdiagonal(d).

matmultodiagonal(x, y)

Product of the matrices x and y assuming that the result is a diagonal matrix. Much faster than x*y in that case. The result is undefined if x*y is not diagonal.

matqr(M, flag=0, precision=0)

Returns [Q,R], the QR-decomposition of the square invertible matrix M with real entries: Q is orthogonal and R upper triangular. If flag = 1, the orthogonal matrix is returned as a sequence of Householder transforms: applying such a sequence is stabler and faster than multiplication by the corresponding Q matrix. More precisely, if

[Q,R] = matqr(M);
[q,r] = matqr(M, 1);

then r = R and mathouseholder(q, M) is (close to) R; furthermore

mathouseholder(q, matid(#M)) == Q~

the inverse of Q. This function raises an error if the precision is too low or x is singular.

matrank(x)

Rank of the matrix x.

matrixqz(A, p=None)

A being an m x n matrix in M_{m,n}(\mathbb{Q}), let {Im}_\mathbb{Q} A (resp. {Im}_\mathbb{Z} A) the \mathbb{Q}-vector space (resp. the \mathbb{Z}-module) spanned by the columns of A. This function has varying behavior depending on the sign of p:

If p >= 0, A is assumed to have maximal rank n <= m. The function returns a matrix B belongs to M_{m,n}(\mathbb{Z}), with {Im}_\mathbb{Q} B = {Im}_\mathbb{Q} A, such that the GCD of all its n x n minors is coprime to p; in particular, if p = 0 (default), this GCD is 1.

? minors(x) = vector(#x[,1], i, matdet(x[^i,]));
? A = [3,1/7; 5,3/7; 7,5/7]; minors(A)
%1 = [4/7, 8/7, 4/7] \\ determinants of all 2x2 minors
? B = matrixqz(A)
%2 =
[3 1]

[5 2]

[7 3]
? minors(%)
%3 = [1, 2, 1] \\ B integral with coprime minors

If p = -1, returns the HNF basis of the lattice \mathbb{Z}^n \cap {Im}_\mathbb{Z} A.

If p = -2, returns the HNF basis of the lattice \mathbb{Z}^n \cap {Im}_\mathbb{Q} A.

? matrixqz(A,-1)
%4 =
[8 5]

[4 3]

[0 1]

? matrixqz(A,-2)
%5 =
[2 -1]

[1 0]

[0 1]
matsize(x)

x being a vector or matrix, returns a row vector with two components, the first being the number of rows (1 for a row vector), the second the number of columns (1 for a column vector).

matsnf(X, flag=0)

If X is a (singular or non-singular) matrix outputs the vector of elementary divisors of X, i.e. the diagonal of the Smith normal form of X, normalized so that d_n \| d_{n-1} \| 
... \| d_1.

The binary digits of flag mean:

1 (complete output): if set, outputs [U,V,D], where U and V are two unimodular matrices such that UXV is the diagonal matrix D. Otherwise output only the diagonal of D. If X is not a square matrix, then D will be a square diagonal matrix padded with zeros on the left or the top.

2 (generic input): if set, allows polynomial entries, in which case the input matrix must be square. Otherwise, assume that X has integer coefficients with arbitrary shape.

4 (cleanup): if set, cleans up the output. This means that elementary divisors equal to 1 will be deleted, i.e. outputs a shortened vector D' instead of D. If complete output was required, returns [U',V',D'] so that U'XV' = D' holds. If this flag is set, X is allowed to be of the form vector of elementary divisors' or :math:`[U,V,D] as would normally be output with the cleanup flag unset.

matsolve(M, B)

M being an invertible matrix and B a column vector, finds the solution X of MX = B, using Dixon p-adic lifting method if M and B are integral and Gaussian elimination otherwise. This has the same effect as, but is faster, than M^{-1}*B.

matsolvemod(M, D, B, flag=0)

M being any integral matrix, D a column vector of non-negative integer moduli, and B an integral column vector, gives a small integer solution to the system of congruences \sum_i m_{i,j}x_j = b_i (mod d_i) if one exists, otherwise returns zero. Shorthand notation: B (resp. D) can be given as a single integer, in which case all the b_i (resp. d_i) above are taken to be equal to B (resp. D).

? M = [1,2;3,4];
? matsolvemod(M, [3,4]~, [1,2]~)
%2 = [-2, 0]~
? matsolvemod(M, 3, 1) \\ M X = [1,1]~ over F_3
%3 = [-1, 1]~
? matsolvemod(M, [3,0]~, [1,2]~) \\ x + 2y = 1 (mod 3), 3x + 4y = 2 (in Z)
%4 = [6, -4]~

If flag = 1, all solutions are returned in the form of a two-component row vector [x,u], where x is a small integer solution to the system of congruences and u is a matrix whose columns give a basis of the homogeneous system (so that all solutions can be obtained by adding x to any linear combination of columns of u). If no solution exists, returns zero.

matsupplement(x)

Assuming that the columns of the matrix x are linearly independent (if they are not, an error message is issued), finds a square invertible matrix whose first columns are the columns of x, i.e. supplement the columns of x to a basis of the whole space.

? matsupplement([1;2])
%1 =
[1 0]

[2 1]

Raises an error if x has 0 columns, since (due to a long standing design bug), the dimension of the ambient space (the number of rows) is unknown in this case:

? matsupplement(matrix(2,0))
 *** at top-level: matsupplement(matrix
 *** ^--------------------
 *** matsupplement: sorry, suppl [empty matrix] is not yet implemented.
mattranspose(x)

Transpose of x (also x~). This has an effect only on vectors and matrices.

max(x, y)

Creates the maximum of x and y when they can be compared.

min(x, y)

Creates the maximum of x and y when they can be compared.

minpoly(A, v=None)

minimal polynomial of A with respect to the variable v., i.e. the monic polynomial P of minimal degree (in the variable v) such that P(A) = 0.

modreverse(z)

Let z = Mod(A, T) be a polmod, and Q be its minimal polynomial, which must satisfy {deg}(Q) = {deg}(T). Returns a “reverse polmod” Mod(B, Q), which is a root of T.

This is quite useful when one changes the generating element in algebraic extensions:

? u = Mod(x, x^3 - x -1); v = u^5;
? w = modreverse(v)
%2 = Mod(x^2 - 4*x + 1, x^3 - 5*x^2 + 4*x - 1)

which means that x^3 - 5x^2 + 4x -1 is another defining polynomial for the cubic field

\mathbb{Q}(u) = \mathbb{Q}[x]/(x^3 - x - 1) = \mathbb{Q}[x]/(x^3 - 5x^2 + 4x - 1) = \mathbb{Q}(v),

and that u \\to v^2 - 4v + 1 gives an explicit isomorphism. From this, it is easy to convert elements between the A(u) belongs to \mathbb{Q}(u) and B(v) belongs to \mathbb{Q}(v) representations:

? A = u^2 + 2*u + 3; subst(lift(A), 'x, w)
%3 = Mod(x^2 - 3*x + 3, x^3 - 5*x^2 + 4*x - 1)
? B = v^2 + v + 1; subst(lift(B), 'x, v)
%4 = Mod(26*x^2 + 31*x + 26, x^3 - x - 1)

If the minimal polynomial of z has lower degree than expected, the routine fails

? u = Mod(-x^3 + 9*x, x^4 - 10*x^2 + 1)
? modreverse(u)
 *** modreverse: domain error in modreverse: deg(minpoly(z)) < 4
 *** Break loop: type 'break' to go back to GP prompt
break> Vec( dbg_err() ) \\ ask for more info
["e_DOMAIN", "modreverse", "deg(minpoly(z))", "<", 4,
 Mod(-x^3 + 9*x, x^4 - 10*x^2 + 1)]
break> minpoly(u)
x^2 - 8
moebius(x)

Moebius \mu-function of \|x\|. x must be of type integer.

msatkinlehner(M, Q, H=None)

Let M be a full modular symbol space of level N, as given by msinit, let Q \| N, (Q,N/Q) = 1, and let H be a subspace stable under the Atkin-Lehner involution w_Q. Return the matrix of w_Q acting on H (M if omitted).

? M = msinit(36,2); \\ M_2(Gamma_0(36))
? w = msatkinlehner(M,4); w^2 == 1
%2 = 1
? #w \\ involution acts on a 13-dimensional space
%3 = 13
? M = msinit(36,2, -1); \\ M_2(Gamma_0(36))^-
? w = msatkinlehner(M,4); w^2 == 1
%5 = 1
? #w
%6 = 4
mscuspidal(M, flag=0)

M being a full modular symbol space, as given by msinit, return its cuspidal part S. If flag = 1, return [S,E] its decomposition into cuspidal and Eisenstein parts.

A subspace is given by a structure allowing quick projection and restriction of linear operators; its first component is a matrix with integer coefficients whose columns form a \mathbb{Q}-basis of the subspace.

? M = msinit(2,8, 1); \\ M_8(Gamma_0(2))^+
? [S,E] = mscuspidal(M, 1);
? E[1] \\ 2-dimensional
%3 =
[0 -10]

[0 -15]

[0 -3]

[1 0]

? S[1] \\ 1-dimensional
%4 =
[ 3]

[30]

[ 6]

[-8]
mseisenstein(M)

M being a full modular symbol space, as given by msinit, return its Eisenstein subspace. A subspace is given by a structure allowing quick projection and restriction of linear operators; its first component is a matrix with integer coefficients whose columns form a \mathbb{Q}-basis of the subspace. This is the same basis as given by the second component of mscuspidal(M, 1).

? M = msinit(2,8, 1); \\ M_8(Gamma_0(2))^+
? E = mseisenstein(M);
? E[1] \\ 2-dimensional
%3 =
[0 -10]

[0 -15]

[0 -3]

[1 0]

? E == mscuspidal(M,1)[2]
%4 = 1
mseval(M, s, p=None)

Let \Delta := {Div}^0(\\P^1 (\mathbb{Q})). Let M be a full modular symbol space, as given by msinit, let s be a modular symbol from M, i.e. an element of {Hom}_G(\Delta, V), and let p = [a,b] belongs to \Delta be a path between two elements in \\P^1(\mathbb{Q}), return s(p) belongs to V. The path extremities a and b may be given as t_INT, t_FRAC or oo = (1:0). The symbol s is either

  • a t_COL coding an element of a modular symbol subspace in terms of the fixed basis of {Hom}_G(\Delta,V) chosen in M;
  • a t_VEC (v_i) of elements of V, where the v_i = s(g_i) give the image of the generators g_i of \Delta, see mspathgens. We assume that s is a proper symbol, i.e. that the v_i satisfy the mspathgens relations.

If p is omitted, convert the symbol s to the second form: a vector of the s(g_i).

? M = msinit(2,8,1); \\ M_8(Gamma_0(2))^+
? g = mspathgens(M)[1]
%2 = [[+oo, 0], [0, 1]]
? N = msnew(M)[1]; \\ Q-basis of new subspace
? s = N[,1] \\ t_COL representation
%4 = [3, 30, 6, -8]~
? S = mseval(M, s) \\ t_VEC representation
%5 = [64*x^6-272*x^4+136*x^2-8, 384*x^5+960*x^4+192*x^3-672*x^2-432*x-72]
? mseval(M,s, g[1])
%6 = 64*x^6 - 272*x^4 + 136*x^2 - 8
? mseval(M,S, g[1])
%6 = 64*x^6 - 272*x^4 + 136*x^2 - 8

Note that the symbol should have values in V = \mathbb{Q}[x,y]_{k-2}, we return the de-homogenized values corresponding to y
= 1 instead.

msfromell(E, sign=1)

Let E/\mathbb{Q} be an elliptic curve of conductor N. Return the (cuspidal, new) modular symbol x^+ in H^1_c(X_0(N),\mathbb{Q})^+ (resp. x^- in H^1_c(X_0(N),\mathbb{Q})^- if sign = -1) associated to E. For all primes p not dividing N we have

System Message: WARNING/2 (T_p(x^±) = a_p x^±)

latex exited with error [stdout] This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2016/dev) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./math.tex LaTeX2e <2015/01/01> patch level 2 Babel <3.9m> and hyphenation patterns for 2 languages loaded. (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty (/usr/share/texlive/texmf-dist/tex/latex/ucs/utf8x.def)) (/usr/share/texlive/texmf-dist/tex/latex/ucs/ucs.sty (/usr/share/texlive/texmf-dist/tex/latex/ucs/data/uni-global.def)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty For additional information on amsmath, use the `?’ option. (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) (/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) (./math.aux) (/usr/share/texlive/texmf-dist/tex/latex/ucs/ucsencs.def) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) ! Missing { inserted. <to be read again> \begingroup l.30 $T_p(x^�� ) = a_p x^��$ (/usr/share/texlive/texmf-dist/tex/latex/ucs/data/uni-0.def) ! Missing } inserted. <inserted text> } l.30 $T_p(x^��) = a_p x^��$ [1] (./math.aux) ) (see the transcript file for additional information) Output written on math.dvi (1 page, 504 bytes). Transcript written on math.log.
, where a_p = p+1-\#E(\mathbb{F}_p). This defines a unique symbol up to multiplication by a constant and we normalize it so that the associated p-adic measure yields the p-adic L-function. Namely, we have

x^{±}([0]-[ oo ]) = L(E,1) / \Omega,

for \Omega the real period of E (which fixes x^{±} unless L(E,1) = 0). Furthermore, for all odd fundamental discriminants d coprime to N such that sign.d > 0 and L(E^{(d)},1) != 0, we also have

\sum_{0 <= a < \|d\|} (d\|a) x^{±}([a/\|d\|]-[ oo ])
= L(E^{(d)},1) / \Omega_d,

where (d\|a) is the Kronecker symbol and \Omega_d is the real period of the twist E^{(d)}.

This function returns the pair [M, x], where M is msinit(N,2) and x is

System Message: WARNING/2 (x^±)

latex exited with error [stdout] This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2016/dev) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./math.tex LaTeX2e <2015/01/01> patch level 2 Babel <3.9m> and hyphenation patterns for 2 languages loaded. (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty (/usr/share/texlive/texmf-dist/tex/latex/ucs/utf8x.def)) (/usr/share/texlive/texmf-dist/tex/latex/ucs/ucs.sty (/usr/share/texlive/texmf-dist/tex/latex/ucs/data/uni-global.def)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty For additional information on amsmath, use the `?’ option. (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) (/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) (./math.aux) (/usr/share/texlive/texmf-dist/tex/latex/ucs/ucsencs.def) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) ! Missing { inserted. <to be read again> \begingroup l.30 $x^�� $ (/usr/share/texlive/texmf-dist/tex/latex/ucs/data/uni-0.def) ! Missing } inserted. <inserted text> } l.30 $x^��$ [1] (./math.aux) ) (see the transcript file for additional information) Output written on math.dvi (1 page, 256 bytes). Transcript written on math.log.
as a t_COL (in terms of the fixed basis of {Hom}_G(\Delta,\mathbb{Q}) chosen in M).

? E=ellinit([0,-1,1,-10,-20]); \\ X_0(11)
? [M,xpm]= msfromell(E,1);
? xpm
%3 = [1/5, -1/2, -1/2]~
? p = 101; (mshecke(M,p) - ellap(E,p))*xpm
%4 = [0, 0, 0]~ \\ true at all primes
mshecke(M, p, H=None)

M being a full modular symbol space, as given by msinit, p being a prime number, and H being a Hecke-stable subspace (M if omitted) return the matrix of T_p acting on H (U_p if p divides N). Result is undefined if H is not stable by T_p (resp. U_p).

? M = msinit(11,2); \\ M_2(Gamma_0(11))
? T2 = mshecke(M,2)
%2 =
[3 0 0]

[1 -2 0]

[1 0 -2]
? M = msinit(11,2, 1); \\ M_2(Gamma_0(11))^+
? T2 = mshecke(M,2)
%4 =
[ 3 0]

[-1 -2]

? N = msnew(M)[1]; \\ Q-basis of new cuspidal subspace
%5 =
[ 0]

[-1]

[-1]
? p = 1009; mshecke(M, p, N) \\ action of T_1009 on N
%6 =
[-10]
? ellap(ellinit("11a1"), p)
%7 = -10
msinit(G, V, sign=0)

Given G a finite index subgroup of {SL}(2,\mathbb{Z}) and a finite dimensional representation V of {GL}(2,\mathbb{Q}), creates a space of modular symbols, the G-module {Hom}_G({Div}^0(\\P^1
(\mathbb{Q})), V). This is canonically isomorphic to H^1_c(X(G), V), and allows to compute modular forms for G. If sign is present and non-zero, it must be ±1 and we consider the subspace defined by {Ker} (\sigma -
sign), where \sigma is induced by [-1,0;0,1]. Currently the only supported groups are the \Gamma_0(N), coded by the integer N > 1. The only supported representation is V_k = \mathbb{Q}[X,Y]_{k-2}, coded by the integer k >= 2.

msissymbol(M, s)

M being a full modular symbol space, as given by msinit, check whether s is a modular symbol associated to M.

? M = msinit(7,8, 1); \\ M_8(Gamma_0(7))^+
? N = msnew(M)[1];
? s = N[,1];
? msissymbol(M, s)
%4 = 1
? S = mseval(M,s);
? msissymbol(M, S)
%6 = 1
? [g,R] = mspathgens(M); g
%7 = [[+oo, 0], [0, 1/2], [1/2, 1]]
? #R \\ 3 relations among the generators g_i
%8 = 3
? T = S; T[3]++; \\ randomly perturb S(g_3)
? msissymbol(M, T)
%10 = 0 \\ no longer satisfies the relations
msnew(M)

M being a full modular symbol space, as given by msinit, return the new part of its cuspidal subspace. A subspace is given by a structure allowing quick projection and restriction of linear operators; its first component is a matrix with integer coefficients whose columns form a \mathbb{Q}-basis of the subspace.

? M = msinit(11,8, 1); \\ M_8(Gamma_0(11))^+
? N = msnew(M);
? #N[1] \\ 6-dimensional
%3 = 6
mspathgens(M)

Let \Delta := {Div}^0(\\P^1(\mathbb{Q})). Let M being a full modular symbol space, as given by msinit, return a set of \mathbb{Z}[G]-generators for \Delta. The output is [g,R], where g is a minimal system of generators and R the vector of \mathbb{Z}[G]-relations between the given generators. A relation is coded by a vector of pairs [a_i,i] with a_i belongs to \mathbb{Z}[G] and i the index of a generator, so that \sum_i a_i g[i] = 0.

An element [v]-[u] in \Delta is coded by the “path” [u,v], where oo denotes the point at infinity (1:0) on the projective line. An element of \mathbb{Z}[G] is coded by a “factorization matrix”: the first column contains distinct elements of G, and the second integers:

? M = msinit(11,8); \\ M_8(Gamma_0(11))
? [g,R] = mspathgens(M);
? g
%3 = [[+oo, 0], [0, 1/3], [1/3, 1/2]] \\ 3 paths
? #R \\ a single relation
%4 = 1
? r = R[1]; #r \\ ...involving all 3 generators
%5 = 3
? r[1]
%6 = [[1, 1; [1, 1; 0, 1], -1], 1]
? r[2]
%7 = [[1, 1; [7, -2; 11, -3], -1], 2]
? r[3]
%8 = [[1, 1; [8, -3; 11, -4], -1], 3]

The given relation is of the form \sum_i (1-\gamma_i) g_i = 0, with \gamma_i belongs to \Gamma_0(11). There will always be a single relation involving all generators (corresponding to a round trip along all cusps), then relations involving a single generator (corresponding to 2 and 3-torsion elements in the group:

? M = msinit(2,8); \\ M_8(Gamma_0(2))
? [g,R] = mspathgens(M);
? g
%3 = [[+oo, 0], [0, 1]]

Note that the output depends only on the group G, not on the representation V.

mspathlog(M, p)

Let \Delta := {Div}^0(\\P^1(\mathbb{Q})). Let M being a full modular symbol space, as given by msinit, encoding fixed \mathbb{Z}[G]-generators (g_i) of \Delta (see mspathgens). A path p = [a,b] between two elements in \\P^1(\mathbb{Q}) corresponds to [b]-[a] belongs to \Delta. The path extremities a and b may be given as t_INT, t_FRAC or oo = (1:0).

Returns (p_i) in \mathbb{Z}[G] such that p = \sum_i p_i g_i.

? M = msinit(2,8); \\ M_8(Gamma_0(2))
? [g,R] = mspathgens(M);
? g
%3 = [[+oo, 0], [0, 1]]
? p = mspathlog(M, [1/2,2/3]);
? p[1]
%6 =
[[1, 0; 2, 1] 1]

? p[2]
%7 =
[ [1, 0; 0, 1] 1]

[[3, -1; 4, -1] 1]

Note that the output depends only on the group G, not on the representation V.

msqexpansion(M, projH, serprec=-1)

M being a full modular symbol space, as given by msinit, and projH being a projector on a Hecke-simple subspace (as given by mssplit), return the Fourier coefficients a_n, n <= B of the corresponding normalized newform. If B is omitted, use seriesprecision.

This function uses a naive O(B^2 d^3) algorithm, where d = O(kN) is the dimension of M_k(\Gamma_0(N)).

? M = msinit(11,2, 1); \\ M_2(Gamma_0(11))^+
? L = mssplit(M, msnew(M));
? msqexpansion(M,L[1], 20)
%3 = [1, -2, -1, 2, 1, 2, -2, 0, -2, -2, 1, -2, 4, 4, -1, -4, -2, 4, 0, 2]
? ellan(ellinit("11a1"), 20)
%4 = [1, -2, -1, 2, 1, 2, -2, 0, -2, -2, 1, -2, 4, 4, -1, -4, -2, 4, 0, 2]
mssplit(M, H)

M being a full modular symbol space, as given by msinit(N,k,1) or msinit(N,k,-1) and H being a Hecke-stable subspace of msnew(M), split H into Hecke-simple subspaces. A subspace is given by a structure allowing quick projection and restriction of linear operators; its first component is a matrix with integer coefficients whose columns form a \mathbb{Q}-basis of the subspace.

? M = msinit(11,8, 1); \\ M_8(Gamma_0(11))^+
? L = mssplit(M, msnew(M));
? #L
%3 = 2
? f = msqexpansion(M,L[1],5); f[1].mod
%4 = x^2 + 8*x - 44
? lift(f)
%5 = [1, x, -6*x - 27, -8*x - 84, 20*x - 155]
? g = msqexpansion(M,L[2],5); g[1].mod
%6 = x^4 - 558*x^2 + 140*x + 51744

To a Hecke-simple subspace corresponds an orbit of (normalized) newforms, defined over a number field. In the above example, we printed the polynomials defining the said fields, as well as the first 5 Fourier coefficients (at the infinite cusp) of one such form.

msstar(M, H=None)

M being a full modular symbol space, as given by msinit, return the matrix of the * involution, induced by complex conjugation, acting on the (stable) subspace H (M if omitted).

? M = msinit(11,2); \\ M_2(Gamma_0(11))
? w = msstar(M);
? w^2 == 1
%3 = 1
newtonpoly(x, p)

Gives the vector of the slopes of the Newton polygon of the polynomial x with respect to the prime number p. The n components of the vector are in decreasing order, where n is equal to the degree of x. Vertical slopes occur iff the constant coefficient of x is zero and are denoted by LONG_MAX, the biggest single precision integer representable on the machine (2^{31}-1 (resp. 2^{63}-1) on 32-bit (resp. 64-bit) machines), see valuation (in the PARI manual).

nextprime(x)

Finds the smallest pseudoprime (see ispseudoprime) greater than or equal to x. x can be of any real type. Note that if x is a pseudoprime, this function returns x and not the smallest pseudoprime strictly larger than x. To rigorously prove that the result is prime, use isprime.

nfalgtobasis(nf, x)

Given an algebraic number x in the number field nf, transforms it to a column vector on the integral basis :emphasis:`nf.zk`.

? nf = nfinit(y^2 + 4);
? nf.zk
%2 = [1, 1/2*y]
? nfalgtobasis(nf, [1,1]~)
%3 = [1, 1]~
? nfalgtobasis(nf, y)
%4 = [0, 2]~
? nfalgtobasis(nf, Mod(y, y^2+4))
%4 = [0, 2]~

This is the inverse function of nfbasistoalg.

nfbasistoalg(nf, x)

Given an algebraic number x in the number field nf, transforms it into t_POLMOD form.

? nf = nfinit(y^2 + 4);
? nf.zk
%2 = [1, 1/2*y]
? nfbasistoalg(nf, [1,1]~)
%3 = Mod(1/2*y + 1, y^2 + 4)
? nfbasistoalg(nf, y)
%4 = Mod(y, y^2 + 4)
? nfbasistoalg(nf, Mod(y, y^2+4))
%4 = Mod(y, y^2 + 4)

This is the inverse function of nfalgtobasis.

nfcertify(nf)

nf being as output by nfinit, checks whether the integer basis is known unconditionally. This is in particular useful when the argument to nfinit was of the form [T, listP], specifying a finite list of primes when p-maximality had to be proven.

The function returns a vector of composite integers. If this vector is empty, then nf.zk and nf.disc are correct. Otherwise, the result is dubious. In order to obtain a certified result, one must completely factor each of the given integers, then addprime each of them, then check whether nfdisc(nf.pol) is equal to nf.disc.

nfcompositum(nf, P, Q, flag=0)

Let nf be a number field structure associated to the field K and let P and Q be squarefree polynomials in K[X] in the same variable. Outputs the simple factors of the étale K-algebra A = K(X, Y) / (P(X), Q(Y)). The factors are given by a list of polynomials R in K[X], associated to the number field K(X)/ (R), and sorted by increasing degree (with respect to lexicographic ordering for factors of equal degrees). Returns an error if one of the polynomials is not squarefree.

Note that it is more efficient to reduce to the case where P and Q are irreducible first. The routine will not perform this for you, since it may be expensive, and the inputs are irreducible in most applications anyway. In this case, there will be a single factor R if and only if the number fields defined by P and Q are linearly disjoint (their intersection is K).

The binary digits of flag mean

1: outputs a vector of 4-component vectors [R,a,b,k], where R ranges through the list of all possible compositums as above, and a (resp. b) expresses the root of P (resp. Q) as an element of K(X)/(R). Finally, k is a small integer such that b + ka = X modulo R.

2: assume that P and Q define number fields which are linearly disjoint: both polynomials are irreducible and the corresponding number fields have no common subfield besides K. This allows to save a costly factorization over K. In this case return the single simple factor instead of a vector with one element.

A compositum is often defined by a complicated polynomial, which it is advisable to reduce before further work. Here is an example involving the field K(\zeta_5, 5^{1/5}), K = \mathbb{Q}(\sqrt{5}):

? K = nfinit(y^2-5);
? L = nfcompositum(K, x^5 - y, polcyclo(5), 1); \\ list of [R,a,b,k]
? [R, a] = L[1]; \\ pick the single factor, extract R,a (ignore b,k)
? lift(R) \\ defines the compositum
%3 = x^10 + (-5/2*y + 5/2)*x^9 + (-5*y + 20)*x^8 + (-20*y + 30)*x^7 + \
(-45/2*y + 145/2)*x^6 + (-71/2*y + 121/2)*x^5 + (-20*y + 60)*x^4 + \
(-25*y + 5)*x^3 + 45*x^2 + (-5*y + 15)*x + (-2*y + 6)
? a^5 - y \\ a fifth root of y
%4 = 0
? [T, X] = rnfpolredbest(K, R, 1);
? lift(T) \\ simpler defining polynomial for K[x]/(R)
%6 = x^10 + (-11/2*y + 25/2)
? liftall(X) \\  root of R in K[x]/(T(x))
%7 = (3/4*y + 7/4)*x^7 + (-1/2*y - 1)*x^5 + 1/2*x^2 + (1/4*y - 1/4)
? a = subst(a.pol, 'x, X); \\ a in the new coordinates
? liftall(a)
%8 = (-3/4*y - 7/4)*x^7 - 1/2*x^2
? a^5 - y
%9 = 0
nfdetint(nf, x)

Given a pseudo-matrix x, computes a non-zero ideal contained in (i.e. multiple of) the determinant of x. This is particularly useful in conjunction with nfhnfmod.

nfdisc(T)

field discriminant of the number field defined by the integral, preferably monic, irreducible polynomial T(X). Returns the discriminant of the number field \mathbb{Q}[X]/(T), using the Round 4 algorithm.

Local discriminants, valuations at certain primes.

As in nfbasis, the argument T can be replaced by [T,listP], where listP is as in nfbasis: a vector of pairwise coprime integers (usually distinct primes), a factorization matrix, or a single integer. In that case, the function returns the discriminant of an order whose basis is given by nfbasis(T,listP), which need not be the maximal order, and whose valuation at a prime entry in listP is the same as the valuation of the field discriminant.

In particular, if listP is [p] for a prime p, we can return the p-adic discriminant of the maximal order of \mathbb{Z}_p[X]/(T), as a power of p, as follows:

? padicdisc(T,p) = p^valuation(nfdisc(T,[p]), p);
? nfdisc(x^2 + 6)
%1 = -24
? padicdisc(x^2 + 6, 2)
%2 = 8
? padicdisc(x^2 + 6, 3)
%3 = 3
nfeltadd(nf, x, y)

Given two elements x and y in nf, computes their sum x+y in the number field nf.

nfeltdiv(nf, x, y)

Given two elements x and y in nf, computes their quotient x/y in the number field nf.

nfeltdiveuc(nf, x, y)

Given two elements x and y in nf, computes an algebraic integer q in the number field nf such that the components of x-qy are reasonably small. In fact, this is functionally identical to round(nfdiv(:emphasis:`nf,x,y))`.

nfeltdivmodpr(nf, x, y, pr)

Given two elements x and y in nf and pr a prime ideal in modpr format (see nfmodprinit), computes their quotient x / y modulo the prime ideal pr.

nfeltdivrem(nf, x, y)

Given two elements x and y in nf, gives a two-element row vector [q,r] such that x = qy+r, q is an algebraic integer in nf, and the components of r are reasonably small.

nfeltmod(nf, x, y)

Given two elements x and y in nf, computes an element r of nf of the form r = x-qy with q and algebraic integer, and such that r is small. This is functionally identical to

x - nfmul(nf,round(nfdiv(nf,x,y)),y).

nfeltmul(nf, x, y)

Given two elements x and y in nf, computes their product x*y in the number field nf.

nfeltmulmodpr(nf, x, y, pr)

Given two elements x and y in nf and pr a prime ideal in modpr format (see nfmodprinit), computes their product x*y modulo the prime ideal pr.

nfeltnorm(nf, x)

Returns the absolute norm of x.

nfeltpow(nf, x, k)

Given an element x in nf, and a positive or negative integer k, computes x^k in the number field nf.

nfeltpowmodpr(nf, x, k, pr)

Given an element x in nf, an integer k and a prime ideal pr in modpr format (see nfmodprinit), computes x^k modulo the prime ideal pr.

nfeltreduce(nf, a, id)

Given an ideal id in Hermite normal form and an element a of the number field nf, finds an element r in nf such that a-r belongs to the ideal and r is small.

nfeltreducemodpr(nf, x, pr)

Given an element x of the number field nf and a prime ideal pr in modpr format compute a canonical representative for the class of x modulo pr.

nfelttrace(nf, x)

Returns the absolute trace of x.

nffactor(nf, T)

Factorization of the univariate polynomial T over the number field nf given by nfinit; T has coefficients in nf (i.e. either scalar, polmod, polynomial or column vector). The factors are sorted by increasing degree.

The main variable of nf must be of lower priority than that of T, see priority (in the PARI manual). However if the polynomial defining the number field occurs explicitly in the coefficients of T as modulus of a t_POLMOD or as a t_POL coefficient, its main variable must be the same as the main variable of T. For example,

? nf = nfinit(y^2 + 1);
? nffactor(nf, x^2 + y); \\ OK
? nffactor(nf, x^2 + Mod(y, y^2+1)); \\  OK
? nffactor(nf, x^2 + Mod(z, z^2+1)); \\  WRONG

It is possible to input a defining polynomial for nf instead, but this is in general less efficient since parts of an nf structure will then be computed internally. This is useful in two situations: when you do not need the nf elsewhere, or when you cannot compute the field discriminant due to integer factorization difficulties. In the latter case, if you must use a partial discriminant factorization (as allowed by both nfdisc or nfbasis) to build a partially correct nf structure, always input nf.pol to nffactor, and not your makeshift nf: otherwise factors could be missed.

nffactorback(nf, f, e=None)

Gives back the nf element corresponding to a factorization. The integer 1 corresponds to the empty factorization.

If e is present, e and f must be vectors of the same length (e being integral), and the corresponding factorization is the product of the f[i]^{e[i]}.

If not, and f is vector, it is understood as in the preceding case with e a vector of 1s: we return the product of the f[i]. Finally, f can be a regular factorization matrix.

? nf = nfinit(y^2+1);
? nffactorback(nf, [3, y+1, [1,2]~], [1, 2, 3])
%2 = [12, -66]~
? 3 * (I+1)^2 * (1+2*I)^3
%3 = 12 - 66*I
nffactormod(nf, Q, pr)

Factors the univariate polynomial Q modulo the prime ideal pr in the number field nf. The coefficients of Q belong to the number field (scalar, polmod, polynomial, even column vector) and the main variable of nf must be of lower priority than that of Q (see priority (in the PARI manual)). The prime ideal pr is either in idealprimedec or (preferred) modprinit format. The coefficients of the polynomial factors are lifted to elements of nf:

? K = nfinit(y^2+1);
? P = idealprimedec(K, 3)[1];
? nffactormod(K, x^2 + y*x + 18*y+1, P)
%3 =
[x + (2*y + 1) 1]

[x + (2*y + 2) 1]
? P = nfmodprinit(K, P); \\ convert to nfmodprinit format
? nffactormod(K, x^2 + y*x + 18*y+1)
[x + (2*y + 1) 1]

[x + (2*y + 2) 1]

Same result, of course, here about 10% faster due to the precomputation.

nfgaloisapply(nf, aut, x)

Let nf be a number field as output by nfinit, and let aut be a Galois automorphism of nf expressed by its image on the field generator (such automorphisms can be found using nfgaloisconj). The function computes the action of the automorphism aut on the object x in the number field; x can be a number field element, or an ideal (possibly extended). Because of possible confusion with elements and ideals, other vector or matrix arguments are forbidden.

? nf = nfinit(x^2+1);
? L = nfgaloisconj(nf)
%2 = [-x, x]~
? aut = L[1]; /* the non-trivial automorphism */
? nfgaloisapply(nf, aut, x)
%4 = Mod(-x, x^2 + 1)
? P = idealprimedec(nf,5); /* prime ideals above 5 */
? nfgaloisapply(nf, aut, P[2]) == P[1]
%7 = 0 \\ !!!!
? idealval(nf, nfgaloisapply(nf, aut, P[2]), P[1])
%8 = 1

The surprising failure of the equality test (%7) is due to the fact that although the corresponding prime ideals are equal, their representations are not. (A prime ideal is specified by a uniformizer, and there is no guarantee that applying automorphisms yields the same elements as a direct idealprimedec call.)

The automorphism can also be given as a column vector, representing the image of Mod(x, nf.pol) as an algebraic number. This last representation is more efficient and should be preferred if a given automorphism must be used in many such calls.

? nf = nfinit(x^3 - 37*x^2 + 74*x - 37);
? l = nfgaloisconj(nf); aut = l[2] \\  automorphisms in basistoalg form
%2 = -31/11*x^2 + 1109/11*x - 925/11
? L = matalgtobasis(nf, l); AUT = L[2] \\  same in algtobasis form
%3 = [16, -6, 5]~
? v = [1, 2, 3]~; nfgaloisapply(nf, aut, v) == nfgaloisapply(nf, AUT, v)
%4 = 1 \\  same result...
? for (i=1,10^5, nfgaloisapply(nf, aut, v))
time = 1,451 ms.
? for (i=1,10^5, nfgaloisapply(nf, AUT, v))
time = 1,045 ms. \\  but the latter is faster
nfgaloisconj(nf, flag=0, d=None, precision=0)

nf being a number field as output by nfinit, computes the conjugates of a root r of the non-constant polynomial x = nf[1] expressed as polynomials in r. This also makes sense when the number field is not Galois since some conjugates may lie in the field. nf can simply be a polynomial.

If no flags or flag = 0, use a combination of flag 4 and 1 and the result is always complete. There is no point whatsoever in using the other flags.

If flag = 1, use nfroots: a little slow, but guaranteed to work in polynomial time.

If flag = 2 (OBSOLETE), use complex approximations to the roots and an integral LLL. The result is not guaranteed to be complete: some conjugates may be missing (a warning is issued if the result is not proved complete), especially so if the corresponding polynomial has a huge index, and increasing the default precision may help. This variant is slow and unreliable: don’t use it.

If flag = 4, use galoisinit: very fast, but only applies to (most) Galois fields. If the field is Galois with weakly super-solvable Galois group (see galoisinit), return the complete list of automorphisms, else only the identity element. If present, d is assumed to be a multiple of the least common denominator of the conjugates expressed as polynomial in a root of pol.

This routine can only compute \mathbb{Q}-automorphisms, but it may be used to get K-automorphism for any base field K as follows:

rnfgaloisconj(nfK, R) = \\ K-automorphisms of L = K[X] / (R)
{ my(polabs, N);
 R *= Mod(1, nfK.pol); \\ convert coeffs to polmod elts of K
 polabs = rnfequation(nfK, R);
 N = nfgaloisconj(polabs) % R; \\ Q-automorphisms of L
 \\ select the ones that fix K
 select(s->subst(R, variable(R), Mod(s,R)) == 0, N);
}
K = nfinit(y^2 + 7);
rnfgaloisconj(K, x^4 - y*x^3 - 3*x^2 + y*x + 1) \\ K-automorphisms of L
nfgrunwaldwang(nf, Lpr, Ld, pl, v=None)

Given nf a number field in nf or bnf format, a t_VEC Lpr of primes of nf and a t_VEC Ld of positive integers of the same length, a t_VECSMALL pl of length r_1 the number of real places of nf, computes a polynomial with coefficients in nf defining a cyclic extension of nf of minimal degree satisfying certain local conditions:

  • at the prime Lpr[i], the extension has local degree a multiple of Ld[i];
  • at the i-th real place of nf, it is complex if pl[i] = -1 (no condition if pl[i] = 0).

The extension has degree the LCM of the local degrees. Currently, the degree is restricted to be a prime power for the search, and to be prime for the construction because of the rnfkummer restrictions.

When nf is \mathbb{Q}, prime integers are accepted instead of prid structures. However, their primality is not checked and the behaviour is undefined if you provide a composite number.

Warning. If the number field nf does not contain the n-th roots of unity where n is the degree of the extension to be computed, triggers the computation of the bnf of nf(\zeta_n), which may be costly.

? nf = nfinit(y^2-5);
? pr = idealprimedec(nf,13)[1];
? pol = nfgrunwaldwang(nf, [pr], [2], [0,-1], 'x)
%3 = x^2 + Mod(3/2*y + 13/2, y^2 - 5)
nfhilbert(nf, a, b, pr=None)

If pr is omitted, compute the global quadratic Hilbert symbol (a,b) in nf, that is 1 if x^2 - a y^2 - b z^2 has a non trivial solution (x,y,z) in nf, and -1 otherwise. Otherwise compute the local symbol modulo the prime ideal pr, as output by idealprimedec.

nfhnf(nf, x, flag=0)

Given a pseudo-matrix (A,I), finds a pseudo-basis (B,J) in Hermite normal form of the module it generates. If flag is non-zero, also return the transfomation matrix U such that AU = [0\|B].

nfhnfmod(nf, x, detx)

Given a pseudo-matrix (A,I) and an ideal detx which is contained in (read integral multiple of) the determinant of (A,I), finds a pseudo-basis in Hermite normal form of the module generated by (A,I). This avoids coefficient explosion. detx can be computed using the function nfdetint.

nfinit(pol, flag=0, precision=0)

pol being a non-constant, preferably monic, irreducible polynomial in \mathbb{Z}[X], initializes a number field structure (nf) associated to the field K defined by pol. As such, it’s a technical object passed as the first argument to most nfxxx functions, but it contains some information which may be directly useful. Access to this information via member functions is preferred since the specific data organization specified below may change in the future. Currently, nf is a row vector with 9 components:

nf[1] contains the polynomial pol (:emphasis:`nf.pol`).

nf[2] contains [r1,r2] (:emphasis:`nf.sign`, :emphasis:`nf.r1`, :emphasis:`nf.r2`), the number of real and complex places of K.

nf[3] contains the discriminant d(K) (:emphasis:`nf.disc`) of K.

nf[4] contains the index of nf[1] (:emphasis:`nf.index`), i.e. [\mathbb{Z}_K : \mathbb{Z}[\theta]], where \theta is any root of nf[1].

nf[5] is a vector containing 7 matrices M, G, roundG, T, MD, TI, MDI useful for certain computations in the number field K.

  * M is the (r1+r2) x n matrix whose columns represent the numerical values of the conjugates of the elements of the integral basis.

  * G is an n x n matrix such that T2 = ^t G G, where T2 is the quadratic form T_2(x) = \sum \|\sigma(x)\|^2, \sigma running over the embeddings of K into \mathbb{C}.

  * roundG is a rescaled copy of G, rounded to nearest integers.

  * T is the n x n matrix whose coefficients are {Tr}(\omega_i\omega_j) where the \omega_i are the elements of the integral basis. Note also that \det(T) is equal to the discriminant of the field K. Also, when understood as an ideal, the matrix T^{-1} generates the codifferent ideal.

  * The columns of MD (:emphasis:`nf.diff`) express a \mathbb{Z}-basis of the different of K on the integral basis.

  * TI is equal to the primitive part of T^{-1}, which has integral coefficients.

  * Finally, MDI is a two-element representation (for faster ideal product) of d(K) times the codifferent ideal (:emphasis:`nf.disc:math:*nf.codiff`, which is an integral ideal). MDI is only used in idealinv.

nf[6] is the vector containing the r1+r2 roots (:emphasis:`nf.roots`) of nf[1] corresponding to the r1+r2 embeddings of the number field into \mathbb{C} (the first r1 components are real, the next r2 have positive imaginary part).

nf[7] is an integral basis for \mathbb{Z}_K (:emphasis:`nf.zk`) expressed on the powers of \theta. Its first element is guaranteed to be 1. This basis is LLL-reduced with respect to T_2 (strictly speaking, it is a permutation of such a basis, due to the condition that the first element be 1).

nf[8] is the n x n integral matrix expressing the power basis in terms of the integral basis, and finally

nf[9] is the n x n^2 matrix giving the multiplication table of the integral basis.

If a non monic polynomial is input, nfinit will transform it into a monic one, then reduce it (see flag = 3). It is allowed, though not very useful given the existence of nfnewprec, to input a nf or a bnf instead of a polynomial. It is also allowed to input a rnf, in which case an nf structure associated to the absolute defining polynomial polabs is returned (flag is then ignored).

? nf = nfinit(x^3 - 12); \\ initialize number field Q[X] / (X^3 - 12)
? nf.pol \\ defining polynomial
%2 = x^3 - 12
? nf.disc \\ field discriminant
%3 = -972
? nf.index \\ index of power basis order in maximal order
%4 = 2
? nf.zk \\ integer basis, lifted to Q[X]
%5 = [1, x, 1/2*x^2]
? nf.sign \\ signature
%6 = [1, 1]
? factor(abs(nf.disc )) \\ determines ramified primes
%7 =
[2 2]

[3 5]
? idealfactor(nf, 2)
%8 =
[[2, [0, 0, -1]~, 3, 1, [0, 1, 0]~] 3] \\  p_2^3

Huge discriminants, helping nfdisc.

In case pol has a huge discriminant which is difficult to factor, it is hard to compute from scratch the maximal order. The special input format [pol, B] is also accepted where pol is a polynomial as above and B has one of the following forms

  • an integer basis, as would be computed by nfbasis: a vector of polynomials with first element 1. This is useful if the maximal order is known in advance.
  • an argument listP which specifies a list of primes (see nfbasis). Instead of the maximal order, nfinit then computes an order which is maximal at these particular primes as well as the primes contained in the private prime table (see addprimes). The result is unconditionaly correct when the discriminant nf.disc factors completely over this set of primes. The function nfcertify automates this:
? pol = polcompositum(x^5 - 101, polcyclo(7))[1];
? nf = nfinit( [pol, 10^3] );
? nfcertify(nf)
%3 = []

A priori, nf.zk defines an order which is only known to be maximal at all primes <= 10^3 (no prime <= 10^3 divides nf.index). The certification step proves the correctness of the computation.

If flag = 2: pol is changed into another polynomial P defining the same number field, which is as simple as can easily be found using the polredbest algorithm, and all the subsequent computations are done using this new polynomial. In particular, the first component of the result is the modified polynomial.

If flag = 3, apply polredbest as in case 2, but outputs [nf,Mod(a,P)], where nf is as before and Mod(a,P) = Mod(x,pol) gives the change of variables. This is implicit when pol is not monic: first a linear change of variables is performed, to get a monic polynomial, then polredbest.

nfisideal(nf, x)

Returns 1 if x is an ideal in the number field nf, 0 otherwise.

nfisincl(x, y)

Tests whether the number field K defined by the polynomial x is conjugate to a subfield of the field L defined by y (where x and y must be in \mathbb{Q}[X]). If they are not, the output is the number 0. If they are, the output is a vector of polynomials, each polynomial a representing an embedding of K into L, i.e. being such that y \| x o a.

If y is a number field (nf), a much faster algorithm is used (factoring x over y using nffactor). Before version 2.0.14, this wasn’t guaranteed to return all the embeddings, hence was triggered by a special flag. This is no more the case.

nfisisom(x, y)

As nfisincl, but tests for isomorphism. If either x or y is a number field, a much faster algorithm will be used.

nfkermodpr(nf, x, pr)

Kernel of the matrix a in \mathbb{Z}_K/pr, where pr is in modpr format (see nfmodprinit).

nfmodprinit(nf, pr)

Transforms the prime ideal pr into modpr format necessary for all operations modulo pr in the number field nf.

nfnewprec(nf, precision=0)

Transforms the number field nf into the corresponding data using current (usually larger) precision. This function works as expected if nf is in fact a bnf (update bnf to current precision) but may be quite slow (many generators of principal ideals have to be computed).

nfroots(nf, x)

Roots of the polynomial x in the number field nf given by nfinit without multiplicity (in \mathbb{Q} if nf is omitted). x has coefficients in the number field (scalar, polmod, polynomial, column vector). The main variable of nf must be of lower priority than that of x (see priority (in the PARI manual)). However if the coefficients of the number field occur explicitly (as polmods) as coefficients of x, the variable of these polmods must be the same as the main variable of t (see nffactor).

It is possible to input a defining polynomial for nf instead, but this is in general less efficient since parts of an nf structure will be computed internally. This is useful in two situations: when you don’t need the nf, or when you can’t compute its discriminant due to integer factorization difficulties. In the latter case, addprimes is a possibility but a dangerous one: roots will probably be missed if the (true) field discriminant and an addprimes entry are strictly divisible by some prime. If you have such an unsafe nf, it is safer to input nf.pol.

nfrootsof1(nf)

Returns a two-component vector [w,z] where w is the number of roots of unity in the number field nf, and z is a primitive w-th root of unity.

? K = nfinit(polcyclo(11));
? nfrootsof1(K)
%2 = [22, [0, 0, 0, 0, 0, -1, 0, 0, 0, 0]~]
? z = nfbasistoalg(K, %[2]) \\ in algebraic form
%3 = Mod(-x^5, x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1)
? [lift(z^11), lift(z^2)] \\ proves that the order of z is 22
%4 = [-1, -x^9 - x^8 - x^7 - x^6 - x^5 - x^4 - x^3 - x^2 - x - 1]

This function guesses the number w as the gcd of the \#k(v)^* for unramified v above odd primes, then computes the roots in nf of the w-th cyclotomic polynomial: the algorithm is polynomial time with respect to the field degree and the bitsize of the multiplication table in nf (both of them polynomially bounded in terms of the size of the discriminant). Fields of degree up to 100 or so should require less than one minute.

nfsnf(nf, x, flag=0)

Given a torsion \mathbb{Z}_K-module x associated to the square integral invertible pseudo-matrix (A,I,J), returns an ideal list D = [d_1,...,d_n] which is the Smith normal form of x. In other words, x is isomorphic to \mathbb{Z}_K/d_1\oplus...\oplus\mathbb{Z}_K/d_n and d_i divides d_{i-1} for i >= 2. If flag is non-zero return [D,U,V], where UAV is the identity.

See ZKmodules (in the PARI manual) for the definition of integral pseudo-matrix; briefly, it is input as a 3-component row vector [A,I,J] where I = [b_1,...,b_n] and J = [a_1,...,a_n] are two ideal lists, and A is a square n x n matrix with columns (A_1,...,A_n), seen as elements in K^n (with canonical basis (e_1,...,e_n)). This data defines the \mathbb{Z}_K module x given by

(b_1e_1\oplus...\oplus b_ne_n) / (a_1A_1\oplus...\oplus a_nA_n)
,

The integrality condition is a_{i,j} belongs to b_i a_j^{-1} for all i,j. If it is not satisfied, then the d_i will not be integral. Note that every finitely generated torsion module is isomorphic to a module of this form and even with b_i = Z_K for all i.

nfsolvemodpr(nf, a, b, P)

Let P be a prime ideal in modpr format (see nfmodprinit), let a be a matrix, invertible over the residue field, and let b be a column vector or matrix. This function returns a solution of a.x = 
b; the coefficients of x are lifted to nf elements.

? K = nfinit(y^2+1);
? P = idealprimedec(K, 3)[1];
? P = nfmodprinit(K, P);
? a = [y+1, y; y, 0]; b = [1, y]~
? nfsolvemodpr(K, a,b, P)
%5 = [1, 2]~
nfsplitting(nf, d=None)

Defining polynomial for the splitting field of nf; if d is given, it must be the degree of the splitting field. It is possible to input a defining polynomial T instead but this is in general less efficient.

? K = nfinit(x^3-2);
? nfsplitting(K)
%2 = x^6 + 108
? nfsplitting(x^8-2)
%3 = x^16 + 272*x^8 + 64

The complexity of the algorithm is polynomial in the degree d of the splitting field and the bitsize of T; if d is large the result will likely be unusable, e.g. nfinit will not be an option:

? nfsplitting(x^6-x-1)
[... degree 720 polynomial deleted ...]
time = 11,020 ms.
nfsubfields(pol, d=0)

Finds all subfields of degree d of the number field defined by the (monic, integral) polynomial pol (all subfields if d is null or omitted). The result is a vector of subfields, each being given by [g,h], where g is an absolute equation and h expresses one of the roots of g in terms of the root x of the polynomial defining nf. This routine uses J. Klüners’s algorithm in the general case, and B. Allombert’s galoissubfields when nf is Galois (with weakly supersolvable Galois group).

norm(x)

Algebraic norm of x, i.e. the product of x with its conjugate (no square roots are taken), or conjugates for polmods. For vectors and matrices, the norm is taken componentwise and hence is not the L^2-norm (see norml2). Note that the norm of an element of \mathbb{R} is its square, so as to be compatible with the complex norm.

norml2(x)

Square of the L^2-norm of x. More precisely, if x is a scalar, norml2(x) is defined to be the square of the complex modulus of x (real t_QUAD s are not supported). If x is a polynomial, a (row or column) vector or a matrix, norml2(:math:`x)` is defined recursively as \sum_i norml2(x_i), where (x_i) run through the components of x. In particular, this yields the usual \sum \|x_i\|^2 (resp. \sum \|x_{i,j}\|^2) if x is a polynomial or vector (resp. matrix) with complex components.

? norml2( [ 1, 2, 3 ] ) \\ vector
%1 = 14
? norml2( [ 1, 2; 3, 4] ) \\ matrix
%2 = 30
? norml2( 2*I + x )
%3 = 5
? norml2( [ [1,2], [3,4], 5, 6 ] ) \\ recursively defined
%4 = 91
normlp(x, p=None, precision=0)

L^p-norm of x; sup norm if p is omitted. More precisely, if x is a scalar, normlp(x, p) is defined to be abs(x). If x is a polynomial, a (row or column) vector or a matrix:

  • if p is omitted, normlp(:math:`x)` is defined recursively as \max_i normlp(x_i)), where (x_i) run through the components of x. In particular, this yields the usual sup norm if x is a polynomial or vector with complex components.
  • otherwise, normlp(:math:`x, p)` is defined recursively as (\sum_i
normlp^p(x_i,p))^{1/p}. In particular, this yields the usual (\sum
|x_i|^p)^{1/p} if x is a polynomial or vector with complex components.
? v = [1,-2,3]; normlp(v) \\ vector
%1 = 3
? M = [1,-2;-3,4]; normlp(M) \\ matrix
%2 = 4
? T = (1+I) + I*x^2; normlp(T)
%3 = 1.4142135623730950488016887242096980786
? normlp([[1,2], [3,4], 5, 6]) \\ recursively defined
%4 = 6

? normlp(v, 1)
%5 = 6
? normlp(M, 1)
%6 = 10
? normlp(T, 1)
%7 = 2.4142135623730950488016887242096980786
numbpart(n)

Gives the number of unrestricted partitions of n, usually called p(n) in the literature; in other words the number of nonnegative integer solutions to a+2b+3c+.. .= n. n must be of type integer and n < 10^{15} (with trivial values p(n) = 0 for n < 0 and p(0) = 1). The algorithm uses the Hardy-Ramanujan-Rademacher formula. To explicitly enumerate them, see partitions.

numdiv(x)

Number of divisors of \|x\|. x must be of type integer.

numerator(x)

Numerator of x. The meaning of this is clear when x is a rational number or function. If x is an integer or a polynomial, it is treated as a rational number or function, respectively, and the result is x itself. For polynomials, you probably want to use

numerator( content(x) )

instead.

In other cases, numerator(x) is defined to be denominator(x)*x. This is the case when x is a vector or a matrix, but also for t_COMPLEX or t_QUAD. In particular since a t_PADIC or t_INTMOD has denominator 1, its numerator is itself.

Warning. Multivariate objects are created according to variable priorities, with possibly surprising side effects (x/y is a polynomial, but y/x is a rational function). See priority (in the PARI manual).

omega(x)

Number of distinct prime divisors of \|x\|. x must be of type integer.

? factor(392)
%1 =
[2 3]

[7 2]

? omega(392)
%2 = 2; \\ without multiplicity
? bigomega(392)
%3 = 5; \\ = 3+2, with multiplicity
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 \mathbb{Z}_p) or can be an integral element of a finite extension of \mathbb{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 \mathbb{Q}_p as a.

padicfields(p, N, flag=0)

Returns a vector of polynomials generating all the extensions of degree N of the field \mathbb{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 = \mathbb{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.

padicprec(x, p)

Absolute p-adic precision of the object x. This is the minimum precision of the components of x. The result is LONG_MAX (2^{31}-1 for 32-bit machines or 2^{63}-1 for 64-bit machines) if x is an exact object.

parapply(f, x)

Parallel evaluation of f on the elements of x. The function f must not access global variables or variables declared with local(), and must be free of side effects.

parapply(factor,[2^256 + 1, 2^193 - 1])

factors 2^{256} + 1 and 2^{193} - 1 in parallel.

{
 my(E = ellinit([1,3]), V = vector(12,i,randomprime(2^200)));
 parapply(p->ellcard(E,p), V)
}

computes the order of E(\mathbb{F}_p) for 12 random primes of 200 bits.

pareval(x)

Parallel evaluation of the elements of x, where x is a vector of closures. The closures must be of arity 0, must not access global variables or variables declared with local and must be free of side effects.

parselect(f, A, flag=0)

Selects elements of A according to the selection function f, done in parallel. If flag is 1, return the indices of those elements (indirect selection) The function f must not access global variables or variables declared with local(), and must be free of side effects.

permtonum(x)

Given a permutation x on n elements, gives the number k such that x = numtoperm(n,k), i.e. inverse function of numtoperm. The numbering used is the standard lexicographic ordering, starting at 0.

polclass(D, x=None)

Return the Hilbert class polynomial for the j function for the imaginary quadratic discriminant D in the variable x.

? polclass(-163)
%1 = x + 262537412640768000
? polclass(-51, 'z)
%2 = z^2 + 5541101568*z + 6262062317568
polcoeff(x, n, v=None)

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).

polcompositum(P, Q, flag=0)

P and Q being squarefree polynomials in \mathbb{Z}[X] in the same variable, outputs the simple factors of the étale \mathbb{Q}-algebra A = \mathbb{Q}(X, Y) / (P(X), Q(Y)). The factors are given by a list of polynomials R in \mathbb{Z}[X], associated to the number field \mathbb{Q}(X)/ (R), and sorted by increasing degree (with respect to lexicographic ordering for factors of equal degrees). Returns an error if one of the polynomials is not squarefree.

Note that it is more efficient to reduce to the case where P and Q are irreducible first. The routine will not perform this for you, since it may be expensive, and the inputs are irreducible in most applications anyway. In this case, there will be a single factor R if and only if the number fields defined by P and Q are linearly disjoint (their intersection is \mathbb{Q}).

Assuming P is irreducible (of smaller degree than Q for efficiency), it is in general much faster to proceed as follows

nf = nfinit(P); L = nffactor(nf, Q)[,1];
vector(#L, i, rnfequation(nf, L[i]))

to obtain the same result. If you are only interested in the degrees of the simple factors, the rnfequation instruction can be replaced by a trivial poldegree(P) * poldegree(L[i]).

The binary digits of flag mean

1: outputs a vector of 4-component vectors [R,a,b,k], where R ranges through the list of all possible compositums as above, and a (resp. b) expresses the root of P (resp. Q) as an element of \mathbb{Q}(X)/(R). Finally, k is a small integer such that b + ka = X modulo R.

2: assume that P and Q define number fields which are linearly disjoint: both polynomials are irreducible and the corresponding number fields have no common subfield besides \mathbb{Q}. This allows to save a costly factorization over \mathbb{Q}. In this case return the single simple factor instead of a vector with one element.

A compositum is often defined by a complicated polynomial, which it is advisable to reduce before further work. Here is an example involving the field \mathbb{Q}(\zeta_5, 5^{1/5}):

? L = polcompositum(x^5 - 5, polcyclo(5), 1); \\ list of [R,a,b,k]
? [R, a] = L[1]; \\ pick the single factor, extract R,a (ignore b,k)
? R \\ defines the compositum
%3 = x^20 + 5*x^19 + 15*x^18 + 35*x^17 + 70*x^16 + 141*x^15 + 260*x^14\
+ 355*x^13 + 95*x^12 - 1460*x^11 - 3279*x^10 - 3660*x^9 - 2005*x^8 \
+ 705*x^7 + 9210*x^6 + 13506*x^5 + 7145*x^4 - 2740*x^3 + 1040*x^2 \
- 320*x + 256
? a^5 - 5 \\ a fifth root of 5
%4 = 0
? [T, X] = polredbest(R, 1);
? T \\ simpler defining polynomial for Q[x]/(R)
%6 = x^20 + 25*x^10 + 5
? X \\  root of R in Q[y]/(T(y))
%7 = Mod(-1/11*x^15 - 1/11*x^14 + 1/22*x^10 - 47/22*x^5 - 29/11*x^4 + 7/22,\
x^20 + 25*x^10 + 5)
? a = subst(a.pol, 'x, X) \\ a in the new coordinates
%8 = Mod(1/11*x^14 + 29/11*x^4, x^20 + 25*x^10 + 5)
? a^5 - 5
%9 = 0

In the above example, x^5-5 and the 5-th cyclotomic polynomial are irreducible over \mathbb{Q}; they have coprime degrees so define linearly disjoint extensions and we could have started by

? [R,a] = polcompositum(x^5 - 5, polcyclo(5), 3); \\ [R,a,b,k]
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 polynomials 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]
poldegree(x, v=None)

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

The degree of 0 is -oo. 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.

poldisc(pol, v=None)

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

poldiscreduced(f)

Reduced discriminant vector of the (integral, monic) polynomial f. This is the vector of elementary divisors of \mathbb{Z}[\alpha]/f'(\alpha)\mathbb{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.

polgalois(T, precision=0)

Galois group of the non-constant polynomial T belongs to \mathbb{Q}[X]. In the present version 2.8.0, T must be irreducible and the degree d of T must be less than or equal to 7. If the galdata package has been installed, degrees 8, 9, 10 and 11 are also implemented. By definition, if K = \mathbb{Q}[x]/(T), this computes the action of the Galois group of the Galois closure of K on the d distinct roots of T, up to conjugacy (corresponding to different root orderings).

The output is a 4-component vector [n,s,k,name] with the following meaning: n is the cardinality of the group, s is its signature (s = 1 if the group is a subgroup of the alternating group A_d, s = -1 otherwise) and name is a character string containing name of the transitive group according to the GAP 4 transitive groups library by Alexander Hulpke.

k is more arbitrary and the choice made up to version 2.2.3 of PARI is rather unfortunate: for d > 7, k is the numbering of the group among all transitive subgroups of S_d, as given in “The transitive groups of degree up to eleven”, G. Butler and J. McKay, Communications in Algebra, vol. 11, 1983, pp. 863–911 (group k is denoted T_k there). And for d <= 7, it was ad hoc, so as to ensure that a given triple would denote a unique group. Specifically, for polynomials of degree d <= 7, the groups are coded as follows, using standard notations

In degree 1: S_1 = [1,1,1].

In degree 2: S_2 = [2,-1,1].

In degree 3: A_3 = C_3 = [3,1,1], S_3 = [6,-1,1].

In degree 4: C_4 = [4,-1,1], V_4 = [4,1,1], D_4 = [8,-1,1], A_4 = [12,1,1], S_4 = [24,-1,1].

In degree 5: C_5 = [5,1,1], D_5 = [10,1,1], M_{20} = [20,-1,1], A_5 = [60,1,1], S_5 = [120,-1,1].

In degree 6: C_6 = [6,-1,1], S_3 = [6,-1,2], D_6 = [12,-1,1], A_4 = [12,1,1], G_{18} = [18,-1,1], S_4^ -= [24,-1,1], A_4 x C_2 = [24,-1,2], S_4^ += [24,1,1], G_{36}^ -= [36,-1,1], G_{36}^ += [36,1,1], S_4 x C_2 = [48,-1,1], A_5 = PSL_2(5) = [60,1,1], G_{72} = [72,-1,1], S_5 = PGL_2(5) = [120,-1,1], A_6 = [360,1,1], S_6 = [720,-1,1].

In degree 7: C_7 = [7,1,1], D_7 = [14,-1,1], M_{21} = [21,1,1], M_{42} = [42,-1,1], PSL_2(7) = PSL_3(2) = [168,1,1], A_7 = [2520,1,1], S_7 = [5040,-1,1].

This is deprecated and obsolete, but for reasons of backward compatibility, we cannot change this behavior yet. So you can use the default new_galois_format to switch to a consistent naming scheme, namely k is always the standard numbering of the group among all transitive subgroups of S_n. If this default is in effect, the above groups will be coded as:

In degree 1: S_1 = [1,1,1].

In degree 2: S_2 = [2,-1,1].

In degree 3: A_3 = C_3 = [3,1,1], S_3 = [6,-1,2].

In degree 4: C_4 = [4,-1,1], V_4 = [4,1,2], D_4 = [8,-1,3], A_4 = [12,1,4], S_4 = [24,-1,5].

In degree 5: C_5 = [5,1,1], D_5 = [10,1,2], M_{20} = [20,-1,3], A_5 = [60,1,4], S_5 = [120,-1,5].

In degree 6: C_6 = [6,-1,1], S_3 = [6,-1,2], D_6 = [12,-1,3], A_4 = [12,1,4], G_{18} = [18,-1,5], A_4 x C_2 = [24,-1,6], S_4^ += [24,1,7], S_4^ -= [24,-1,8], G_{36}^ -= [36,-1,9], G_{36}^ += [36,1,10], S_4 x C_2 = [48,-1,11], A_5 = PSL_2(5) = [60,1,12], G_{72} = [72,-1,13], S_5 = PGL_2(5) = [120,-1,14], A_6 = [360,1,15], S_6 = [720,-1,16].

In degree 7: C_7 = [7,1,1], D_7 = [14,-1,2], M_{21} = [21,1,3], M_{42} = [42,-1,4], PSL_2(7) = PSL_3(2) = [168,1,5], A_7 = [2520,1,6], S_7 = [5040,-1,7].

Warning. The method used is that of resolvent polynomials and is sensitive to the current precision. The precision is updated internally but, in very rare cases, a wrong result may be returned if the initial precision was not sufficient.

polgraeffe(f)

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

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 \mathbb{F}_p[t]/(T), you can lift it to \mathbb{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)
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
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
polisirreducible(pol)

pol being a polynomial (univariate in the present version 2.8.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.

pollead(x, v=None)

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.

polrecip(pol)

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

polred(T, flag=0, _arg2=None)

This function is deprecated, use polredbest instead. Finds polynomials with reasonably small coefficients defining subfields of the number field defined by T. One of the polynomials always defines \mathbb{Q} (hence is equal to x-1), and another always defines the same number field as T if T is irreducible.

All T accepted by nfinit are also allowed here; in particular, the format [T, listP] is recommended, e.g. with listP = 10^5 or a vector containing all ramified primes. Otherwise, the maximal order of \mathbb{Q}[x]/(T) must be computed.

The following binary digits of flag are significant:

1: Possibly use a suborder of the maximal order. The primes dividing the index of the order chosen are larger than primelimit or divide integers stored in the addprimes table. This flag is deprecated, the [T, listP] format is more flexible.

2: gives also elements. The result is a two-column matrix, the first column giving primitive elements defining these subfields, the second giving the corresponding minimal polynomials.

? M = polred(x^4 + 8, 2)
%1 =
[1 x - 1]

[1/2*x^2 x^2 + 2]

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

[x x^4 + 8]
? minpoly(Mod(M[2,1], x^4+8))
%2 = x^2 + 2
polredabs(T, flag=0)

Returns a canonical defining polynomial P for the number field \mathbb{Q}[X]/(T) defined by T, such that the sum of the squares of the modulus of the roots (i.e. the T_2-norm) is minimal. Different T defining isomorphic number fields will yield the same P. All T accepted by nfinit are also allowed here, e.g. non-monic polynomials, or pairs [T, listP] specifying that a non-maximal order may be used.

Warning 1. Using a t_POL T requires fully factoring the discriminant of T, which may be very hard. The format [T, listP] computes only a suborder of the maximal order and replaces this part of the algorithm by a polynomial time computation. In that case the polynomial P is a priori no longer canonical, and it may happen that it does not have minimal T_2 norm. The routine attempts to certify the result independently of this order computation (as per nfcertify: we try to prove that the order is maximal); if it fails, the routine returns 0 instead of P. In order to force an output in that case as well, you may either use polredbest, or polredabs(,16), or

polredabs([T, nfbasis([T, listP])])

(In all three cases, the result is no longer canonical.)

Warning 2. Apart from the factorization of the discriminant of T, this routine runs in polynomial time for a fixed degree. But the complexity is exponential in the degree: this routine may be exceedingly slow when the number field has many subfields, hence a lot of elements of small T_2-norm. If you do not need a canonical polynomial, the function polredbest is in general much faster (it runs in polynomial time), and tends to return polynomials with smaller discriminants.

The binary digits of flag mean

1: outputs a two-component row vector [P,a], where P is the default output and Mod(a, P) is a root of the original T.

4: gives all polynomials of minimal T_2 norm; of the two polynomials P(x) and ± P(-x), only one is given.

16: Possibly use a suborder of the maximal order, without attempting to certify the result as in Warning 1: we always return a polynomial and never 0. The result is a priori not canonical.

? T = x^16 - 136*x^14 + 6476*x^12 - 141912*x^10 + 1513334*x^8 \
 - 7453176*x^6 + 13950764*x^4 - 5596840*x^2 + 46225
? T1 = polredabs(T); T2 = polredbest(T);
? [ norml2(polroots(T1)), norml2(polroots(T2)) ]
%3 = [88.0000000, 120.000000]
? [ sizedigit(poldisc(T1)), sizedigit(poldisc(T2)) ]
%4 = [75, 67]
polredbest(T, flag=0)

Finds a polynomial with reasonably small coefficients defining the same number field as T. All T accepted by nfinit are also allowed here (e.g. non-monic polynomials, nf, bnf, [T,Z_K_basis]). Contrary to polredabs, this routine runs in polynomial time, but it offers no guarantee as to the minimality of its result.

This routine computes an LLL-reduced basis for the ring of integers of \mathbb{Q}[X]/(T), then examines small linear combinations of the basis vectors, computing their characteristic polynomials. It returns the separable P polynomial of smallest discriminant (the one with lexicographically smallest abs(Vec(P)) in case of ties). This is a good candidate for subsequent number field computations, since it guarantees that the denominators of algebraic integers, when expressed in the power basis, are reasonably small. With no claim of minimality, though.

It can happen that iterating this functions yields better and better polynomials, until it stabilizes:

? \p5
? P = X^12+8*X^8-50*X^6+16*X^4-3069*X^2+625;
? poldisc(P)*1.
%2 = 1.2622 E55
? P = polredbest(P);
? poldisc(P)*1.
%4 = 2.9012 E51
? P = polredbest(P);
? poldisc(P)*1.
%6 = 8.8704 E44

In this example, the initial polynomial P is the one returned by polredabs, and the last one is stable.

If flag = 1: outputs a two-component row vector [P,a], where P is the default output and Mod(a, P) is a root of the original T.

? [P,a] = polredbest(x^4 + 8, 1)
%1 = [x^4 + 2, Mod(x^3, x^4 + 2)]
? charpoly(a)
%2 = x^4 + 8

In particular, the map \mathbb{Q}[x]/(T) \\to \mathbb{Q}[x]/(P), x:--->Mod(a,P) defines an isomorphism of number fields, which can be computed as

subst(lift(Q), 'x, a)

if Q is a t_POLMOD modulo T; b = modreverse(a) returns a t_POLMOD giving the inverse of the above map (which should be useless since \mathbb{Q}[x]/(P) is a priori a better representation for the number field and its elements).

polredord(x)

Finds polynomials with reasonably small coefficients and of the same degree as that of x defining suborders of the order defined by x. One of the polynomials always defines \mathbb{Q} (hence is equal to (x-1)^n, where n is the degree), and another always defines the same order as x if x is irreducible. Useless function: try polredbest.

polresultant(x, y, v=None, 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 \mathbb{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.

polresultantext(A, B, v=None)

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
polroots(x, precision=0)

Complex roots of the polynomial x, 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.

polrootsff(x, p=None, a=None)

Returns the vector of distinct roots of the polynomial x in the field \mathbb{F}_q defined by the irreducible polynomial a over \mathbb{F}_p. The coefficients of x must be operation-compatible with \mathbb{Z}/p\mathbb{Z}. Either a or p can omitted (in which case both are ignored) if x has t_FFELT coefficients:

? polrootsff(x^2 + 1, 5, y^2+3) \\ over F_5[y]/(y^2+3) ~ F_25
%1 = [Mod(Mod(3, 5), Mod(1, 5)*y^2 + Mod(3, 5)),
 Mod(Mod(2, 5), Mod(1, 5)*y^2 + Mod(3, 5))]
? t = ffgen(y^2 + Mod(3,5), 't); \\ a generator for F_25 as a t_FFELT
? polrootsff(x^2 + 1) \\ not enough information to determine the base field
 *** at top-level: polrootsff(x^2+1)
 *** ^-----------------
 *** polrootsff: incorrect type in factorff.
? polrootsff(x^2 + t^0) \\ make sure one coeff. is a t_FFELT
%3 = [3, 2]
? polrootsff(x^2 + t + 1)
%4 = [2*t + 1, 3*t + 4]

Notice that the second syntax is easier to use and much more readable.

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.

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 \mathbb{Z}/p^r\mathbb{Z}, rather it gives approximations in \mathbb{Z}/p^r\mathbb{Z} of the true roots living in \mathbb{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 \mathbb{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.

polrootsreal(T, ab=None, precision=0)

Real roots of the polynomial T with rational coefficients, multiple roots being included according to their multiplicity. The roots are given to a relative accuracy of realprecision. If argument ab is present, it must be a vector [a,b] with two components (of type t_INT, t_FRAC or t_INFINITY) and we restrict to roots belonging to that closed interval.

? \p9
? polrootsreal(x^2-2)
%1 = [-1.41421356, 1.41421356]~
? polrootsreal(x^2-2, [1,+oo])
%2 = [1.41421356]~
? polrootsreal(x^2-2, [2,3])
%3 = []~
? polrootsreal((x-1)*(x-2), [2,3])
%4 = [2.00000000]~

The algorithm used is a modification of Uspensky’s method (relying on Descartes’s rule of sign), following Rouillier and Zimmerman “Efficient isolation of a polynomial real roots” (http://hal.inria.fr/inria-00072518/. Barring bugs, it is guaranteed to converge and to give the roots to the required accuracy.

Remark. If the polynomial T is of the form Q(x^h) for some h >= 2 and ab is omitted, the routine will apply the algorithm to Q (restricting to non-negative roots when h is even), then take h-th roots. On the other hand, if you want to specify ab, you should apply the routine to Q yourself and a suitable interval [a',b'] using approximate h-th roots adapted to your problem: the function will not perform this change of variables if ab is present.

polsturm(T, ab=None, _arg2=None)

Number of real roots of the real squarefree polynomial T. If the argument ab is present, it must be a vector [a,b] with two real components (of type t_INT, t_REAL, t_FRAC or t_INFINITY) and we count roots belonging to that closed interval.

If possible, you should stick to exact inputs, that is avoid t_REAL s in T and the bounds a,b: the result is then guaranteed and we use a fast algorithm (Uspensky’s method, relying on Descartes’s rule of sign, see polrootsreal); otherwise, we use Sturm’s algorithm and the result may be wrong due to round-off errors.

? T = (x-1)*(x-2)*(x-3);
? polsturm(T)
%2 = 3
? polsturm(T, [-oo,2])
%3 = 2
? polsturm(T, [1/2,+oo])
%4 = 3
? polsturm(T, [1, Pi]) \\ Pi inexact: not recommended !
%5 = 3
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.

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.

poltschirnhaus(x)

Applies a random Tschirnhausen transformation to the polynomial x, which is assumed to be non-constant and separable, so as to obtain a new equation for the étale algebra defined by x. This is for instance useful when computing resolvents, hence is used by the polgalois function.

powers(x, n)

Return the vector [1,x,...,x^n].

precision(x, n=0)

The function has two different behaviors according to whether n is present or not.

If n is missing, the function returns the precision in decimal digits of the PARI object x. If x is an exact object, the largest single precision integer is returned.

? precision(exp(1e-100))
%1 = 134 \\ 134 significant decimal digits
? precision(2 + x)
%2 = 2147483647 \\ exact object
? precision(0.5 + O(x))
%3 = 28 \\ floating point accuracy, NOT series precision
? precision( [ exp(1e-100), 0.5 ] )
%4 = 28 \\ minimal accuracy among components

The return value for exact objects is meaningless since it is not even the same on 32 and 64-bit machines. The proper way to test whether an object is exact is

? isexact(x) = precision(x) == precision(0)

If n is present, the function creates a new object equal to x with a new “precision” n. (This never changes the type of the result. In particular it is not possible to use it to obtain a polynomial from a power series; for that, see truncate.) Now the meaning of precision is different from the above (floating point accuracy), and depends on the type of x:

For exact types, no change. For x a vector or a matrix, the operation is done componentwise.

For real x, n is the number of desired significant decimal digits. If n is smaller than the precision of x, x is truncated, otherwise x is extended with zeros.

For x a p-adic or a power series, n is the desired number of significant p-adic or X-adic digits, where X is the main variable of x. (Note: yes, this is inconsistent.) Note that the precision is a priori distinct from the exponent k appearing in O(*^k); it is indeed equal to k if and only if x is a p-adic or X-adic unit.

? precision(1 + O(x), 10)
%1 = 1 + O(x^10)
? precision(x^2 + O(x^10), 3)
%2 = x^2 + O(x^5)
? precision(7^2 + O(7^10), 3)
%3 = 7^2 + O(7^5)

For the last two examples, note that x^2 + O(x^5) = x^2(1 + O(x^3)) indeed has 3 significant coefficients

precprime(x)

Finds the largest pseudoprime (see ispseudoprime) less than or equal to x. x can be of any real type. Returns 0 if x <= 1. Note that if x is a prime, this function returns x and not the largest prime strictly smaller than x. To rigorously prove that the result is prime, use isprime.

primepi(x)

The prime counting function. Returns the number of primes p, p <= x.

? primepi(10)
%1 = 4;
? primes(5)
%2 = [2, 3, 5, 7, 11]
? primepi(10^11)
%3 = 4118054813

Uses checkpointing and a naive O(x) algorithm.

primes(n)

Creates a row vector whose components are the first n prime numbers. (Returns the empty vector for n <= 0.) A t_VEC n = [a,b] is also allowed, in which case the primes in [a,b] are returned

? primes(10) \\ the first 10 primes
%1 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
? primes([0,29]) \\ the primes up to 29
%2 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
? primes([15,30])
%3 = [17, 19, 23, 29]
psi(x, precision=0)

The \psi-function of x, i.e. the logarithmic derivative \Gamma'(x)/\Gamma(x).

qfauto(G, fl=None)

G being a square and symmetric matrix with integer entries representing a positive definite quadratic form, outputs the automorphism group of the associate lattice. Since this requires computing the minimal vectors, the computations can become very lengthy as the dimension grows. G can also be given by an qfisominit structure. See qfisominit for the meaning of fl.

The output is a two-components vector [o,g] where o is the group order and g is the list of generators (as a vector). For each generator H, the equality G = {^t}H G H holds.

The interface of this function is experimental and will likely change in the future.

This function implements an algorithm of Plesken and Souvignier, following Souvignier’s implementation.

qfautoexport(qfa, flag=0)

qfa being an automorphism group as output by qfauto, export the underlying matrix group as a string suitable for (no flags or flag = 0) GAP or (flag = 1) Magma. The following example computes the size of the matrix group using GAP:

? G = qfauto([2,1;1,2])
%1 = [12, [[-1, 0; 0, -1], [0, -1; 1, 1], [1, 1; 0, -1]]]
? s = qfautoexport(G)
%2 = "Group([[-1, 0], [0, -1]], [[0, -1], [1, 1]], [[1, 1], [0, -1]])"
? extern("echo \"Order("s");\" | gap -q")
%3 = 12
qfbclassno(D, flag=0)

Ordinary class number of the quadratic order of discriminant D, for “small” values of D.

  • if D > 0 or flag = 1, use a O(\|D\|^{1/2}) algorithm (compute L(1,\chi_D) with the approximate functional equation). This is slower than quadclassunit as soon as |D| ~ 10^2 or so and is not meant to be used for large D.
  • if D < 0 and flag = 0 (or omitted), use a O(\|D\|^{1/4}) algorithm (Shanks’s baby-step/giant-step method). It should be faster than quadclassunit for small values of D, say |D| < 10^{18}.

Important warning. In the latter case, this function only implements part of Shanks’s method (which allows to speed it up considerably). It gives unconditionnally correct results for \|D\| < 2.
10^{10}, but may give incorrect results for larger values if the class group has many cyclic factors. We thus recommend to double-check results using the function quadclassunit, which is about 2 to 3 times slower in the above range, assuming GRH. We currently have no counter-examples but they should exist: we’d appreciate a bug report if you find one.

Warning. Contrary to what its name implies, this routine does not compute the number of classes of binary primitive forms of discriminant D, which is equal to the narrow class number. The two notions are the same when D < 0 or the fundamental unit \varepsilon has negative norm; when D
> 0 and N\varepsilon > 0, the number of classes of forms is twice the ordinary class number. This is a problem which we cannot fix for backward compatibility reasons. Use the following routine if you are only interested in the number of classes of forms:

QFBclassno(D) =
qfbclassno(D) * if (D < 0 || norm(quadunit(D)) < 0, 1, 2)

Here are a few examples:

? qfbclassno(400000028)
time = 3,140 ms.
%1 = 1
? quadclassunit(400000028).no
time = 20 ms. \\{ much faster}
%2 = 1
? qfbclassno(-400000028)
time = 0 ms.
%3 = 7253 \\{ correct, and fast enough}
? quadclassunit(-400000028).no
time = 0 ms.
%4 = 7253

See also qfbhclassno.

qfbcompraw(x, y)

composition of the binary quadratic forms x and y, without reduction of the result. This is useful e.g. to compute a generating element of an ideal. The result is undefined if x and y do not have the same discriminant.

qfbhclassno(x)

Hurwitz class number of x, where x is non-negative and congruent to 0 or 3 modulo 4. For x > 5.
10^5, we assume the GRH, and use quadclassunit with default parameters.

qfbil(x, y, q=None)

Evaluate the bilinear form q (symmetric matrix) at the vectors (x,y); if q omitted, use the standard Euclidean scalar product, corresponding to the identity matrix.

Roughly equivalent to x~ * q * y, but a little faster and more convenient (does not distinguish between column and row vectors):

? x = [1,2,3]~; y = [-1,0,1]~; qfbil(x,y)
%1 = 2
? q = [1,2,3;2,2,-1;3,-1,0]; qfbil(x,y, q)
%2 = -13
? for(i=1,10^6, qfbil(x,y,q))
%3 = 568ms
? for(i=1,10^6, x~*q*y)
%4 = 717ms

The associated quadratic form is also available, as qfnorm, slightly faster:

? for(i=1,10^6, qfnorm(x,q))
time = 444ms
? for(i=1,10^6, qfnorm(x))
time = 176 ms.
? for(i=1,10^6, qfbil(x,y))
time = 208 ms.
qfbnucomp(x, y, L)

composition of the primitive positive definite binary quadratic forms x and y (type t_QFI) using the NUCOMP and NUDUPL algorithms of Shanks, à la Atkin. L is any positive constant, but for optimal speed, one should take L = \|D/4\|^{1/4}, i.e. sqrtnint(abs(D) >> 2,4), where D is the common discriminant of x and y. When x and y do not have the same discriminant, the result is undefined.

The current implementation is slower than the generic routine for small D, and becomes faster when D has about 45 bits.

qfbnupow(x, n, L=None)

n-th power of the primitive positive definite binary quadratic form x using Shanks’s NUCOMP and NUDUPL algorithms; if set, L should be equal to sqrtnint(abs(D) >> 2,4), where D < 0 is the discriminant of x.

The current implementation is slower than the generic routine for small discriminant D, and becomes faster for D ~ 2^45.

qfbpowraw(x, n)

n-th power of the binary quadratic form x, computed without doing any reduction (i.e. using qfbcompraw). Here n must be non-negative and n < 2^{31}.

qfbprimeform(x, p, precision=0)

Prime binary quadratic form of discriminant x whose first coefficient is p, where \|p\| is a prime number. By abuse of notation, p = ± 1 is also valid and returns the unit form. Returns an error if x is not a quadratic residue mod p, or if x < 0 and p < 0. (Negative definite t_QFI are not implemented.) In the case where x > 0, the “distance” component of the form is set equal to zero according to the current precision.

qfbred(x, flag=0, d=None, isd=None, sd=None)

Reduces the binary quadratic form x (updating Shanks’s distance function if x is indefinite). The binary digits of flag are toggles meaning

  1: perform a single reduction step

  2: don’t update Shanks’s distance

The arguments d, isd, sd, if present, supply the values of the discriminant, floor{\sqrt{d}}, and \sqrt{d} respectively (no checking is done of these facts). If d < 0 these values are useless, and all references to Shanks’s distance are irrelevant.

qfbredsl2(x, data=None)

Reduction of the (real or imaginary) binary quadratic form x, return [y,g] where y is reduced and g in {SL}(2,\mathbb{Z}) is such that g.x = y; data, if present, must be equal to [D, sqrtint(D)], where D > 0 is the discriminant of x. In case x is t_QFR, the distance component is unaffected.

qfbsolve(Q, p)

Solve the equation Q(x,y) = p over the integers, where Q is a binary quadratic form and p a prime number.

Return [x,y] as a two-components vector, or zero if there is no solution. Note that this function returns only one solution and not all the solutions.

Let D = \mathrm{disc} Q. The algorithm used runs in probabilistic polynomial time in p (through the computation of a square root of D modulo p); it is polynomial time in D if Q is imaginary, but exponential time if Q is real (through the computation of a full cycle of reduced forms). In the latter case, note that bnfisprincipal provides a solution in heuristic subexponential time in D assuming the GRH.

qfgaussred(q)

decomposition into squares of the quadratic form represented by the symmetric matrix q. The result is a matrix whose diagonal entries are the coefficients of the squares, and the off-diagonal entries on each line represent the bilinear forms. More precisely, if (a_{ij}) denotes the output, one has

q(x) = \sum_i a_{ii} (x_i + \sum_{j != i} a_{ij} x_j)^2

? qfgaussred([0,1;1,0])
%1 =
[1/2 1]

[-1 -1/2]

This means that 2xy = (1/2)(x+y)^2 - (1/2)(x-y)^2.

qfisom(G, H, fl=None)

G, H being square and symmetric matrices with integer entries representing positive definite quadratic forms, return an invertible matrix S such that G = {^t}S H S. This defines a isomorphism between the corresponding lattices. Since this requires computing the minimal vectors, the computations can become very lengthy as the dimension grows. See qfisominit for the meaning of fl.

G can also be given by an qfisominit structure which is preferable if several forms H need to be compared to G.

This function implements an algorithm of Plesken and Souvignier, following Souvignier’s implementation.

qfisominit(G, fl=None)

G being a square and symmetric matrix with integer entries representing a positive definite quadratic form, return an isom structure allowing to compute isomorphisms between G and other quadratic forms faster.

The interface of this function is experimental and will likely change in future release.

If present, the optional parameter fl must be a t_VEC with two components. It allows to specify the invariants used, which can make the computation faster or slower. The components are

  • fl[1] Depth of scalar product combination to use.
  • fl[2] Maximum level of Bacher polynomials to use.

Since this function computes the minimal vectors, it can become very lengthy as the dimension of G grows.

qfjacobi(A, precision=0)

Apply Jacobi’s eigenvalue algorithm to the real symmetric matrix A. This returns [L, V], where

  • L is the vector of (real) eigenvalues of A, sorted in increasing order,
  • V is the corresponding orthogonal matrix of eigenvectors of A.
? \p19
? A = [1,2;2,1]; mateigen(A)
%1 =
[-1 1]

[ 1 1]
? [L, H] = qfjacobi(A);
? L
%3 = [-1.000000000000000000, 3.000000000000000000]~
? H
%4 =
[ 0.7071067811865475245 0.7071067811865475244]

[-0.7071067811865475244 0.7071067811865475245]
? norml2( (A-L[1])*H[,1] ) \\ approximate eigenvector
%5 = 9.403954806578300064 E-38
? norml2(H*H~ - 1)
%6 = 2.350988701644575016 E-38 \\ close to orthogonal
qflll(x, flag=0)

LLL algorithm applied to the columns of the matrix x. The columns of x may be linearly dependent. The result is a unimodular transformation matrix T such that x
.T is an LLL-reduced basis of the lattice generated by the column vectors of x. Note that if x is not of maximal rank T will not be square. The LLL parameters are (0.51,0.99), meaning that the Gram-Schmidt coefficients for the final basis satisfy \mu_{i,j} <= \|0.51\|, and the Lovász’s constant is 0.99.

If flag = 0 (default), assume that x has either exact (integral or rational) or real floating point entries. The matrix is rescaled, converted to integers and the behavior is then as in flag = 1.

If flag = 1, assume that x is integral. Computations involving Gram-Schmidt vectors are approximate, with precision varying as needed (Lehmer’s trick, as generalized by Schnorr). Adapted from Nguyen and Stehlé’s algorithm and Stehlé’s code (fplll-1.3).

If flag = 2, x should be an integer matrix whose columns are linearly independent. Returns a partially reduced basis for x, using an unpublished algorithm by Peter Montgomery: a basis is said to be partially reduced if \|v_i ± v_j\| >= \|v_i\| for any two distinct basis vectors v_i, 
v_j.

This is faster than flag = 1, esp. when one row is huge compared to the other rows (knapsack-style), and should quickly produce relatively short vectors. The resulting basis is not LLL-reduced in general. If LLL reduction is eventually desired, avoid this partial reduction: applying LLL to the partially reduced matrix is significantly slower than starting from a knapsack-type lattice.

If flag = 4, as flag = 1, returning a vector [K, T] of matrices: the columns of K represent a basis of the integer kernel of x (not LLL-reduced in general) and T is the transformation matrix such that x.T is an LLL-reduced \mathbb{Z}-basis of the image of the matrix x.

If flag = 5, case as case 4, but x may have polynomial coefficients.

If flag = 8, same as case 0, but x may have polynomial coefficients.

qflllgram(G, flag=0)

Same as qflll, except that the matrix G = x~ * x is the Gram matrix of some lattice vectors x, and not the coordinates of the vectors themselves. In particular, G must now be a square symmetric real matrix, corresponding to a positive quadratic form (not necessarily definite: x needs not have maximal rank). The result is a unimodular transformation matrix T such that x.T is an LLL-reduced basis of the lattice generated by the column vectors of x. See qflll for further details about the LLL implementation.

If flag = 0 (default), assume that G has either exact (integral or rational) or real floating point entries. The matrix is rescaled, converted to integers and the behavior is then as in flag = 1.

If flag = 1, assume that G is integral. Computations involving Gram-Schmidt vectors are approximate, with precision varying as needed (Lehmer’s trick, as generalized by Schnorr). Adapted from Nguyen and Stehlé’s algorithm and Stehlé’s code (fplll-1.3).

flag = 4: G has integer entries, gives the kernel and reduced image of x.

flag = 5: same as 4, but G may have polynomial coefficients.

qfminim(x, b=None, m=None, flag=0, precision=0)

x being a square and symmetric matrix representing a positive definite quadratic form, this function deals with the vectors of x whose norm is less than or equal to b, enumerated using the Fincke-Pohst algorithm, storing at most m vectors (no limit if m is omitted). The function searches for the minimal non-zero vectors if b is omitted. The behavior is undefined if x is not positive definite (a “precision too low” error is most likely, although more precise error messages are possible). The precise behavior depends on flag.

If flag = 0 (default), seeks at most 2m vectors. The result is a three-component vector, the first component being the number of vectors found, the second being the maximum norm found, and the last vector is a matrix whose columns are the vectors found, only one being given for each pair ± v (at most m such pairs, unless m was omitted). The vectors are returned in no particular order.

If flag = 1, ignores m and returns [N,v], where v is a non-zero vector of length N <= b, or [] if no non-zero vector has length <= b. If no explicit b is provided, return a vector of smallish norm (smallest vector in an LLL-reduced basis).

In these two cases, x must have integral entries. The implementation uses low precision floating point computations for maximal speed, which gives incorrect result when x has large entries. (The condition is checked in the code and the routine raises an error if large rounding errors occur.) A more robust, but much slower, implementation is chosen if the following flag is used:

If flag = 2, x can have non integral real entries. In this case, if b is omitted, the “minimal” vectors only have approximately the same norm. If b is omitted, m is an upper bound for the number of vectors that will be stored and returned, but all minimal vectors are nevertheless enumerated. If m is omitted, all vectors found are stored and returned; note that this may be a huge vector!

? x = matid(2);
? qfminim(x) \\ 4 minimal vectors of norm 1: ±[0,1], ±[1,0]
%2 = [4, 1, [0, 1; 1, 0]]
? { x =
[4, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 1, 0,-1, 0, 0, 0,-2;
 2, 4,-2,-2, 0,-2, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0,-1, 0, 1,-1,-1;
 0,-2, 4, 0,-2, 0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1, 0, 0, 1,-1,-1, 0, 0;
 0,-2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 1,-1, 0, 1,-1, 1, 0;
 0, 0,-2, 0, 4, 0, 0, 0, 1,-1, 0, 0, 1, 0, 0, 0,-2, 0, 0,-1, 1, 1, 0, 0;
-2, -2,0, 0, 0, 4,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,-1, 1, 1;
 0, 0, 0, 0, 0,-2, 4,-2, 0, 0, 0, 0, 0, 1, 0, 0, 0,-1, 0, 0, 0, 1,-1, 0;
 0, 0, 0, 0, 0, 0,-2, 4, 0, 0, 0, 0,-1, 0, 0, 0, 0, 0,-1,-1,-1, 0, 1, 0;
 0, 0, 0, 0, 1,-1, 0, 0, 4, 0,-2, 0, 1, 1, 0,-1, 0, 1, 0, 0, 0, 0, 0, 0;
 0, 0, 0, 0,-1, 0, 0, 0, 0, 4, 0, 0, 1, 1,-1, 1, 0, 0, 0, 1, 0, 0, 1, 0;
 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 4,-2, 0,-1, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 4,-1, 1, 0, 0,-1, 1, 0, 1, 1, 1,-1, 0;
 1, 0,-1, 1, 1, 0, 0,-1, 1, 1, 0,-1, 4, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1,-1;
-1,-1, 1,-1, 0, 0, 1, 0, 1, 1,-1, 1, 0, 4, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1;
 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0, 1, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1, 1, 0, 4, 0, 0, 0, 0, 1, 1, 0, 0;
 0, 0, 1, 0,-2, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0, 4, 1, 1, 1, 0, 0, 1, 1;
 1, 0, 0, 1, 0, 0,-1, 0, 1, 0,-1, 1, 1, 0, 0, 0, 1, 4, 0, 1, 1, 0, 1, 0;
 0, 0, 0,-1, 0, 1, 0,-1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 4, 0, 1, 1, 0, 1;
-1, -1,1, 0,-1, 1, 0,-1, 0, 1,-1, 1, 0, 1, 0, 0, 1, 1, 0, 4, 0, 0, 1, 1;
 0, 0,-1, 1, 1, 0, 0,-1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 4, 1, 0, 1;
 0, 1,-1,-1, 1,-1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 4, 0, 1;
 0,-1, 0, 1, 0, 1,-1, 1, 0, 1, 0,-1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 4, 1;
-2,-1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 4]; }
? qfminim(x,,0) \\ the Leech lattice has 196560 minimal vectors of norm 4
time = 648 ms.
%4 = [196560, 4, [;]]
? qfminim(x,,0,2); \\ safe algorithm. Slower and unnecessary here.
time = 18,161 ms.
%5 = [196560, 4.000061035156250000, [;]]

In the last example, we store 0 vectors to limit memory use. All minimal vectors are nevertheless enumerated. Provided parisize is about 50MB, qfminim(x) succeeds in 2.5 seconds.

qfnorm(x, q=None)

Evaluate the binary quadratic form q (symmetric matrix) at the vector x. If q omitted, use the standard Euclidean form, corresponding to the identity matrix.

Equivalent to x~ * q * x, but about twice faster and more convenient (does not distinguish between column and row vectors):

? x = [1,2,3]~; qfnorm(x)
%1 = 14
? q = [1,2,3;2,2,-1;3,-1,0]; qfnorm(x, q)
%2 = 23
? for(i=1,10^6, qfnorm(x,q))
time = 384ms.
? for(i=1,10^6, x~*q*x)
time = 729ms.

We also allow t_MAT s of compatible dimensions for x, and return x~ * q * x in this case as well:

? M = [1,2,3;4,5,6;7,8,9]; qfnorm(M) \\ Gram matrix
%5 =
[66 78 90]

[78 93 108]

[90 108 126]

? for(i=1,10^6, qfnorm(M,q))
time = 2,144 ms.
? for(i=1,10^6, M~*q*M)
time = 2,793 ms.

The polar form is also available, as qfbil.

qfparam(G, sol, flag=0)

Coefficients of binary quadratic forms that parametrize the solutions of the ternary quadratic form G, using the particular solution sol. flag is optional and can be 1, 2, or 3, in which case the flag-th form is reduced. The default is flag = 0 (no reduction).

? G = [1,0,0;0,1,0;0,0,-34];
? M = qfparam(G, qfsolve(G))
%2 =
[ 3 -10 -3]

[-5 -6 5]

[ 1 0 1]

Indeed, the solutions can be parametrized as

(3x^2 - 10xy - 3y^2)^2 + (-5x^2 - 6xy + 5y^2)^2 -34(x^2 + y^2)^2 = 0.

? v = y^2 * M*[1,x/y,(x/y)^2]~
%3 = [3*x^2 - 10*y*x - 3*y^2, -5*x^2 - 6*y*x + 5*y^2, -x^2 - y^2]~
? v~*G*v
%4 = 0
qfperfection(G)

G being a square and symmetric matrix with integer entries representing a positive definite quadratic form, outputs the perfection rank of the form. That is, gives the rank of the family of the s symmetric matrices v_iv_i^t, where s is half the number of minimal vectors and the v_i (1 <= i <= s) are the minimal vectors.

Since this requires computing the minimal vectors, the computations can become very lengthy as the dimension of x grows.

qfrep(q, B, flag=0)

q being a square and symmetric matrix with integer entries representing a positive definite quadratic form, count the vectors representing successive integers.

  • If flag = 0, count all vectors. Outputs the vector whose i-th entry, 1 <= i <= B is half the number of vectors v such that q(v) = i.
  • If flag = 1, count vectors of even norm. Outputs the vector whose i-th entry, 1 <= i <= B is half the number of vectors such that q(v) = 2i.
? q = [2, 1; 1, 3];
? qfrep(q, 5)
%2 = Vecsmall([0, 1, 2, 0, 0]) \\ 1 vector of norm 2, 2 of norm 3, etc.
? qfrep(q, 5, 1)
%3 = Vecsmall([1, 0, 0, 1, 0]) \\ 1 vector of norm 2, 0 of norm 4, etc.

This routine uses a naive algorithm based on qfminim, and will fail if any entry becomes larger than 2^{31} (or 2^{63}).

qfsign(x)

Returns [p,m] the signature of the quadratic form represented by the symmetric matrix x. Namely, p (resp. m) is the number of positive (resp. negative) eigenvalues of x.The result is computed using Gaussian reduction.

qfsolve(G)

Given a square symmetric matrix G of dimension n >= 1, solve over \mathbb{Q} the quadratic equation X^tGX = 0. The matrix G must have rational coefficients. The solution might be a single non-zero vector (vectorv) or a matrix (whose columns generate a totally isotropic subspace).

If no solution exists, returns an integer, that can be a prime p such that there is no local solution at p, or -1 if there is no real solution, or -2 if n = 2 and -\det G is positive but not a square (which implies there is a real solution, but no local solution at some p dividing \det G).

? G = [1,0,0;0,1,0;0,0,-34];
? qfsolve(G)
%1 = [-3, -5, 1]~
? qfsolve([1,0; 0,2])
%2 = -1 \\ no real solution
? qfsolve([1,0,0;0,3,0; 0,0,-2])
%3 = 3 \\ no solution in Q_3
? qfsolve([1,0; 0,-2])
%4 = -2 \\ no solution, n = 2
quadclassunit(D, flag=0, tech=None, precision=0)

Buchmann-McCurley’s sub-exponential algorithm for computing the class group of a quadratic order of discriminant D.

This function should be used instead of qfbclassno or quadregula when D < -10^{25}, D > 10^{10}, or when the structure is wanted. It is a special case of bnfinit, which is slower, but more robust.

The result is a vector v whose components should be accessed using member functions:

  • :math:`v.no`: the class number
  • :math:`v.cyc`: a vector giving the structure of the class group as a product of cyclic groups;
  • :math:`v.gen`: a vector giving generators of those cyclic groups (as binary quadratic forms).
  • :math:`v.reg`: the regulator, computed to an accuracy which is the maximum of an internal accuracy determined by the program and the current default (note that once the regulator is known to a small accuracy it is trivial to compute it to very high accuracy, see the tutorial).

The flag is obsolete and should be left alone. In older versions, it supposedly computed the narrow class group when D > 0, but this did not work at all; use the general function bnfnarrow.

Optional parameter tech is a row vector of the form [c_1, c_2], where c_1 <= c_2 are non-negative real numbers which control the execution time and the stack size, see GRHbnf (in the PARI manual). The parameter is used as a threshold to balance the relation finding phase against the final linear algebra. Increasing the default c_1 means that relations are easier to find, but more relations are needed and the linear algebra will be harder. The default value for c_1 is 0 and means that it is taken equal to c_2. The parameter c_2 is mostly obsolete and should not be changed, but we still document it for completeness: we compute a tentative class group by generators and relations using a factorbase of prime ideals <= c_1 (\log \|D\|)^2, then prove that ideals of norm <= c_2 (\log \|D\|)^2 do not generate a larger group. By default an optimal c_2 is chosen, so that the result is provably correct under the GRH — a famous result of Bach states that c_2 = 6 is fine, but it is possible to improve on this algorithmically. You may provide a smaller c_2, it will be ignored (we use the provably correct one); you may provide a larger c_2 than the default value, which results in longer computing times for equally correct outputs (under GRH).

quaddisc(x)

Discriminant of the étale algebra \mathbb{Q}(\sqrt{x}), where x belongs to \mathbb{Q}^*. This is the same as coredisc(d) where d is the integer square-free part of x, so x = d f^2 with f belongs to \mathbb{Q}^* and d belongs to \mathbb{Z}. This returns 0 for x = 0, 1 for x square and the discriminant of the quadratic field \mathbb{Q}(\sqrt{x}) otherwise.

? quaddisc(7)
%1 = 28
? quaddisc(-7)
%2 = -7
quadgen(D)

Creates the quadratic number \omega = (a+\sqrt{D})/2 where a = 0 if D = 0 mod 4, a = 1 if D = 1 mod 4, so that (1,\omega) is an integral basis for the quadratic order of discriminant D. D must be an integer congruent to 0 or 1 modulo 4, which is not a square.

quadhilbert(D, precision=0)

Relative equation defining the Hilbert class field of the quadratic field of discriminant D.

If D < 0, uses complex multiplication (Schertz’s variant).

If D > 0 Stark units are used and (in rare cases) a vector of extensions may be returned whose compositum is the requested class field. See bnrstark for details.

quadpoly(D, v=None)

Creates the “canonical” quadratic polynomial (in the variable v) corresponding to the discriminant D, i.e. the minimal polynomial of quadgen(D). D must be an integer congruent to 0 or 1 modulo 4, which is not a square.

quadray(D, f, precision=0)

Relative equation for the ray class field of conductor f for the quadratic field of discriminant D using analytic methods. A bnf for x^2 - D is also accepted in place of D.

For D < 0, uses the \sigma function and Schertz’s method.

For D > 0, uses Stark’s conjecture, and a vector of relative equations may be returned. See bnrstark for more details.

quadregulator(x, precision=0)

Regulator of the quadratic field of positive discriminant x. Returns an error if x is not a discriminant (fundamental or not) or if x is a square. See also quadclassunit if x is large.

quadunit(D)

Fundamental unit of the real quadratic field \mathbb{Q}(\sqrt D) where D is the positive discriminant of the field. If D is not a fundamental discriminant, this probably gives the fundamental unit of the corresponding order. D must be an integer congruent to 0 or 1 modulo 4, which is not a square; the result is a quadratic number (see quadgen (in the PARI manual)).

random(N)

Returns a random element in various natural sets depending on the argument N.

  • t_INT: returns an integer uniformly distributed between 0 and N-1. Omitting the argument is equivalent to random(2^31).
  • t_REAL: returns a real number in [0,1[ with the same accuracy as N (whose mantissa has the same number of significant words).
  • t_INTMOD: returns a random intmod for the same modulus.
  • t_FFELT: returns a random element in the same finite field.
  • t_VEC of length 2, N = [a,b]: returns an integer uniformly distributed between a and b.
  • t_VEC generated by ellinit over a finite field k (coefficients are t_INTMOD s modulo a prime or t_FFELT s): returns a “random” k-rational affine point on the curve. More precisely if the curve has a single point (at infinity!) we return it; otherwise we return an affine point by drawing an abscissa uniformly at random until ellordinate succeeds. Note that this is definitely not a uniform distribution over E(k), but it should be good enough for applications.
  • t_POL return a random polynomial of degree at most the degree of N. The coefficients are drawn by applying random to the leading coefficient of N.
? random(10)
%1 = 9
? random(Mod(0,7))
%2 = Mod(1, 7)
? a = ffgen(ffinit(3,7), 'a); random(a)
%3 = a^6 + 2*a^5 + a^4 + a^3 + a^2 + 2*a
? E = ellinit([3,7]*Mod(1,109)); random(E)
%4 = [Mod(103, 109), Mod(10, 109)]
? E = ellinit([1,7]*a^0); random(E)
%5 = [a^6 + a^5 + 2*a^4 + 2*a^2, 2*a^6 + 2*a^4 + 2*a^3 + a^2 + 2*a]
? random(Mod(1,7)*x^4)
%6 = Mod(5, 7)*x^4 + Mod(6, 7)*x^3 + Mod(2, 7)*x^2 + Mod(2, 7)*x + Mod(5, 7)

These variants all depend on a single internal generator, and are independent from your operating system’s random number generators. A random seed may be obtained via getrand, and reset using setrand: from a given seed, and given sequence of random s, the exact same values will be generated. The same seed is used at each startup, reseed the generator yourself if this is a problem. Note that internal functions also call the random number generator; adding such a function call in the middle of your code will change the numbers produced.

Technical note. Up to version 2.4 included, the internal generator produced pseudo-random numbers by means of linear congruences, which were not well distributed in arithmetic progressions. We now use Brent’s XORGEN algorithm, based on Feedback Shift Registers, see http://wwwmaths.anu.edu.au/~brent/random.html. The generator has period 2^{4096}-1, passes the Crush battery of statistical tests of L’Ecuyer and Simard, but is not suitable for cryptographic purposes: one can reconstruct the state vector from a small sample of consecutive values, thus predicting the entire sequence.

randomprime(N)

Returns a strong pseudo prime (see ispseudoprime) in [2,N-1]. A t_VEC N = [a,b] is also allowed, with a <= b in which case a pseudo prime a <= p <= b is returned; if no prime exists in the interval, the function will run into an infinite loop. If the upper bound is less than 2^{64} the pseudo prime returned is a proven prime.

real(x)

Real part of x. In the case where x is a quadratic number, this is the coefficient of 1 in the “canonical” integral basis (1,\omega).

removeprimes(x)

Removes the primes listed in x from the prime number table. In particular removeprimes(addprimes()) empties the extra prime table. x can also be a single integer. List the current extra primes if x is omitted.

rnfalgtobasis(rnf, x)

Expresses x on the relative integral basis. Here, rnf is a relative number field extension L/K as output by rnfinit, and x an element of L in absolute form, i.e. expressed as a polynomial or polmod with polmod coefficients, not on the relative integral basis.

rnfbasis(bnf, M)

Let K the field represented by bnf, as output by bnfinit. M is a projective \mathbb{Z}_K-module of rank n (M\\otimes K is an n-dimensional K-vector space), given by a pseudo-basis of size n. The routine returns either a true \mathbb{Z}_K-basis of M (of size n) if it exists, or an n+1-element generating set of M if not.

It is allowed to use an irreducible polynomial P in K[X] instead of M, in which case, M is defined as the ring of integers of K[X]/(P), viewed as a \mathbb{Z}_K-module.

rnfbasistoalg(rnf, x)

Computes the representation of x as a polmod with polmods coefficients. Here, rnf is a relative number field extension L/K as output by rnfinit, and x an element of L expressed on the relative integral basis.

rnfcharpoly(nf, T, a, var=None)

Characteristic polynomial of a over nf, where a belongs to the algebra defined by T over nf, i.e. nf[X]/(T). Returns a polynomial in variable v (x by default).

? nf = nfinit(y^2+1);
? rnfcharpoly(nf, x^2+y*x+1, x+y)
%2 = x^2 + Mod(-y, y^2 + 1)*x + 1
rnfconductor(bnf, pol)

Given bnf as output by bnfinit, and pol a relative polynomial defining an Abelian extension, computes the class field theory conductor of this Abelian extension. The result is a 3-component vector [conductor,rayclgp,subgroup], where conductor is the conductor of the extension given as a 2-component row vector [f_0,f_ oo ], rayclgp is the full ray class group corresponding to the conductor given as a 3-component vector [h,cyc,gen] as usual for a group, and subgroup is a matrix in HNF defining the subgroup of the ray class group on the given generators gen.

rnfdedekind(nf, pol, pr=None, flag=0)

Given a number field K coded by nf and a monic polynomial P belongs to \mathbb{Z}_K[X], irreducible over K and thus defining a relative extension L of K, applies Dedekind’s criterion to the order \mathbb{Z}_K[X]/(P), at the prime ideal pr. It is possible to set pr to a vector of prime ideals (test maximality at all primes in the vector), or to omit altogether, in which case maximality at all primes is tested; in this situation flag is automatically set to 1.

The default historic behavior (flag is 0 or omitted and pr is a single prime ideal) is not so useful since rnfpseudobasis gives more information and is generally not that much slower. It returns a 3-component vector [max, basis, v]:

  • basis is a pseudo-basis of an enlarged order O produced by Dedekind’s criterion, containing the original order \mathbb{Z}_K[X]/(P) with index a power of pr. Possibly equal to the original order.
  • max is a flag equal to 1 if the enlarged order O could be proven to be pr-maximal and to 0 otherwise; it may still be maximal in the latter case if pr is ramified in L,
  • v is the valuation at pr of the order discriminant.

If flag is non-zero, on the other hand, we just return 1 if the order \mathbb{Z}_K[X]/(P) is pr-maximal (resp. maximal at all relevant primes, as described above), and 0 if not. This is much faster than the default, since the enlarged order is not computed.

? nf = nfinit(y^2-3); P = x^3 - 2*y;
? pr3 = idealprimedec(nf,3)[1];
? rnfdedekind(nf, P, pr3)
%2 = [1, [[1, 0, 0; 0, 1, 0; 0, 0, 1], [1, 1, 1]], 8]
? rnfdedekind(nf, P, pr3, 1)
%3 = 1

In this example, pr3 is the ramified ideal above 3, and the order generated by the cube roots of y is already pr3-maximal. The order-discriminant has valuation 8. On the other hand, the order is not maximal at the prime above 2:

? pr2 = idealprimedec(nf,2)[1];
? rnfdedekind(nf, P, pr2, 1)
%5 = 0
? rnfdedekind(nf, P, pr2)
%6 = [0, [[2, 0, 0; 0, 1, 0; 0, 0, 1], [[1, 0; 0, 1], [1, 0; 0, 1],
 [1, 1/2; 0, 1/2]]], 2]

The enlarged order is not proven to be pr2-maximal yet. In fact, it is; it is in fact the maximal order:

? B = rnfpseudobasis(nf, P)
%7 = [[1, 0, 0; 0, 1, 0; 0, 0, 1], [1, 1, [1, 1/2; 0, 1/2]],
 [162, 0; 0, 162], -1]
? idealval(nf,B[3], pr2)
%4 = 2

It is possible to use this routine with non-monic P = \sum_{i <= n} a_i X^i belongs to \mathbb{Z}_K[X] if flag = 1; in this case, we test maximality of Dedekind’s order generated by

1, a_n \alpha, a_n\alpha^2 + a_{n-1}\alpha,...,
a_n\alpha^{n-1} + a_{n-1}\alpha^{n-2} +...+ a_1\alpha.

The routine will fail if P is 0 on the projective line over the residue field \mathbb{Z}_K/pr (FIXME).

rnfdet(nf, M)

Given a pseudo-matrix M over the maximal order of nf, computes its determinant.

rnfdisc(nf, pol)

Given a number field nf as output by nfinit and a polynomial pol with coefficients in nf defining a relative extension L of nf, computes the relative discriminant of L. This is a two-element row vector [D,d], where D is the relative ideal discriminant and d is the relative discriminant considered as an element of nf^*/{nf^*}^2. The main variable of nf must be of lower priority than that of pol, see priority (in the PARI manual).

rnfeltabstorel(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an element of L expressed as a polynomial modulo the absolute equation :emphasis:`rnf.pol`, computes x as an element of the relative extension L/K as a polmod with polmod coefficients.

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
? L.pol
%2 = x^4 + 1
? rnfeltabstorel(L, Mod(x, L.pol))
%3 = Mod(x, x^2 + Mod(-y, y^2 + 1))
? rnfeltabstorel(L, Mod(2, L.pol))
%4 = 2
? rnfeltabstorel(L, Mod(x, x^2-y))
 *** at top-level: rnfeltabstorel(L,Mod
 *** ^--------------------
 *** rnfeltabstorel: inconsistent moduli in rnfeltabstorel: x^2-y != x^4+1
rnfeltdown(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an element of L expressed as a polynomial or polmod with polmod coefficients, computes x as an element of K as a polmod, assuming x is in K (otherwise a domain error occurs).

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
? L.pol
%2 = x^4 + 1
? rnfeltdown(L, Mod(x^2, L.pol))
%3 = Mod(y, y^2 + 1)
? rnfeltdown(L, Mod(y, x^2-y))
%4 = Mod(y, y^2 + 1)
? rnfeltdown(L, Mod(y,K.pol))
%5 = Mod(y, y^2 + 1)
? rnfeltdown(L, Mod(x, L.pol))
 *** at top-level: rnfeltdown(L,Mod(x,x
 *** ^--------------------
 *** rnfeltdown: domain error in rnfeltdown: element not in the base field
rnfeltnorm(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an element of L, returns the relative norm N_{L/K}(x) as an element of K.

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
? rnfeltnorm(L, Mod(x, L.pol))
%2 = Mod(x, x^2 + Mod(-y, y^2 + 1))
? rnfeltnorm(L, 2)
%3 = 4
? rnfeltnorm(L, Mod(x, x^2-y))
rnfeltreltoabs(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an element of L expressed as a polynomial or polmod with polmod coefficients, computes x as an element of the absolute extension L/\mathbb{Q} as a polynomial modulo the absolute equation :emphasis:`rnf.pol`.

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
? L.pol
%2 = x^4 + 1
? rnfeltreltoabs(L, Mod(x, L.pol))
%3 = Mod(x, x^4 + 1)
? rnfeltreltoabs(L, Mod(y, x^2-y))
%4 = Mod(x^2, x^4 + 1)
? rnfeltreltoabs(L, Mod(y,K.pol))
%5 = Mod(x^2, x^4 + 1)
rnfelttrace(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an element of L, returns the relative trace N_{L/K}(x) as an element of K.

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
? rnfelttrace(L, Mod(x, L.pol))
%2 = 0
? rnfelttrace(L, 2)
%3 = 4
? rnfelttrace(L, Mod(x, x^2-y))
rnfeltup(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an element of K, computes x as an element of the absolute extension L/\mathbb{Q} as a polynomial modulo the absolute equation :emphasis:`rnf.pol`.

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y);
? L.pol
%2 = x^4 + 1
? rnfeltup(L, Mod(y, K.pol))
%4 = Mod(x^2, x^4 + 1)
? rnfeltup(L, y)
%5 = Mod(x^2, x^4 + 1)
? rnfeltup(L, [1,2]~) \\ in terms of K.zk
%6 = Mod(2*x^2 + 1, x^4 + 1)
rnfequation(nf, pol, flag=0)

Given a number field nf as output by nfinit (or simply a polynomial) and a polynomial pol with coefficients in nf defining a relative extension L of nf, computes an absolute equation of L over \mathbb{Q}.

The main variable of nf must be of lower priority than that of pol (see priority (in the PARI manual)). Note that for efficiency, this does not check whether the relative equation is irreducible over nf, but only if it is squarefree. If it is reducible but squarefree, the result will be the absolute equation of the étale algebra defined by pol. If pol is not squarefree, raise an e_DOMAIN exception.

? rnfequation(y^2+1, x^2 - y)
%1 = x^4 + 1
? T = y^3-2; rnfequation(nfinit(T), (x^3-2)/(x-Mod(y,T)))
%2 = x^6 + 108 \\ Galois closure of Q(2^(1/3))

If flag is non-zero, outputs a 3-component row vector [z,a,k], where

  • z is the absolute equation of L over \mathbb{Q}, as in the default behavior,
  • a expresses as a t_POLMOD modulo z a root \alpha of the polynomial defining the base field nf,
  • k is a small integer such that \theta = \beta+k\alpha is a root of z, where \beta is a root of pol.
? T = y^3-2; pol = x^2 +x*y + y^2;
? [z,a,k] = rnfequation(T, pol, 1);
? z
%4 = x^6 + 108
? subst(T, y, a)
%5 = 0
? alpha= Mod(y, T);
? beta = Mod(x*Mod(1,T), pol);
? subst(z, x, beta + k*alpha)
%8 = 0
rnfhnfbasis(bnf, x)

Given bnf as output by bnfinit, and either a polynomial x with coefficients in bnf defining a relative extension L of bnf, or a pseudo-basis x of such an extension, gives either a true bnf-basis of L in upper triangular Hermite normal form, if it exists, and returns 0 otherwise.

rnfidealabstorel(rnf, x)

Let rnf be a relative number field extension L/K as output by rnfinit and x be an ideal of the absolute extension L/\mathbb{Q} given by a \mathbb{Z}-basis of elements of L. Returns the relative pseudo-matrix in HNF giving the ideal x considered as an ideal of the relative extension L/K, i.e. as a \mathbb{Z}_K-module.

The reason why the input does not use the customary HNF in terms of a fixed \mathbb{Z}-basis for \mathbb{Z}_L is precisely that no such basis has been explicitly specified. On the other hand, if you already computed an (absolute) nf structure Labs associated to L, and m is in HNF, defining an (absolute) ideal with respect to the \mathbb{Z}-basis Labs.zk, then Labs.zk * m is a suitable \mathbb{Z}-basis for the ideal, and

rnfidealabstorel(rnf, Labs.zk * m)

converts m to a relative ideal.

? K = nfinit(y^2+1); L = rnfinit(K, x^2-y); Labs = nfinit(L);
? m = idealhnf(Labs, 17, x^3+2);
? B = rnfidealabstorel(L, Labs.zk * m)
%3 = [[1, 8; 0, 1], [[17, 4; 0, 1], 1]] \\ pseudo-basis for m as Z_K-module
? A = rnfidealreltoabs(L, B)
%4 = [17, x^2 + 4, x + 8, x^3 + 8*x^2] \\ Z-basis for m in Q[x]/(L.pol)
? mathnf(matalgtobasis(Labs, A))
%5 =
[17 8 4 2]

[ 0 1 0 0]

[ 0 0 1 0]

[ 0 0 0 1]
? % == m
%6 = 1
rnfidealdown(rnf, x)

Let rnf be a relative number field extension L/K as output by rnfinit, and x an ideal of L, given either in relative form or by a \mathbb{Z}-basis of elements of L (see rnfidealabstorel (in the PARI manual)). This function returns the ideal of K below x, i.e. the intersection of x with K.

rnfidealhnf(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being a relative ideal (which can be, as in the absolute case, of many different types, including of course elements), computes the HNF pseudo-matrix associated to x, viewed as a \mathbb{Z}_K-module.

rnfidealmul(rnf, x, y)

rnf being a relative number field extension L/K as output by rnfinit and x and y being ideals of the relative extension L/K given by pseudo-matrices, outputs the ideal product, again as a relative ideal.

rnfidealnormabs(rnf, x)

Let rnf be a relative number field extension L/K as output by rnfinit and let x be a relative ideal (which can be, as in the absolute case, of many different types, including of course elements). This function computes the norm of the x considered as an ideal of the absolute extension L/\mathbb{Q}. This is identical to

idealnorm(rnf, rnfidealnormrel(rnf,x))

but faster.

rnfidealnormrel(rnf, x)

Let rnf be a relative number field extension L/K as output by rnfinit and let x be a relative ideal (which can be, as in the absolute case, of many different types, including of course elements). This function computes the relative norm of x as an ideal of K in HNF.

rnfidealreltoabs(rnf, x)

Let rnf be a relative number field extension L/K as output by rnfinit and let x be a relative ideal, given as a \mathbb{Z}_K-module by a pseudo matrix [A,I]. This function returns the ideal x as an absolute ideal of L/\mathbb{Q} in the form of a \mathbb{Z}-basis, given by a vector of polynomials (modulo rnf.pol).

The reason why we do not return the customary HNF in terms of a fixed \mathbb{Z}-basis for \mathbb{Z}_L is precisely that no such basis has been explicitly specified. On the other hand, if you already computed an (absolute) nf structure Labs associated to L, then

xabs = rnfidealreltoabs(L, x);
xLabs = mathnf(matalgtobasis(Labs, xabs));

computes a traditional HNF xLabs for x in terms of the fixed \mathbb{Z}-basis Labs.zk.

rnfidealtwoelt(rnf, x)

rnf being a relative number field extension L/K as output by rnfinit and x being an ideal of the relative extension L/K given by a pseudo-matrix, gives a vector of two generators of x over \mathbb{Z}_L expressed as polmods with polmod coefficients.

rnfidealup(rnf, x)

Let rnf be a relative number field extension L/K as output by rnfinit and let x be an ideal of K. This function returns the ideal x\mathbb{Z}_L as an absolute ideal of L/\mathbb{Q}, in the form of a \mathbb{Z}-basis, given by a vector of polynomials (modulo rnf.pol).

The reason why we do not return the customary HNF in terms of a fixed \mathbb{Z}-basis for \mathbb{Z}_L is precisely that no such basis has been explicitly specified. On the other hand, if you already computed an (absolute) nf structure Labs associated to L, then

xabs = rnfidealup(L, x);
xLabs = mathnf(matalgtobasis(Labs, xabs));

computes a traditional HNF xLabs for x in terms of the fixed \mathbb{Z}-basis Labs.zk.

rnfinit(nf, pol)

nf being a number field in nfinit format considered as base field, and pol a polynomial defining a relative extension over nf, this computes data to work in the relative extension. The main variable of pol must be of higher priority (see priority (in the PARI manual)) than that of nf, and the coefficients of pol must be in nf.

The result is a row vector, whose components are technical. In the following description, we let K be the base field defined by nf and L/K the large field associated to the rnf. Furthermore, we let m = [K:\mathbb{Q}] the degree of the base field, n = [L:K] the relative degree, r_1 and r_2 the number of real and complex places of K. Access to this information via member functions is preferred since the specific data organization specified below will change in the future.

Note that a subsequent nfinit(rnf) will explicitly add an nf structure associated to L to rnf (and return it as well). This is likely to be very expensive if the absolute degree mn is large, but fixes an integer basis for \mathbb{Z}_L as a \mathbb{Z}-module and allows to input and output elements of L in absolute form: as t_COL for elements, as t_MAT in HNF for ideals, as prid for prime ideals. Without such a call, elements of L are represented as t_POLMOD, etc.

rnf[1]`(:literal:`rnf.pol) contains the relative polynomial pol.

rnf[2] contains the integer basis [A,d] of K, as (integral) elements of L/\mathbb{Q}. More precisely, A is a vector of polynomial with integer coefficients, d is a denominator, and the integer basis is given by A/d.

rnf[3] (rnf.disc) is a two-component row vector [d(L/K),s] where d(L/K) is the relative ideal discriminant of L/K and s is the discriminant of L/K viewed as an element of K^*/(K^*)^2, in other words it is the output of rnfdisc.

rnf[4]`(:literal:`rnf.index) is the ideal index f, i.e. such that d(pol)\mathbb{Z}_K = f^2d(L/K).

rnf[5] is currently unused.

rnf[6] is currently unused.

rnf[7] (rnf.zk) is the pseudo-basis (A,I) for the maximal order \mathbb{Z}_L as a \mathbb{Z}_K-module: A is the relative integral pseudo basis expressed as polynomials (in the variable of pol) with polmod coefficients in nf, and the second component I is the ideal list of the pseudobasis in HNF.

rnf[8] is the inverse matrix of the integral basis matrix, with coefficients polmods in nf.

rnf[9] is currently unused.

rnf[10] (rnf.nf) is nf.

rnf[11] is an extension of rnfequation(K, pol, 1). Namely, a vector [P, a, k, K.pol, pol] describing the absolute extension L/\mathbb{Q}: P is an absolute equation, more conveniently obtained as rnf.polabs; a expresses the generator \alpha = y mod K.pol of the number field K as an element of L, i.e. a polynomial modulo the absolute equation P;

k is a small integer such that, if \beta is an abstract root of pol and \alpha the generator of K given above, then P(\beta + k\alpha) = 0.

Caveat. Be careful if k != 0 when dealing simultaneously with absolute and relative quantities since L = \mathbb{Q}(\beta + k\alpha) = 
K(\alpha), and the generator chosen for the absolute extension is not the same as for the relative one. If this happens, one can of course go on working, but we advise to change the relative polynomial so that its root becomes \beta + k \alpha. Typical GP instructions would be

[P,a,k] = rnfequation(K, pol, 1);
if (k, pol = subst(pol, x, x - k*Mod(y, K.pol)));
L = rnfinit(K, pol);

rnf[12] is by default unused and set equal to 0. This field is used to store further information about the field as it becomes available (which is rarely needed, hence would be too expensive to compute during the initial rnfinit call).

rnfisabelian(nf, T)

T being a relative polynomial with coefficients in nf, return 1 if it defines an abelian extension, and 0 otherwise.

? K = nfinit(y^2 + 23);
? rnfisabelian(K, x^3 - 3*x - y)
%2 = 1
rnfisfree(bnf, x)

Given bnf as output by bnfinit, and either a polynomial x with coefficients in bnf defining a relative extension L of bnf, or a pseudo-basis x of such an extension, returns true (1) if L/bnf is free, false (0) if not.

rnfisnorm(T, a, flag=0)

Similar to bnfisnorm but in the relative case. T is as output by rnfisnorminit applied to the extension L/K. This tries to decide whether the element a in K is the norm of some x in the extension L/K.

The output is a vector [x,q], where a = \mathrm{Norm}(x)*q. The algorithm looks for a solution x which is an S-integer, with S a list of places of K containing at least the ramified primes, the generators of the class group of L, as well as those primes dividing a. If L/K is Galois, then this is enough; otherwise, flag is used to add more primes to S: all the places above the primes p <= flag (resp. p\|flag) if flag > 0 (resp. flag < 0).

The answer is guaranteed (i.e. a is a norm iff q = 1) if the field is Galois, or, under GRH, if S contains all primes less than 12\log^2\|\mathrm{disc}(M)\|, where M is the normal closure of L/K.

If rnfisnorminit has determined (or was told) that L/K is Galois, and flag != 0, a Warning is issued (so that you can set flag = 1 to check whether L/K is known to be Galois, according to T). Example:

bnf = bnfinit(y^3 + y^2 - 2*y - 1);
p = x^2 + Mod(y^2 + 2*y + 1, bnf.pol);
T = rnfisnorminit(bnf, p);
rnfisnorm(T, 17)

checks whether 17 is a norm in the Galois extension \mathbb{Q}(\beta) /
\mathbb{Q}(\alpha), where \alpha^3 + \alpha^2 - 2\alpha - 1 = 0 and \beta^2 +
\alpha^2 + 2\alpha + 1 = 0 (it is).

rnfisnorminit(pol, polrel, flag=2)

Let K be defined by a root of pol, and L/K the extension defined by the polynomial polrel. As usual, pol can in fact be an nf, or bnf, etc; if pol has degree 1 (the base field is \mathbb{Q}), polrel is also allowed to be an nf, etc. Computes technical data needed by rnfisnorm to solve norm equations Nx = a, for x in L, and a in K.

If flag = 0, do not care whether L/K is Galois or not.

If flag = 1, L/K is assumed to be Galois (unchecked), which speeds up rnfisnorm.

If flag = 2, let the routine determine whether L/K is Galois.

rnfkummer(bnr, subgp=None, d=0, precision=0)

bnr being as output by bnrinit, finds a relative equation for the class field corresponding to the module in bnr and the given congruence subgroup (the full ray class field if subgp is omitted). If d is positive, outputs the list of all relative equations of degree d contained in the ray class field defined by bnr, with the same conductor as (bnr, subgp).

Warning. This routine only works for subgroups of prime index. It uses Kummer theory, adjoining necessary roots of unity (it needs to compute a tough bnfinit here), and finds a generator via Hecke’s characterization of ramification in Kummer extensions of prime degree. If your extension does not have prime degree, for the time being, you have to split it by hand as a tower / compositum of such extensions.

rnflllgram(nf, pol, order, precision=0)

Given a polynomial pol with coefficients in nf defining a relative extension L and a suborder order of L (of maximal rank), as output by rnfpseudobasis(nf,pol) or similar, gives [[neworder],U], where neworder is a reduced order and U is the unimodular transformation matrix.

rnfnormgroup(bnr, pol)

bnr being a big ray class field as output by bnrinit and pol a relative polynomial defining an Abelian extension, computes the norm group (alias Artin or Takagi group) corresponding to the Abelian extension of bnf =bnr.bnf defined by pol, where the module corresponding to bnr is assumed to be a multiple of the conductor (i.e. pol defines a subextension of bnr). The result is the HNF defining the norm group on the given generators of bnr.gen. Note that neither the fact that pol defines an Abelian extension nor the fact that the module is a multiple of the conductor is checked. The result is undefined if the assumption is not correct, but the function will return the empty matrix [;] if it detects a problem; it may also not detect the problem and return a wrong result.

rnfpolred(nf, pol, precision=0)

THIS FUNCTION IS OBSOLETE: use rnfpolredbest instead. Relative version of polred. Given a monic polynomial pol with coefficients in nf, finds a list of relative polynomials defining some subfields, hopefully simpler and containing the original field. In the present version 2.8.0, this is slower and less efficient than rnfpolredbest.

Remark. this function is based on an incomplete reduction theory of lattices over number fields, implemented by rnflllgram, which deserves to be improved.

rnfpolredabs(nf, pol, flag=0)

THIS FUNCTION IS OBSOLETE: use rnfpolredbest instead. Relative version of polredabs. Given a monic polynomial pol with coefficients in nf, finds a simpler relative polynomial defining the same field. The binary digits of flag mean

The binary digits of flag correspond to 1: add information to convert elements to the new representation, 2: absolute polynomial, instead of relative, 16: possibly use a suborder of the maximal order. More precisely:

0: default, return P

1: returns [P,a] where P is the default output and a, a t_POLMOD modulo P, is a root of pol.

2: returns Pabs, an absolute, instead of a relative, polynomial. Same as but faster than

rnfequation(nf, rnfpolredabs(nf,pol))

3: returns [Pabs,a,b], where Pabs is an absolute polynomial as above, a, b are t_POLMOD modulo Pabs, roots of nf.pol and pol respectively.

16: possibly use a suborder of the maximal order. This is slower than the default when the relative discriminant is smooth, and much faster otherwise. See polredabs (in the PARI manual).

Warning. In the present implementation, rnfpolredabs produces smaller polynomials than rnfpolred and is usually faster, but its complexity is still exponential in the absolute degree. The function rnfpolredbest runs in polynomial time, and tends to return polynomials with smaller discriminants.

rnfpolredbest(nf, pol, flag=0)

Relative version of polredbest. Given a monic polynomial pol with coefficients in nf, finds a simpler relative polynomial P defining the same field. As opposed to rnfpolredabs this function does not return a smallest (canonical) polynomial with respect to some measure, but it does run in polynomial time.

The binary digits of flag correspond to 1: add information to convert elements to the new representation, 2: absolute polynomial, instead of relative. More precisely:

0: default, return P

1: returns [P,a] where P is the default output and a, a t_POLMOD modulo P, is a root of pol.

2: returns Pabs, an absolute, instead of a relative, polynomial. Same as but faster than

rnfequation(nf, rnfpolredbest(nf,pol))

3: returns [Pabs,a,b], where Pabs is an absolute polynomial as above, a, b are t_POLMOD modulo Pabs, roots of nf.pol and pol respectively.

? K = nfinit(y^3-2); pol = x^2 +x*y + y^2;
? [P, a] = rnfpolredbest(K,pol,1);
? P
%3 = x^2 - x + Mod(y - 1, y^3 - 2)
? a
%4 = Mod(Mod(2*y^2+3*y+4,y^3-2)*x + Mod(-y^2-2*y-2,y^3-2),
 x^2 - x + Mod(y-1,y^3-2))
? subst(K.pol,y,a)
%5 = 0
? [Pabs, a, b] = rnfpolredbest(K,pol,3);
? Pabs
%7 = x^6 - 3*x^5 + 5*x^3 - 3*x + 1
? a
%8 = Mod(-x^2+x+1, x^6-3*x^5+5*x^3-3*x+1)
? b
%9 = Mod(2*x^5-5*x^4-3*x^3+10*x^2+5*x-5, x^6-3*x^5+5*x^3-3*x+1)
? subst(K.pol,y,a)
%10 = 0
? substvec(pol,[x,y],[a,b])
%11 = 0
rnfpseudobasis(nf, pol)

Given a number field nf as output by nfinit and a polynomial pol with coefficients in nf defining a relative extension L of nf, computes a pseudo-basis (A,I) for the maximal order \mathbb{Z}_L viewed as a \mathbb{Z}_K-module, and the relative discriminant of L. This is output as a four-element row vector [A,I,D,d], where D is the relative ideal discriminant and d is the relative discriminant considered as an element of nf^*/{nf^*}^2.

rnfsteinitz(nf, x)

Given a number field nf as output by nfinit and either a polynomial x with coefficients in nf defining a relative extension L of nf, or a pseudo-basis x of such an extension as output for example by rnfpseudobasis, computes another pseudo-basis (A,I) (not in HNF in general) such that all the ideals of I except perhaps the last one are equal to the ring of integers of nf, and outputs the four-component row vector [A,I,D,d] as in rnfpseudobasis. The name of this function comes from the fact that the ideal class of the last ideal of I, which is well defined, is the Steinitz class of the \mathbb{Z}_K-module \mathbb{Z}_L (its image in SK_0(\mathbb{Z}_K)).

select(f, A, flag=0)

We first describe the default behavior, when flag is 0 or omitted. Given a vector or list A and a t_CLOSURE f, select returns the elements x of A such that f(x) is non-zero. In other words, f is seen as a selection function returning a boolean value.

? select(x->isprime(x), vector(50,i,i^2+1))
%1 = [2, 5, 17, 37, 101, 197, 257, 401, 577, 677, 1297, 1601]
? select(x->(x<100), %)
%2 = [2, 5, 17, 37]

returns the primes of the form i^2+1 for some i <= 50, then the elements less than 100 in the preceding result. The select function also applies to a matrix A, seen as a vector of columns, i.e. it selects columns instead of entries, and returns the matrix whose columns are the selected ones.

Remark. For v a t_VEC, t_COL, t_LIST or t_MAT, the alternative set-notations

[g(x) | x <- v, f(x)]
[x | x <- v, f(x)]
[g(x) | x <- v]

are available as shortcuts for

apply(g, select(f, Vec(v)))
select(f, Vec(v))
apply(g, Vec(v))

respectively:

? [ x | x <- vector(50,i,i^2+1), isprime(x) ]
%1 = [2, 5, 17, 37, 101, 197, 257, 401, 577, 677, 1297, 1601]

If flag = 1, this function returns instead the indices of the selected elements, and not the elements themselves (indirect selection):

? V = vector(50,i,i^2+1);
? select(x->isprime(x), V, 1)
%2 = Vecsmall([1, 2, 4, 6, 10, 14, 16, 20, 24, 26, 36, 40])
? vecextract(V, %)
%3 = [2, 5, 17, 37, 101, 197, 257, 401, 577, 677, 1297, 1601]

The following function lists the elements in (\mathbb{Z}/N\mathbb{Z})^*:

? invertibles(N) = select(x->gcd(x,N) == 1, [1..N])

Finally

? select(x->x, M)

selects the non-0 entries in M. If the latter is a t_MAT, we extract the matrix of non-0 columns. Note that removing entries instead of selecting them just involves replacing the selection function f with its negation:

? select(x->!isprime(x), vector(50,i,i^2+1))
seralgdep(s, p, r)

finds a linear relation between powers (1,s,
..., s^p) of the series s, with polynomial coefficients of degree <= r. In case no relation is found, return 0.

? s = 1 + 10*y - 46*y^2 + 460*y^3 - 5658*y^4 + 77740*y^5 + O(y^6);
? seralgdep(s, 2, 2)
%2 = -x^2 + (8*y^2 + 20*y + 1)
? subst(%, x, s)
%3 = O(y^6)
? seralgdep(s, 1, 3)
%4 = (-77*y^2 - 20*y - 1)*x + (310*y^3 + 231*y^2 + 30*y + 1)
? seralgdep(s, 1, 2)
%5 = 0

The series main variable must not be x, so as to be able to express the result as a polynomial in x.

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.

serlaplace(x)

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

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)
setbinop(f, X, Y=None)

The set whose elements are the f(x,y), where x,y run through X,Y. respectively. If Y is omitted, assume that X = Y and that f is symmetric: f(x,y) = f(y,x) for all x,y in X.

? X = [1,2,3]; Y = [2,3,4];
? setbinop((x,y)->x+y, X,Y) \\ set X + Y
%2 = [3, 4, 5, 6, 7]
? setbinop((x,y)->x-y, X,Y) \\ set X - Y
%3 = [-3, -2, -1, 0, 1]
? setbinop((x,y)->x+y, X) \\ set 2X = X + X
%2 = [2, 3, 4, 5, 6]
setintersect(x, y)

Intersection of the two sets x and y (see setisset). If x or y is not a set, the result is undefined.

setisset(x)

Returns true (1) if x is a set, false (0) if not. In PARI, a set is a row vector whose entries are strictly increasing with respect to a (somewhat arbitrary) universal comparison function. To convert any object into a set (this is most useful for vectors, of course), use the function Set.

? a = [3, 1, 1, 2];
? setisset(a)
%2 = 0
? Set(a)
%3 = [1, 2, 3]
setminus(x, y)

Difference of the two sets x and y (see setisset), i.e. set of elements of x which do not belong to y. If x or y is not a set, the result is undefined.

setrand(n)

Reseeds the random number generator using the seed n. No value is returned. The seed is either a technical array output by getrand, or a small positive integer, used to generate deterministically a suitable state array. For instance, running a randomized computation starting by setrand(1) twice will generate the exact same output.

setsearch(S, x, flag=0)

Determines whether x belongs to the set S (see setisset).

We first describe the default behaviour, when flag is zero or omitted. If x belongs to the set S, returns the index j such that S[j] = x, otherwise returns 0.

? T = [7,2,3,5]; S = Set(T);
? setsearch(S, 2)
%2 = 1
? setsearch(S, 4) \\ not found
%3 = 0
? setsearch(T, 7) \\ search in a randomly sorted vector
%4 = 0 \\ WRONG !

If S is not a set, we also allow sorted lists with respect to the cmp sorting function, without repeated entries, as per listsort(L,1); otherwise the result is undefined.

? L = List([1,4,2,3,2]); setsearch(L, 4)
%1 = 0 \\ WRONG !
? listsort(L, 1); L \\ sort L first
%2 = List([1, 2, 3, 4])
? setsearch(L, 4)
%3 = 4 \\ now correct

If flag is non-zero, this function returns the index j where x should be inserted, and 0 if it already belongs to S. This is meant to be used for dynamically growing (sorted) lists, in conjunction with listinsert.

? L = List([1,5,2,3,2]); listsort(L,1); L
%1 = List([1,2,3,5])
? j = setsearch(L, 4, 1) \\ 4 should have been inserted at index j
%2 = 4
? listinsert(L, 4, j); L
%3 = List([1, 2, 3, 4, 5])
setunion(x, y)

Union of the two sets x and y (see setisset). If x or y is not a set, the result is undefined.

shift(x, n)

Shifts x componentwise left by n bits if n >= 0 and right by \|n\| bits if n < 0. May be abbreviated as x :literal:` << ` n or x :literal:` >> ` (-n). A left shift by n corresponds to multiplication by 2^n. A right shift of an integer x by \|n\| corresponds to a Euclidean division of x by 2^{\|n\|} with a remainder of the same sign as x, hence is not the same (in general) as x \\ 2^n.

shiftmul(x, n)

Multiplies x by 2^n. The difference with shift is that when n < 0, ordinary division takes place, hence for example if x is an integer the result may be a fraction, while for shifts Euclidean division takes place when n < 0 hence if x is an integer the result is still an integer.

sigma(x, k=1)

Sum of the k-th powers of the positive divisors of \|x\|. x and k must be of type integer.

sign(x)

sign (0, 1 or -1) of x, which must be of type integer, real or fraction; t_QUAD with positive discriminants and t_INFINITY are also supported.

simplify(x)

This function simplifies x as much as it can. Specifically, a complex or quadratic number whose imaginary part is the integer 0 (i.e. not Mod(0,2) or 0.E-28) is converted to its real part, and a polynomial of degree 0 is converted to its constant term. Simplifications occur recursively.

This function is especially useful before using arithmetic functions, which expect integer arguments:

? x = 2 + y - y
%1 = 2
? isprime(x)
 *** at top-level: isprime(x)
 *** ^----------
 *** isprime: not an integer argument in an arithmetic function
? type(x)
%2 = "t_POL"
? type(simplify(x))
%3 = "t_INT"

Note that GP results are simplified as above before they are stored in the history. (Unless you disable automatic simplification with \y, that is.) In particular

? type(%1)
%4 = "t_INT"
sin(x, precision=0)

Sine of x.

sinc(x, precision=0)

Cardinal sine of x, i.e. \sin(x)/x if x != 0, 1 otherwise. Note that this function also allows to compute

(1-\cos(x)) / x^2 = sinc(x/2)^2 / 2

accurately near x = 0.

sinh(x, precision=0)

Hyperbolic sine of x.

sizebyte(x)

Outputs the total number of bytes occupied by the tree representing the PARI object x.

sizedigit(x)

Outputs a quick upper bound for the number of decimal digits of (the components of) x, off by at most 1. More precisely, for a positive integer x, it computes (approximately) the ceiling of

floor(1 + \log_2 x) \log_{10}2,

This function is DEPRECATED, essentially meaningless, and provided for backwards compatibility only. Don’t use it!

To count the number of decimal digits of a positive integer x, use #digits(x). To estimate (recursively) the size of x, use normlp(x).

sqr(x)

Square of x. This operation is not completely straightforward, i.e. identical to x * x, since it can usually be computed more efficiently (roughly one-half of the elementary multiplications can be saved). Also, squaring a 2-adic number increases its precision. For example,

? (1 + O(2^4))^2
%1 = 1 + O(2^5)
? (1 + O(2^4)) * (1 + O(2^4))
%2 = 1 + O(2^4)

Note that this function is also called whenever one multiplies two objects which are known to be identical, e.g. they are the value of the same variable, or we are computing a power.

? x = (1 + O(2^4)); x * x
%3 = 1 + O(2^5)
? (1 + O(2^4))^4
%4 = 1 + O(2^6)

(note the difference between %2 and %3 above).

sqrt(x, precision=0)

Principal branch of the square root of x, defined as \sqrt{x} = 
\exp(\log x / 2). In particular, we have {Arg}({sqrt}(x)) belongs to ]-\Pi/2, \Pi/2], and if x belongs to \mathbb{R} and x < 0, then the result is complex with positive imaginary part.

Intmod a prime p, t_PADIC and t_FFELT are allowed as arguments. In the first 2 cases (t_INTMOD, t_PADIC), the square root (if it exists) which is returned is the one whose first p-adic digit is in the interval [0,p/2]. For other arguments, the result is undefined.

sqrtint(x)

Returns the integer square root of x, i.e. the largest integer y such that y^2 <= x, where x a non-negative integer.

? N = 120938191237; sqrtint(N)
%1 = 347761
? sqrt(N)
%2 = 347761.68741970412747602130964414095216
sqrtnint(x, n)

Returns the integer n-th root of x, i.e. the largest integer y such that y^n <= x, where x is a non-negative integer.

? N = 120938191237; sqrtnint(N, 5)
%1 = 164
? N^(1/5)
%2 = 164.63140849829660842958614676939677391

The special case n = 2 is sqrtint

subgrouplist(bnr, bound=None, flag=0)

bnr being as output by bnrinit or a list of cyclic components of a finite Abelian group G, outputs the list of subgroups of G. Subgroups are given as HNF left divisors of the SNF matrix corresponding to G.

If flag = 0 (default) and bnr is as output by bnrinit, gives only the subgroups whose modulus is the conductor. Otherwise, the modulus is not taken into account.

If bound is present, and is a positive integer, restrict the output to subgroups of index less than bound. If bound is a vector containing a single positive integer B, then only subgroups of index exactly equal to B are computed. For instance

? subgrouplist([6,2])
%1 = [[6, 0; 0, 2], [2, 0; 0, 2], [6, 3; 0, 1], [2, 1; 0, 1], [3, 0; 0, 2],
[1, 0; 0, 2], [6, 0; 0, 1], [2, 0; 0, 1], [3, 0; 0, 1], [1, 0; 0, 1]]
? subgrouplist([6,2],3) \\ index less than 3
%2 = [[2, 1; 0, 1], [1, 0; 0, 2], [2, 0; 0, 1], [3, 0; 0, 1], [1, 0; 0, 1]]
? subgrouplist([6,2],[3]) \\ index 3
%3 = [[3, 0; 0, 1]]
? bnr = bnrinit(bnfinit(x), [120,[1]], 1);
? L = subgrouplist(bnr, [8]);

In the last example, L corresponds to the 24 subfields of \mathbb{Q}(\zeta_{120}), of degree 8 and conductor 120 oo (by setting flag, we see there are a total of 43 subgroups of degree 8).

? vector(#L, i, galoissubcyclo(bnr, L[i]))

will produce their equations. (For a general base field, you would have to rely on bnrstark, or rnfkummer.)

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.

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)
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]
sumdedekind(h, k)

Returns the Dedekind sum associated to the integers h and k, corresponding to a fast implementation of

s(h,k) = sum(n = 1, k-1, (n/k)*(frac(h*n/k) - 1/2))
sumdigits(n, B=None)

Sum of digits in the integer n, when written in base B > 1.

? sumdigits(123456789)
%1 = 45
? sumdigits(123456789, 2)
%1 = 16

Note that the sum of bits in n is also returned by hammingweight. This function is much faster than vecsum(digits(n,B)) when B is 10 or a power of 2, and only slightly faster in other cases.

sumformal(f, v=None)

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
sumnuminit(asymp, precision=0)

Initialize tables for Euler–MacLaurin delta summation of a series with positive terms. If given, asymp is of the form [+oo, \alpha], as in intnum and indicates the decrease rate at infinity of functions to be summed. A positive \alpha > 0 encodes an exponential decrease of type \exp(-\alpha n) and a negative -2 < \alpha < -1 encodes a slow polynomial decrease of type n^{\alpha}.

? \p200
? sumnum(n=1, n^-2);
time = 200 ms.
? tab = sumnuminit();
time = 188 ms.
? sumnum(n=1, n^-2, tab); \\ faster
time = 8 ms.

? tab = sumnuminit([+oo, log(2)]); \\ decrease like 2^-n
time = 200 ms.
? sumnum(n=1, 2^-n, tab)
time = 44 ms.

? tab = sumnuminit([+oo, -4/3]); \\ decrease like n^(-4/3)
time = 200 ms.
? sumnum(n=1, n^(-4/3), tab);
time = 221 ms.
tan(x, precision=0)

Tangent of x.

tanh(x, precision=0)

Hyperbolic tangent of x.

taylor(x, t, serprec=-1)

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.
teichmuller(x)

Teichmüller character of the p-adic number x, i.e. the unique (p-1)-th root of unity congruent to x / p^{v_p(x)} modulo p.

theta(q, z, precision=0)

Jacobi sine theta-function

\theta_1(z, q) = 2q^{1/4} \sum_{n >= 0} (-1)^n q^{n(n+1)} \sin((2n+1)z).

thetanullk(q, k, precision=0)

k-th derivative at z = 0 of theta(q,z).

thue(tnf, a, sol=None)

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 \mathrm{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 is 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 favorable 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.

thueinit(P, flag=0, precision=0)

Initializes the tnf corresponding to P, a non-constant 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. Accordingly, P must either have at least two distinct irreducible factors over \mathbb{Q}, or have one irreducible factor T with degree > 2 or two conjugate complex roots: under these (necessary and sufficient) conditions, the equation has finitely many integer solutions.

? S = thueinit(t^2+1);
? thue(S, 5)
%2 = [[-2, -1], [-2, 1], [-1, -2], [-1, 2], [1, -2], [1, 2], [2, -1], [2, 1]]
? S = thueinit(t+1);
 *** at top-level: thueinit(t+1)
 *** ^-------------
 *** thueinit: domain error in thueinit: P = t + 1

The hardest case is when \deg P > 2 and P is irreducible with at least one real root. The routine then uses Bilu-Hanrot’s algorithm.

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 unconditional.

Note. The general philosophy is to disprove the existence of large solutions then to enumerate bounded solutions naively. The implementation will overflow when there exist huge solutions and the equation has degree > 2 (the quadratic imaginary case is special, since we can use bnfisintnorm):

? thue(t^3+2, 10^30)
 *** at top-level: L=thue(t^3+2,10^30)
 *** ^-----------------
 *** thue: overflow in thue (SmallSols): y <= 80665203789619036028928.
? thue(x^2+2, 10^30) \\ quadratic case much easier
%1 = [[-1000000000000000, 0], [1000000000000000, 0]]

Note. It is sometimes possible to circumvent the above, and in any case obtain an important speed-up, if you can write P = Q(x^d) for some d > 
1 and Q still satisfying the thueinit hypotheses. You can then solve the equation associated to Q then eliminate all solutions (x,y) such that either x or y is not a d-th power.

? thue(x^4+1, 10^40); \\ stopped after 10 hours
? filter(L,d) =
 my(x,y); [[x,y] | v<-L, ispower(v[1],d,&x)&&ispower(v[2],d,&y)];
? L = thue(x^2+1, 10^40);
? filter(L, 2)
%4 = [[0, 10000000000], [10000000000, 0]]

The last 2 commands use less than 20ms.

trace(x)

This applies to quite general x. If x is not a matrix, it is equal to the sum of x and its conjugate, except for polmods where it is the trace as an algebraic number.

For x a square matrix, it is the ordinary trace. If x is a non-square matrix (but not a vector), an error occurs.

type(x)

This is useful only under gp. Returns the internal type name of the PARI object x as a string. Check out existing type names with the metacommand \t. For example type(1) will return “t_INT”.

valuation(x, p)

Computes the highest exponent of p dividing x. If p is of type integer, x must be an integer, an intmod whose modulus is divisible by p, a fraction, a q-adic number with q = p, or a polynomial or power series in which case the valuation is the minimum of the valuation of the coefficients.

If p is of type polynomial, x must be of type polynomial or rational function, and also a power series if x is a monomial. Finally, the valuation of a vector, complex or quadratic number is the minimum of the component valuations.

If x = 0, the result is +oo if x is an exact object. If x is a p-adic numbers or power series, the result is the exponent of the zero. Any other type combinations gives an error.

variable(x)

Gives the main variable of the object x (the variable with the highest priority used in x), and p if x is a p-adic number. Return 0 if x has no variable associated to it.

? variable(x^2 + y)
%1 = x
? variable(1 + O(5^2))
%2 = 5
? variable([x,y,z,t])
%3 = x
? variable(1)
%4 = 0

The construction

if (!variable(x),...)

can be used to test whether a variable is attached to x.

If x is omitted, returns the list of user variables known to the interpreter, by order of decreasing priority. (Highest priority is initially x, which come first until varhigher is used.) If varhigher or varlower are used, it is quite possible to end up with different variables (with different priorities) printed in the same way: they will then appear multiple times in the output:

? varhigher("y");
? varlower("y");
? variable()
%4 = [y, x, y]

Using v = variable() then v[1], v[2], etc. allows to recover and use existing variables.

variables(x)

Returns the list of all variables occuring in object x (all user variables known to the interpreter if x is omitted), sorted by decreasing priority.

? variables([x^2 + y*z + O(t), a+x])
%1 = [x, y, z, t, a]

The construction

if (!variables(x),...)

can be used to test whether a variable is attached to x.

If varhigher or varlower are used, it is quite possible to end up with different variables (with different priorities) printed in the same way: they will then appear multiple times in the output:

? y1 = varhigher("y");
? y2 = varlower("y");
? variables(y*y1*y2)
%4 = [y, y, y]
vecextract(x, y, z=None)

Extraction of components of the vector or matrix x according to y. In case x is a matrix, its components are the columns of x. The parameter y is a component specifier, which is either an integer, a string describing a range, or a vector.

If y is an integer, it is considered as a mask: the binary bits of y are read from right to left, but correspond to taking the components from left to right. For example, if y = 13 = (1101)_2 then the components 1,3 and 4 are extracted.

If y is a vector (t_VEC, t_COL or t_VECSMALL), which must have integer entries, these entries correspond to the component numbers to be extracted, in the order specified.

If y is a string, it can be

  • a single (non-zero) index giving a component number (a negative index means we start counting from the end).
  • a range of the form ":math:`a..:math:b, where :math:`a and b are indexes as above. Any of a and b can be omitted; in this case, we take as default values a = 1 and b = -1, i.e. the first and last components respectively. We then extract all components in the interval [a,b], in reverse order if b < a.

In addition, if the first character in the string is ^, the complement of the given set of indices is taken.

If z is not omitted, x must be a matrix. y is then the row specifier, and z the column specifier, where the component specifier is as explained above.

? v = [a, b, c, d, e];
? vecextract(v, 5) \\ mask
%1 = [a, c]
? vecextract(v, [4, 2, 1]) \\ component list
%2 = [d, b, a]
? vecextract(v, "2..4") \\ interval
%3 = [b, c, d]
? vecextract(v, "-1..-3") \\ interval + reverse order
%4 = [e, d, c]
? vecextract(v, "^2") \\ complement
%5 = [a, c, d, e]
? vecextract(matid(3), "2..", "..")
%6 =
[0 1 0]

[0 0 1]

The range notations v[i..j] and v[^i] (for t_VEC or t_COL) and M[i..j, k..l] and friends (for t_MAT) implement a subset of the above, in a simpler and faster way, hence should be preferred in most common situations. The following features are not implemented in the range notation:

  • reverse order,
  • omitting either a or b in :math:`a..:math:b`.
vecsearch(v, x, cmpf=None)

Determines whether x belongs to the sorted vector or list v: return the (positive) index where x was found, or 0 if it does not belong to v.

If the comparison function cmpf is omitted, we assume that v is sorted in increasing order, according to the standard comparison function lex, thereby restricting the possible types for x and the elements of v (integers, fractions, reals, and vectors of such).

If cmpf is present, it is understood as a comparison function and we assume that v is sorted according to it, see vecsort for how to encode comparison functions.

? v = [1,3,4,5,7];
? vecsearch(v, 3)
%2 = 2
? vecsearch(v, 6)
%3 = 0 \\ not in the list
? vecsearch([7,6,5], 5) \\ unsorted vector: result undefined
%4 = 0

By abuse of notation, x is also allowed to be a matrix, seen as a vector of its columns; again by abuse of notation, a t_VEC is considered as part of the matrix, if its transpose is one of the matrix columns.

? v = vecsort([3,0,2; 1,0,2]) \\ sort matrix columns according to lex order
%1 =
[0 2 3]

[0 2 1]
? vecsearch(v, [3,1]~)
%2 = 3
? vecsearch(v, [3,1]) \\ can search for x or x~
%3 = 3
? vecsearch(v, [1,2])
%4 = 0 \\ not in the list
vecsort(x, cmpf=None, flag=0)

Sorts the vector x in ascending order, using a mergesort method. x must be a list, vector or matrix (seen as a vector of its columns). Note that mergesort is stable, hence the initial ordering of “equal” entries (with respect to the sorting criterion) is not changed.

If cmpf is omitted, we use the standard comparison function lex, thereby restricting the possible types for the elements of x (integers, fractions or reals and vectors of those). If cmpf is present, it is understood as a comparison function and we sort according to it. The following possibilities exist:

  • an integer k: sort according to the value of the k-th subcomponents of the components of x.
  • a vector: sort lexicographically according to the components listed in the vector. For example, if cmpf = [2,1,3], sort with respect to the second component, and when these are equal, with respect to the first, and when these are equal, with respect to the third.
  • a comparison function (t_CLOSURE), with two arguments x and y, and returning an integer which is < 0, > 0 or = 0 if x < y, x > y or x = y respectively. The sign function is very useful in this context:
? vecsort([3,0,2; 1,0,2]) \\ sort columns according to lex order
%1 =
[0 2 3]

[0 2 1]
? vecsort(v, (x,y)->sign(y-x)) \\ reverse sort
? vecsort(v, (x,y)->sign(abs(x)-abs(y))) \\ sort by increasing absolute value
? cmpf(x,y) = my(dx = poldisc(x), dy = poldisc(y)); sign(abs(dx) - abs(dy))
? vecsort([x^2+1, x^3-2, x^4+5*x+1], cmpf)

The last example used the named cmpf instead of an anonymous function, and sorts polynomials with respect to the absolute value of their discriminant. A more efficient approach would use precomputations to ensure a given discriminant is computed only once:

? DISC = vector(#v, i, abs(poldisc(v[i])));
? perm = vecsort(vector(#v,i,i), (x,y)->sign(DISC[x]-DISC[y]))
? vecextract(v, perm)

Similar ideas apply whenever we sort according to the values of a function which is expensive to compute.

The binary digits of flag mean:

  • 1: indirect sorting of the vector x, i.e. if x is an n-component vector, returns a permutation of [1,2,...,n] which applied to the components of x sorts x in increasing order. For example, vecextract(x, vecsort(x,,1)) is equivalent to vecsort(x).
  • 4: use descending instead of ascending order.
  • 8: remove “duplicate” entries with respect to the sorting function (keep the first occurring entry). For example:
? vecsort([Pi,Mod(1,2),z], (x,y)->0, 8) \\ make everything compare equal
%1 = [3.141592653589793238462643383]
? vecsort([[2,3],[0,1],[0,3]], 2, 8)
%2 = [[0, 1], [2, 3]]
vecsum(v)

Return the sum of the components of the vector v. Return 0 on an empty vector.

? vecsum([1,2,3])
%1 = 6
? vecsum([])
%2 = 0
weber(x, flag=0, precision=0)

One of Weber’s three f functions. If flag = 0, returns

f(x) = \exp(-i\Pi/24).\eta((x+1)/2)/\eta(x) {such that} 
j = (f^{24}-16)^3/f^{24},

where j is the elliptic j-invariant (see the function ellj). If flag = 1, returns

f_1(x) = \eta(x/2)/\eta(x) {such that} 
j = (f_1^{24}+16)^3/f_1^{24}.

Finally, if flag = 2, returns

f_2(x) = \sqrt{2}\eta(2x)/\eta(x) {such that} 
j = (f_2^{24}+16)^3/f_2^{24}.

Note the identities f^8 = f_1^8+f_2^8 and ff_1f_2 = \sqrt2.

zeta(s, precision=0)

For s a complex number, Riemann’s zeta function \zeta(s) = \sum_{n >= 1}n^{-s}, computed using the Euler-Maclaurin summation formula, except when s is of type integer, in which case it is computed using Bernoulli numbers for s <= 0 or s > 0 and even, and using modular forms for s > 0 and odd.

For s a p-adic number, Kubota-Leopoldt zeta function at s, that is the unique continuous p-adic function on the p-adic integers that interpolates the values of (1 - p^{-k}) \zeta(k) at negative integers k such that k = 1 (mod p-1) (resp. k is odd) if p is odd (resp. p = 2).

zetak(nfz, x, flag=0, precision=0)

znf being a number field initialized by zetakinit (not by nfinit), computes the value of the Dedekind zeta function of the number field at the complex number x. If flag = 1 computes Dedekind \Lambda function instead (i.e. the product of the Dedekind zeta function by its gamma and exponential factors).

CAVEAT. This implementation is not satisfactory and must be rewritten. In particular

  • The accuracy of the result depends in an essential way on the accuracy of both the zetakinit program and the current accuracy. Be wary in particular that x of large imaginary part or, on the contrary, very close to an ordinary integer will suffer from precision loss, yielding fewer significant digits than expected. Computing with 28 digits of relative accuracy, we have
? zeta(3)
%1 = 1.202056903159594285399738161
? zeta(3-1e-20)
%2 = 1.202056903159594285401719424
? zetak(zetakinit(x), 3-1e-20)
%3 = 1.2020569031595952919 \\ 5 digits are wrong
? zetak(zetakinit(x), 3-1e-28)
%4 = -25.33411749 \\ junk
  • As the precision increases, results become unexpectedly completely wrong:
? \p100
? zetak(zetakinit(x^2-5), -1) - 1/30
%1 = 7.26691813 E-108 \\ perfect
? \p150
? zetak(zetakinit(x^2-5), -1) - 1/30
%2 = -2.486113578 E-156 \\ perfect
? \p200
? zetak(zetakinit(x^2-5), -1) - 1/30
%3 = 4.47... E-75 \\ more than half of the digits are wrong
? \p250
? zetak(zetakinit(x^2-5), -1) - 1/30
%4 = 1.6 E43 \\ junk
zetakinit(bnf, precision=0)

Computes a number of initialization data concerning the number field associated to bnf so as to be able to compute the Dedekind zeta and lambda functions, respectively zetak(x) and zetak(x,1), at the current real precision. If you do not need the bnfinit data somewhere else, you may call it with an irreducible polynomial instead of a bnf: it will call bnfinit itself.

The result is a 9-component vector v whose components are very technical and cannot really be used except through the zetak function.

This function is very inefficient and should be rewritten. It needs to computes millions of coefficients of the corresponding Dirichlet series if the precision is big. Unless the discriminant is small it will not be able to handle more than 9 digits of relative precision. For instance, zetakinit(x^8 - 2) needs 440MB of memory at default precision.

This function will fail with the message

*** bnrL1: overflow in zeta_get_N0 [need too many primes].

if the approximate functional equation requires us to sum too many terms (if the discriminant of the number field is too large).

zetamult(s, precision=0)

For s a vector of positive integers such that s[1] >= 2, returns the multiple zeta value (MZV)

\zeta(s_1,..., s_k) = \sum_{n_1 > ... > n_k > 0} n_1^{-s_1}...n_k^{-s_k}.

? zetamult([2,1]) - zeta(3) \\ Euler's identity
%1 = 0.E-38
zncoppersmith(P, N, X, B=None)

N being an integer and P belongs to \mathbb{Z}[X], finds all integers x with \|x\| <= X such that

\mathrm{gcd}(N, P(x)) >= B,

using Coppersmith’s algorithm (a famous application of the LLL algorithm). X must be smaller than \exp(\log^2 B / (\deg(P) \log N)): for B = N, this means X < N^{1/\deg(P)}. Some x larger than X may be returned if you are very lucky. The smaller B (or the larger X), the slower the routine will be. The strength of Coppersmith method is the ability to find roots modulo a general composite N: if N is a prime or a prime power, polrootsmod or polrootspadic will be much faster.

We shall now present two simple applications. The first one is finding non-trivial factors of N, given some partial information on the factors; in that case B must obviously be smaller than the largest non-trivial divisor of N.

setrand(1); \\ to make the example reproducible
interval = [10^30, 10^31];
p = randomprime(interval);
q = randomprime(interval); N = p*q;
p0 = p % 10^20; \\ assume we know 1) p > 10^29, 2) the last 19 digits of p
L = zncoppersmith(10^19*x + p0, N, 10^12, 10^29)

\\ result in 10ms.
%6 = [738281386540]
? gcd(L[1] * 10^19 + p0, N) == p
%2 = 1

and we recovered p, faster than by trying all possibilities < 10^{12}.

The second application is an attack on RSA with low exponent, when the message x is short and the padding P is known to the attacker. We use the same RSA modulus N as in the first example:

setrand(1);
P = random(N); \\ known padding
e = 3; \\ small public encryption exponent
X = floor(N^0.3); \\ N^(1/e - epsilon)
x0 = random(X); \\ unknown short message
C = lift( (Mod(x0,N) + P)^e ); \\ known ciphertext, with padding P
zncoppersmith((P + x)^3 - C, N, X)

\\ result in 244ms.
%14 = [2679982004001230401]

? %[1] == x0
%4 = 1

We guessed an integer of the order of 10^{18}, almost instantly.

znlog(x, g, o=None)

Discrete logarithm of x in (\mathbb{Z}/N\mathbb{Z})^* in base g. The result is [] when x is not a power of g. If present, o represents the multiplicative order of g, see DLfun (in the PARI manual); the preferred format for this parameter is [ord, factor(ord)], where ord is the order of g. This provides a definite speedup when the discrete log problem is simple:

? p = nextprime(10^4); g = znprimroot(p); o = [p-1, factor(p-1)];
? for(i=1,10^4, znlog(i, g, o))
time = 205 ms.
? for(i=1,10^4, znlog(i, g))
time = 244 ms. \\ a little slower

The result is undefined if g is not invertible mod N or if the supplied order is incorrect.

This function uses

  • a combination of generic discrete log algorithms (see below).
  • in (\mathbb{Z}/N\mathbb{Z})^* when N is prime: a linear sieve index calculus method, suitable for N < 10^{50}, say, is used for large prime divisors of the order.

The generic discrete log algorithms are:

  • Pohlig-Hellman algorithm, to reduce to groups of prime order q, where q | p-1 and p is an odd prime divisor of N,
  • Shanks baby-step/giant-step (q < 2^{32} is small),
  • Pollard rho method (q > 2^{32}).

The latter two algorithms require O(\sqrt{q}) operations in the group on average, hence will not be able to treat cases where q > 10^{30}, say. In addition, Pollard rho is not able to handle the case where there are no solutions: it will enter an infinite loop.

? g = znprimroot(101)
%1 = Mod(2,101)
? znlog(5, g)
%2 = 24
? g^24
%3 = Mod(5, 101)

? G = znprimroot(2 * 101^10)
%4 = Mod(110462212541120451003, 220924425082240902002)
? znlog(5, G)
%5 = 76210072736547066624
? G^% == 5
%6 = 1
? N = 2^4*3^2*5^3*7^4*11; g = Mod(13, N); znlog(g^110, g)
%7 = 110
? znlog(6, Mod(2,3)) \\ no solution
%8 = []

For convenience, g is also allowed to be a p-adic number:

? g = 3+O(5^10); znlog(2, g)
%1 = 1015243
? g^%
%2 = 2 + O(5^10)
znorder(x, o=None)

x must be an integer mod n, and the result is the order of x in the multiplicative group (\mathbb{Z}/n\mathbb{Z})^*. Returns an error if x is not invertible. The parameter o, if present, represents a non-zero multiple of the order of x, see DLfun (in the PARI manual); the preferred format for this parameter is [ord, factor(ord)], where ord = eulerphi(n) is the cardinality of the group.

znprimroot(n)

Returns a primitive root (generator) of (\mathbb{Z}/n\mathbb{Z})^*, whenever this latter group is cyclic (n = 4 or n = 2p^k or n = p^k, where p is an odd prime and k >= 0). If the group is not cyclic, the result is undefined. If n is a prime power, then the smallest positive primitive root is returned. This may not be true for n = 2p^k, p odd.

Note that this function requires factoring p-1 for p as above, in order to determine the exact order of elements in (\mathbb{Z}/n\mathbb{Z})^*: this is likely to be costly if p is large.

znstar(n)

Gives the structure of the multiplicative group (\mathbb{Z}/n\mathbb{Z})^* as a 3-component row vector v, where v[1] = \phi(n) is the order of that group, v[2] is a k-component row-vector d of integers d[i] such that d[i] > 1 and d[i] \| d[i-1] for i >= 2 and (\mathbb{Z}/n\mathbb{Z})^* ~ \prod_{i = 1}^k(\mathbb{Z}/d[i]\mathbb{Z}), and v[3] is a k-component row vector giving generators of the image of the cyclic groups \mathbb{Z}/d[i]\mathbb{Z}.

? G = znstar(40)
%1 = [16, [4, 2, 2], [Mod(17, 40), Mod(21, 40), Mod(11, 40)]]
? G.no \\ eulerphi(40)
%2 = 16
? G.cyc \\ cycle structure
%3 = [4, 2, 2]
? G.gen \\ generators for the cyclic components
%4 = [Mod(17, 40), Mod(21, 40), Mod(11, 40)]
? apply(znorder, G.gen)
%5 = [4, 2, 2]

According to the above definitions, znstar(0) is [2, [2], [-1]], corresponding to \mathbb{Z}^*.

sage.libs.pari.gen.objtogen(s)

Convert any Sage/Python object to a PARI gen.