See the PariInstance class for documentation and examples.
AUTHORS:
Bases: sage.libs.pari.gen.gen_auto
Cython extension class that models the PARI GEN type.
Transform the object \(x\) into a column vector with minimal size \(|n|\).
INPUT:
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).
Transform the object \(x\) into a column vector with minimal size \(|n|\). The order of the resulting vector is reversed compared to Col().
INPUT:
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): 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): Returns the matrix defined by x.
INPUT:
OUTPUT:
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): Returns the object x modulo y, denoted Mod(x, y).
The input y must be a an integer or a polynomial:
Warning
This function is not the same as x % y which is an integer or a polynomial.
INPUT:
OUTPUT:
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(x, v): convert x into a polynomial with main variable v and return the result.
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:
OUTPUT:
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(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:
OUTPUT:
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.): Returns the binary quadratic form
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:
OUTPUT:
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
Return a power series or Laurent series in the variable \(v\) constructed from the object \(f\).
INPUT:
OUTPUT:
The series is constructed from \(f\) in the following way:
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): convert x into a set, i.e. a row vector of strings in increasing lexicographic order.
INPUT:
OUTPUT:
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(self): Return the print representation of self as a PARI object.
INPUT:
OUTPUT:
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): converts x to a string, translating each integer into a character (in ASCII).
Note
Vecsmall() is (essentially) the inverse to Strchr().
INPUT:
OUTPUT:
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"
Concatenate the entries of the vector \(x\) into a single string, then perform tilde expansion and environment variable expansion similar to shells.
INPUT:
OUTPUT:
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): Translates the vector x of PARI gens to TeX format and returns the resulting concatenated strings as a PARI t_STR.
INPUT:
OUTPUT:
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"
Transform the object \(x\) into a vector with minimal size \(|n|\).
INPUT:
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).
Transform the object \(x\) into a vector with minimal size \(|n|\). The order of the resulting vector is reversed compared to Vec().
INPUT:
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]
Transform the object \(x\) into a t_VECSMALL with minimal size \(|n|\).
INPUT:
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])
Return True if self is a square modulo \(n\), False if not.
INPUT:
EXAMPLES:
sage: pari(3).Zn_issquare(4)
False
sage: pari(4).Zn_issquare(30.factor())
True
Return a square root of self modulo \(n\), if such a square root exists; otherwise, raise a ValueError.
INPUT:
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
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)
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
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
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
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): 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
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
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
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
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
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]
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
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]
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
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
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
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
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
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:
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
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
Deprecated: Use polresultantext() instead. See trac ticket #18203 for details.
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]
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): gives the vector formed by the binary digits of abs(x), where x is of type t_INT.
INPUT:
OUTPUT:
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): return the binomial coefficient “x choose k”.
INPUT:
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): Bitwise and of two integers x and y. Negative numbers behave as if modulo some large power of 2.
INPUT:
OUTPUT:
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): 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:
OUTPUT:
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): 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:
OUTPUT:
EXAMPLES:
sage: pari(14).bitnegimply(0)
14
sage: pari(8).bitnegimply(8)
0
sage: pari(8+4).bitnegimply(8)
4
bitor(x,y): Bitwise or of two integers x and y. Negative numbers behave as if modulo big power of 2.
INPUT:
OUTPUT:
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, 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:
OUTPUT:
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): Bitwise exclusive or of two integers x and y. Negative numbers behave as if modulo big power of 2.
INPUT:
OUTPUT:
EXAMPLES:
sage: pari(6).bitxor(4)
2
sage: pari(0).bitxor(4)
4
sage: pari(6).bitxor(0)
6
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]
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)]
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
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...
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 |
Return the order of the ray class group of self modulo I.
INPUT:
OUTPUT: integer
TESTS:
sage: K.<z> = QuadraticField(-23)
sage: p = K.primes_above(3)[0]
sage: K.pari_bnf().bnrclassno(p._pari_bid_())
3
For real x: return the smallest integer = x. For rational functions: the quotient of numerator by denominator. For lists: apply componentwise.
INPUT:
OUTPUT:
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): Centered lift of x. This function returns exactly the same thing as lift, except if x is an integer mod.
INPUT:
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)
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, 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:
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): Return the algebraic conjugate of x.
INPUT:
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): Returns the vector of all conjugates of the algebraic number x. An algebraic number is a polynomial over Q modulo an irreducible polynomial.
INPUT:
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
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
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)
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)
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
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): 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:
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
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
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]
x.eint1(n): exponential integral E1(x):
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:
EXAMPLES:
e.elladd(z0, z1): return the sum of the points z0 and z1 on this elliptic curve.
INPUT:
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]
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:
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
Return the first \(n\) Fourier coefficients of the modular form attached to this elliptic curve. See ellak for more details.
INPUT:
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'>
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]
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:
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
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:
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'>
Deprecated: Use ellheight() instead. See trac ticket #18203 for details.
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:
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]
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
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:
OUTPUT:
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
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
Return information related to the global minimal model of the elliptic curve e.
INPUT:
OUTPUT: A vector [N, [u,r,s,t], c, faN, L] with
N - the (arithmetic) conductor of \(e\)
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]]]
Canonical height of point a on elliptic curve self, resp. the value of the associated bilinear form at (a,b).
INPUT:
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
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:
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]
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:
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]]
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
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
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:
OUTPUT:
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]
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:
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(e): return the standard minimal integral model of the rational elliptic curve e and the corresponding change of variables. INPUT:
OUTPUT:
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]
Return \(n\) times the point \(z\) on the elliptic curve \(e\).
INPUT:
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))
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:
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
e.ellordinate(x): return the \(y\)-coordinates of the points on the elliptic curve e having x as \(x\)-coordinate.
INPUT:
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]
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
Deprecated: Use ellmul() instead. See trac ticket #18203 for details.
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:
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
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
e.ellsub(z0, z1): return z0-z1 on this elliptic curve.
INPUT:
OUTPUT: point on E
EXAMPLES:
sage: e = pari([0, 1, 1, -2, 0]).ellinit()
sage: e.ellsub([1,0], [-1,1])
[0, 0]
e.elltors(flag = 0): return information about the torsion subgroup of the elliptic curve e
INPUT:
OUTPUT:
EXAMPLES:
sage: e = pari([1,0,1,-19,26]).ellinit()
sage: e.elltors()
[12, [6, 2], [[1, 2], [3, -2]]]
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:
OUTPUT:
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]
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:
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
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:
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]
Return the complementary error 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).erfc()
0.157299207050285
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
Evaluate self with the given arguments.
This is currently implemented in 3 cases:
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]]
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)
Return the factorization of x.
INPUT:
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
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]
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]
Return the generator \(g=x \bmod T\) of the finite field defined by the polynomial \(T\).
INPUT:
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
Return a monic irreducible polynomial \(g\) of degree \(n\) over the finite field of \(p\) elements.
INPUT:
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)
Return the discrete logarithm of the finite field element self in base \(g\).
INPUT:
OUTPUT:
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
Return the multiplicative order of the finite field element self.
INPUT:
OUTPUT:
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
Return a primitive root of the multiplicative group of the definition field of the given finite field element.
INPUT:
OUTPUT:
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
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]
For real x: return the largest integer = x. For rational functions: the quotient of numerator by denominator. For lists: apply componentwise.
INPUT:
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): Return the fractional part of x, which is x - floor(x).
INPUT:
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)
Compute the fixed field of the Galois group self.
This wraps the galoisfixedfield function from PARI.
INPUT:
OUTPUT:
This depends on the value of flag:
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]]
Calculate the Galois group of self.
This wraps the galoisinit function from PARI.
INPUT:
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
Decide whether self is an abelian group.
This wraps the galoisisabelian function from PARI.
INPUT:
OUTPUT:
This returns 0 if self is not an abelian group. If it is, then the output depends on flag:
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
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
Return the polynomial defining the Galois automorphism perm.
This wraps the galoispermtopol function from PARI.
INPUT:
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]
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]]
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]
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
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
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
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
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
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
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
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
Chinese Remainder Theorem over number fields.
INPUT:
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
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]~
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]]
Return the discrete logarithm of the unit x in (ring of integers)/bid.
INPUT:
OUTPUT:
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]~
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
Return the big ideal (bid) structure of modulus I.
INPUT:
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)]
imag(x): Return the imaginary part of x. This function also works component-wise.
INPUT:
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]
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
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
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:
OUTPUT:
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(x, flag=0): Returns True if x is a PROVEN prime number, and False otherwise.
INPUT:
OUTPUT:
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])
Check whether self is a prime power (with an exponent >= 1).
INPUT:
OUTPUT:
A tuple (k, p) where \(k\) is a Python integer and \(p\) a PARI integer.
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(x, flag=0): Returns True if x is a pseudo-prime number, and False otherwise.
INPUT:
OUTPUT:
EXAMPLES:
sage: pari(9).ispseudoprime()
False
sage: pari(17).ispseudoprime()
True
sage: n = pari(561) # smallest Carmichael number
sage: n.ispseudoprime(2)
False
Check whether self is the power (with an exponent >= 1) of a pseudo-prime.
INPUT:
OUTPUT:
A tuple (k, p) where \(k\) is a Python integer and \(p\) a PARI integer.
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,n): True if x is a square, False if not. If find_root is given, also returns the exact square root.
EXAMPLES:
sage: pari(10).issquarefree()
True
sage: pari(20).issquarefree()
False
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]
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): 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:
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
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]
Return str that might correctly evaluate to a Python-list.
Alias for log_gamma().
EXAMPLES:
sage: pari(100).lngamma()
359.134205369575
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
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
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(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]
Return the determinant of this matrix.
INPUT:
EXAMPLES:
sage: pari('[1,2; 3,4]').matdet(0)
-2
sage: pari('[1,2; 3,4]').matdet(1)
-2
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:
A.mathnf(flag=0): (upper triangular) Hermite normal form of A, basis for the lattice formed by the columns of A.
INPUT:
EXAMPLES:
sage: pari('[1,2,3; 4,5,6; 7,8,9]').mathnf()
[6, 1; 3, 1; 0, 1]
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:
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]
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:
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]
Return a basis of the kernel of this matrix.
INPUT:
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)]
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]
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): 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:
EXAMPLES:
sage: pari('[1,1;1,-1]').matsolve(pari('[1;0]'))
[1/2; 1/2]
For column vectors \(D=(d_i)\) and \(B=(b_i)\), find a small integer solution to the system of linear congruences
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]]
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]
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()
Return the number of columns of self.
EXAMPLES:
sage: pari('matrix(19,8)').ncols()
8
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(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
Returns the different of this number field as a PARI ideal.
INPUT:
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]
Returns the defining polynomial of this number field.
INPUT:
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)
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:
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]
Returns a vector with a \(\ZZ\)-basis for the ring of integers of this number field. The first element is always \(1\).
INPUT:
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]
Given a PARI number field self, return the same PARI number field but in the variable z.
INPUT:
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]
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]
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)
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
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(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
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]~
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
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]~
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(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:
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.
0: default
1: do not compute different
2: first use polred to find a simpler polynomial
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(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]
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)]
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]
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:
Return the number of rows of self.
EXAMPLES:
sage: pari('matrix(19,8)').nrows()
19
numbpart(x): returns the number of partitions of x.
EXAMPLES:
sage: pari(20).numbpart()
627
sage: pari(100).numbpart()
190569292
Return the number of divisors of the integer n.
EXAMPLES:
sage: pari(10).numdiv()
4
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]
padicprec(x,p): Return the absolute p-adic precision of the object x.
INPUT:
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
The uniformizer of the p-adic ring this element lies in, as a t_INT.
INPUT:
OUTPUT:
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'
Return the Euler phi function of n.
EXAMPLES:
sage: pari(10).phi()
4
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
f.poldegree(var=x): Return the degree of this polynomial.
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)
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.
f.polisirreducible(): Returns True if f is an irreducible non-constant polynomial, or False if f is reducible or constant.
Complex roots of the given polynomial using Schonhage’s method, as modified by Gourdon.
Deprecated: Use polsturm() instead. See trac ticket #18203 for details.
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
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
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
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
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): 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:
OUTPUT: nothing or gen if n is omitted
EXAMPLES:
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
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
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
Return a Python list of the PARI gens. This object must be of type t_VEC.
INPUT: None
OUTPUT:
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]
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'>
Computes the class number of the quadratic order of discriminant \(d\).
INPUT:
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
Computes the Hurwitz-Kronecker class number of \(n\).
INPUT:
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
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
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]
]
Coefficients of binary quadratic forms that parametrize the solutions of the ternary quadratic form self, using the particular solution sol.
INPUT:
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
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])
Try to solve over \(\mathbb{Q}\) the quadratic equation \(X^t G X = 0\) for a matrix G with rational coefficients.
INPUT:
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]
Returns the class group of a quadratic order of discriminant \(d\).
INPUT:
OUTPUT:
(h,cyc,gen,reg) where:
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
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
Return the polynomial obtained by reversing the coefficients of this polynomial.
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
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)
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:
OUTPUT:
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
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(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)
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 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'
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
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
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:
OUTPUT: int (a Python int)
EXAMPLE:
sage: pari('1').sizebyte()
12 # 32-bit
24 # 64-bit
sizedigit(x): Return a quick estimate for the maximal number of decimal digits before the decimal point of any component of x.
INPUT:
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
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:
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
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)
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
Return the integer square root of the integer \(x\), rounded towards zero.
EXAMPLES:
sage: pari(8).sqrtint()
2
sage: pari(10^100).sqrtint()
100000000000000000000000000000000000000000000000000
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:
OUTPUT:
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
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
Return the sum of the divisors of \(n\).
EXAMPLES:
sage: pari(10).sumdiv()
18
Return the sum of the k-th powers of the divisors of n.
EXAMPLES:
sage: pari(10).sumdivk(2)
130
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
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 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)
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
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
Return the trace of this PARI object.
EXAMPLES:
sage: pari('[1,2; 3,4]').trace()
5
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:
OUTPUT:
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)
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): Return the valuation of x with respect to p.
The valuation is the highest exponent of p dividing x.
INPUT:
OUTPUT:
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): 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:
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
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): Return the maximum of the elements of the vector/matrix x.
vecmin(x): Return the maximum of the elements of the vector/matrix x.
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
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): 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:
OUTPUT:
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)
Return a primitive root modulo self, whenever it exists.
INPUT:
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)
Return the structure of the group \((\ZZ/n\ZZ)^*\).
INPUT:
OUTPUT:
A triple \([\phi(n), [d_1, \ldots, d_k], [x_1, \ldots, x_k]]\), where
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)]]
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.
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
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.
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.
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.
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
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]
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`.
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.
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).
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.
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.
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]
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"
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
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.
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.
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).
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.
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\).
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.
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.
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.
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
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.
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]~
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
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)
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]
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]~
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
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
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
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.
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\).
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
\(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.
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
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
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.
Given two elements \(x\) and \(y\) in al, return \(xy^{-1}\). Also accepts matrices with coefficients in al.
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
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])
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])
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
Initialize the central simple algebra defined by data \(B\), \(C\) and variable \(v\), as follows.
{ 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.
? 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})\).
? Q = nfinit(y); A = alginit(Q, [-1,-1]); \\ (-1,-1)_Q
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
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:
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.
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]
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).
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
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
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
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
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
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
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.
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]
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.
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.
Given an element \(b\) in al and a polynomial \(T\) in \(K[X]\), computes \(T(b)\) in al.
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.
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]
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
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]
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]]
Given an algebra al and an integer b, returns a random element in al with coefficients in \([-b,b]\).
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
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.
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:
? 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]
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
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.
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.
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.
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
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:
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]
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\).
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.
Given an algebra al output by alginit or by algtableinit, returns an integer indicating the type of 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
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:
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 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]
Argument of the complex number \(x\), such that \(-\Pi < {arg}(x) <= \Pi\).
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)\).
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.
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\).
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.
\(H^1\)-Bessel function of index nu and argument \(x\).
\(H^2\)-Bessel function of index nu and argument \(x\).
\(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).
\(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).
\(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.
\(K\)-Bessel function of index nu and argument \(x\).
\(N\)-Bessel function of index nu and argument \(x\).
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\)).
? 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\).)
? 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 \([]\).
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\)).
? 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]
? 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 \([]\).
Deprecated alias for gcdext
Deprecated alias for polresultantext
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
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 coefficient \(binom{x}{y}\). Here \(y\) must be an integer, but \(x\) can be any PARI object.
Bitwise and of two integers \(x\) and \(y\), that is the integer
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
bitwise negation of an integer \(x\), truncated to \(n\) bits, \(n >= 0\), that is the integer
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.
Bitwise negated imply of two integers \(x\) and \(y\) (or not \((x ==> y)\)), that is the integer
See bitand (in the PARI manual) for the behavior for negative arguments.
bitwise (inclusive) or of two integers \(x\) and \(y\), that is the integer
See bitand (in the PARI manual) for the behavior for negative arguments.
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.
Bitwise (exclusive) or of two integers \(x\) and \(y\), that is the integer
See bitand (in the PARI manual) for the behavior for negative arguments.
\(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
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]\).
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]
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).
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.
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.
\(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
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:
is_principal(bnf, x) = !bnfisprincipal(bnf,x,0);
\(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.
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.)
\(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.
\(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
}
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\).
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
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).
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.
\(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
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)\).
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.
\(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:
\(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.
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.
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.
\(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.
\(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.
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.
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.
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
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).
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)
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.
Same as lift, except that t_INTMOD and t_PADIC components are lifted using centered residues:
For backward compatibility, centerlift(x,'v) is allowed as an alias for lift(x,'v).
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
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\)).
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.
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).
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
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]
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).
Conjugate vector representation of \(z\). If \(z\) is a polmod, equal to Mod\((a,T)\), this gives a vector of length \({degree}(T)\) containing:
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\).
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}[\).
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)`.
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.
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.
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]
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]\).
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}^*\).
Cosine of \(x\).
Hyperbolic cosine of \(x\).
Cotangent of \(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).
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\).
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))
}
Outputs the vector of the digits of \(\|x\|\) in base \(b\), where \(x\) and \(b\) are integers. See fromdigits for the reverse operation.
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\).
\(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.
\(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]
Gives as a vector the first \(b\) coefficients of the Dedekind zeta function of the number field \(nf\) considered as a Dirichlet series.
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.
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)
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.
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[...]
Sum of the points \(z1\) and \(z2\) on the elliptic curve corresponding to \(E\).
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.
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.
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]
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.
Deprecated alias for ellheight(E,P,Q).
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.
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.
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]
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
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"
\(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
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
For \(n >= 2\), the roots of \(f_n\) are the \(X\)-coordinates of points in \(E[n]\).
\(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
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
is a Weierstrass equation for \(E\).
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]
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\):
? 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)
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)
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)
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\):
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)]
Return the formal power series \(w\) associated to the elliptic curve \(E\), in the variable \(t\):
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)
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]
Returns the coefficients \([a_1,a_2,a_3,a_4,a_6]\) of a fixed elliptic curve with \(j\)-invariant \(j\).
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)\).
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
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
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.
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\).
\(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.
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.
Initialize an ell structure, associated to the elliptic curve \(E\). \(E\) is either
The optional argument \(D\) describes the domain over which the curve is defined:
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:
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.
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]]
Given an isogeny of elliptic curves \(f:E'\\to E\) (being the result of a call to ellisogeny), apply \(f\) to \(x\):
? 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
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.
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]
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.
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\).
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
\(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.
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.
Opposite of the point \(z\) on elliptic curve \(E\).
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
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.
Gives a 0, 1 or 2-component vector containing the \(y\)-coordinates of the points of the curve \(E\) having \(x\) as \(x\)-coordinate.
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
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
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
? 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)]~
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
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
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
(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)
\(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\).
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)\).
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
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.
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.
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
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:
? 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)
Deprecated alias for ellmul.
\(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.
This function finds all curves in the elldata database satisfying the constraint defined by the argument \(N\):
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 = []
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\).
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))\).
Difference of the points \(z1\) and \(z2\) on the elliptic curve corresponding to \(E\).
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\).
Computes the Tate pairing of the two points \(P\) and \(Q\) on the elliptic curve \(E\). The point \(P\) must be of \(m\)-torsion.
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]\).
Computes the Weil pairing of the two points of \(m\)-torsion \(P\) and \(Q\) on the elliptic curve \(E\).
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)]\).
In standard notation, for any affine point \(P = (v,w)\) on the curve \(E\), we have
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\).
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\).
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
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)
\(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
If \(z\) is in the lattice defining \(E\) over \(\mathbb{C}\), the result is the point at infinity \([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\).
Returns the type of the error message E as a string.
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:
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}\).
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}\).
Exponential of \(x\). \(p\)-adic arguments with positive valuation are accepted.
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.
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.
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
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.
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.
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).
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.
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.
\(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.
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.
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.
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
? 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
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\)).
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 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.
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
Fractional part of \(x\). Identical to \(x-{floor}(x)\). If \(x\) is real, the result is in \([0,1[\).
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
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 ]
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)\)
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.
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 galois\(xxx\) 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]\).
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.
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.
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\).
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
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\).
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.
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])
For \(s\) a complex number, evaluates Euler’s gamma function
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
Gamma function evaluated at the argument \(x+1/2\).
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.
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
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
with \(a = (1-d+\sum_{1 <= j <= d}a_j)/d\).
Initialize data for the computation by gammamellininv of the \(m\)-th derivative of the inverse Mellin transform of the function
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
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:
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\).
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.
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
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.
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 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.)
\(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.
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\).
\(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.
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)).
\(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\).
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).
\(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\).
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\).
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.
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.
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.
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\).
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:
? 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.
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,] )
}
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]\).
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.
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]
\(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
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.
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.
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.
Computes the norm of the ideal \(x\) in the number field \(nf\).
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]]
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.
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
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
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:
and for \(i >= 2\),
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\).
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
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”.
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.
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)
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.
Imaginary part of \(x\). When \(x\) is a quadratic number, this is the coefficient of \(\omega\) in the “canonical” integral basis \((1,\omega)\).
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.
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\).
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
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
for some integration step \(h\) and truncation parameter \(N\). In basic use, let
[h, x0, w0, xp, wp, xm, wm] = intnuminit(a,b);
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\).
True (1) if \(x\) is equal to 1 or to the discriminant of a quadratic field, false (0) otherwise.
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
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
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.
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\)).
True (1) if \(x\) is squarefree, false (0) if not. Here \(x\) can be an integer or a polynomial.
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\):
Lambert \(W\) function, solution of the implicit equation \(xe^x = y\), for \(y > 0\).
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 of \(x\); #\(x\) is a shortcut for length\((x)\). This is mostly useful for
? #"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.
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
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).
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
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)
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
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
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
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
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\).
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]
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
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.
\(nf\) being a number field in nfinit format, and \(x\) a (row or column) vector or matrix, apply nfalgtobasis to each entry of \(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\).
The left companion matrix to the non-zero polynomial \(x\).
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:
? 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]
Determinant of the square matrix \(x\).
If \(flag = 0\), uses an appropriate algorithm depending on the coefficients:
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.
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.
\(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]
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\).
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\).
Returns a matrix similar to the square matrix \(x\), which is in upper Hessenberg form (zero entries below the first subdiagonal).
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:
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.
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]
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.
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]
applies a sequence \(Q\) of Householder transforms, as returned by matqr\((M,1)\) to the vector or matrix \(v\).
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!).
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\).
\(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.
\(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.
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]
Returns true (1) if \(x\) is a diagonal matrix, false (0) if not.
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\).
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.
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)\).
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.
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.
Rank of the matrix \(x\).
\(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]
\(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).
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.
\(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\).
\(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.
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.
Transpose of \(x\) (also \(x~\)). This has an effect only on vectors and matrices.
Creates the maximum of \(x\) and \(y\) when they can be compared.
Creates the maximum of \(x\) and \(y\) when they can be compared.
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\).
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
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 \(\mu\)-function of \(\|x\|\). \(x\) must be of type integer.
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
\(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]
\(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
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
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.
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 \(T_p(x^±) = a_p x^±\), 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
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
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 \(x^±\) 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
\(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
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\).
\(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
\(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
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\).
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\).
\(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]
\(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.
\(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
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).
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.
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.
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.
\(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.
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
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.
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
Given two elements \(x\) and \(y\) in nf, computes their sum \(x+y\) in the number field \(nf\).
Given two elements \(x\) and \(y\) in nf, computes their quotient \(x/y\) in the number field \(nf\).
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))`.
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.
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.
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
Given two elements \(x\) and \(y\) in nf, computes their product \(x*y\) in the number field \(nf\).
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.
Returns the absolute norm of \(x\).
Given an element \(x\) in nf, and a positive or negative integer \(k\), computes \(x^k\) in the number field \(nf\).
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.
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.
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.
Returns the absolute trace of \(x\).
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.
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
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.
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
\(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
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:
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)
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.
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]\).
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.
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
? 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.
Returns 1 if \(x\) is an ideal in the number field \(nf\), 0 otherwise.
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.
As nfisincl, but tests for isomorphism. If either \(x\) or \(y\) is a number field, a much faster algorithm will be used.
Kernel of the matrix \(a\) in \(\mathbb{Z}_K/pr\), where pr is in modpr format (see nfmodprinit).
Transforms the prime ideal pr into modpr format necessary for all operations modulo pr in the number field nf.
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).
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.
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.
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
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\).
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]~
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.
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).
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.
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
\(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:
? 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
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.
Number of divisors of \(\|x\|\). \(x\) must be of type integer.
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).
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
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\).
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.
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.
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.
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.
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.
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\).
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
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).
\(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]
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]
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.
Discriminant of the polynomial pol in the main variable if \(v\) is omitted, in \(v\) otherwise. The algorithm used is the subresultant algorithm.
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\).
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.
Returns the Graeffe transform \(g\) of \(f\), such that \(g(x^2) = f(x) f(-x)\).
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)
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
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
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.
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.
Reciprocal polynomial of pol, i.e. the coefficients are in reverse order. pol must be a polynomial.
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
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]
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).
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.
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.
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
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.
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.
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.
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.
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.
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
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.
Creates the column vector of the symmetric powers of the roots of the polynomial \(x\) up to power \(n\), using Newton’s formula.
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.
Return the vector \([1,x,...,x^n]\).
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
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.
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.
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]
The \(\psi\)-function of \(x\), i.e. the logarithmic derivative \(\Gamma'(x)/\Gamma(x)\).
\(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.
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
Ordinary class number of the quadratic order of discriminant \(D\), for “small” values of \(D\).
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.
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.
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.
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.
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.
\(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\).
\(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}\).
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.
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.
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.
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.
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
? 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\).
\(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.
\(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
Since this function computes the minimal vectors, it can become very lengthy as the dimension of \(G\) grows.
Apply Jacobi’s eigenvalue algorithm to the real symmetric matrix \(A\). This returns \([L, V]\), where
? \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
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.
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.
\(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.
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.
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
? 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
\(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.
\(q\) being a square and symmetric matrix with integer entries representing a positive definite quadratic form, count the vectors representing successive integers.
? 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}\)).
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.
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
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:
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).
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
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.
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.
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.
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.
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.
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)).
Returns a random element in various natural sets depending on the argument \(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.
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 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)\).
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.
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.
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.
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.
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
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.
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]\):
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
The routine will fail if \(P\) is \(0\) on the projective line over the residue field \(\mathbb{Z}_K/pr\) (FIXME).
Given a pseudo-matrix \(M\) over the maximal order of \(nf\), computes its determinant.
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).
\(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
\(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
\(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))
\(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)
\(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))
\(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)
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
? 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
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.
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
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\).
\(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.
\(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.
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.
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.
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.
\(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.
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.
\(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).
\(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
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.
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).
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.
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.
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.
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.
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.
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.
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
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\).
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)\)).
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))
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\).
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\).
\(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\).
Reverse power series of \(s\), i.e. the series \(t\) such that \(t(s) = x\); \(s\) must be a power series whose valuation is exactly equal to one.
? \ps 8
? t = serreverse(tan(x))
%2 = x - 1/3*x^3 + 1/5*x^5 - 1/7*x^7 + O(x^8)
? tan(t)
%3 = x + O(x^8)
The 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]
Intersection of the two sets \(x\) and \(y\) (see setisset). If \(x\) or \(y\) is not a set, the result is undefined.
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]
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.
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.
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])
Union of the two sets \(x\) and \(y\) (see setisset). If \(x\) or \(y\) is not a set, the result is undefined.
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\).
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.
Sum of the \(k-th\) powers of the positive divisors of \(\|x\|\). \(x\) and \(k\) must be of type integer.
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.
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"
Sine of \(x\).
Cardinal sine of \(x\), i.e. \(\sin(x)/x\) if \(x != 0\), \(1\) otherwise. Note that this function also allows to compute
accurately near \(x = 0\).
Hyperbolic sine of \(x\).
Outputs the total number of bytes occupied by the tree representing the PARI object \(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
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).
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).
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.
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
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
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.)
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.
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)
\(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]
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))
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.
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
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.
Tangent of \(x\).
Hyperbolic tangent of \(x\).
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.
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\).
Jacobi sine theta-function
\(k\)-th derivative at \(z = 0\) of \(theta(q,z)\).
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
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.
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.
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.
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”.
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.
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.
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]
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
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:
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
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:
? 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:
? 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]]
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
One of Weber’s three \(f\) functions. If \(flag = 0\), returns
where \(j\) is the elliptic \(j\)-invariant (see the function ellj). If \(flag = 1\), returns
Finally, if \(flag = 2\), returns
Note the identities \(f^8 = f_1^8+f_2^8\) and \(ff_1f_2 = \sqrt2\).
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\)).
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
? 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
? \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
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).
For \(s\) a vector of positive integers such that \(s[1] >= 2\), returns the multiple zeta value (MZV)
? zetamult([2,1]) - zeta(3) \\ Euler's identity
%1 = 0.E-38
\(N\) being an integer and \(P belongs to \mathbb{Z}[X]\), finds all integers \(x\) with \(\|x\| <= X\) such that
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.
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
The generic discrete log algorithms are:
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)
\(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.
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.
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}^*\).
Convert any Sage/Python object to a PARI gen.