The Gen class wrapping PARI’s GEN type¶
AUTHORS:
William Stein (2006-03-01): updated to work with PARI 2.2.12-beta
William Stein (2006-03-06): added newtonpoly
Justin Walker: contributed some of the function definitions
Gonzalo Tornaria: improvements to conversions; much better error handling.
Robert Bradshaw, Jeroen Demeyer, William Stein (2010-08-15): Upgrade to PARI 2.4.3 (Sage ticket #9343)
Jeroen Demeyer (2011-11-12): rewrite various conversion routines (Sage ticket #11611, Sage ticket #11854, Sage ticket #11952)
Peter Bruin (2013-11-17): move Pari to a separate file (Sage ticket #15185)
Jeroen Demeyer (2014-02-09): upgrade to PARI 2.7 (Sage ticket #15767)
Martin von Gagern (2014-12-17): Added some Galois functions (Sage ticket #17519)
Jeroen Demeyer (2015-01-12): upgrade to PARI 2.8 (Sage ticket #16997)
Jeroen Demeyer (2015-03-17): automatically generate methods from
pari.desc
(Sage ticket #17631 and Sage ticket #17860)Kiran Kedlaya (2016-03-23): implement infinity type
Luca De Feo (2016-09-06): Separate Sage-specific components from generic C-interface in
Pari
(Sage ticket #20241)Vincent Delecroix (2017-04-29): Python 3 support and doctest conversion
- class cypari2.gen.Gen¶
Wrapper for a PARI
GEN
with memory management.This wraps PARI objects which live either on the PARI stack or on the PARI heap. Results from PARI computations appear on the PARI stack and we try to keep them there. However, when the stack fills up, we copy (“clone” in PARI speak) all live objects from the stack to the heap. This happens transparently for the user.
- Ser(v, precision)¶
Return a power series or Laurent series in the variable v constructed from the object f.
INPUT:
f
– PARI genv
– PARI variable (default: x)precision
– the desired relative precision (default: the value returned bypari.get_series_precision()
). This is the absolute precision minus the v-adic valuation.
OUTPUT:
PARI object of type
t_SER
The series is constructed from f in the following way:
If f is a scalar, a constant power series is returned.
If f is a polynomial, it is converted into a power series in the obvious way.
If f is a rational function, it will be expanded in a Laurent series around v = 0.
If f is a vector, its coefficients become the coefficients of the power series, starting from the constant term. This is the convention used by the function
Polrev()
, and the reverse of that used byPol()
.
Warning
This function will not transform objects containing variables of higher priority than v.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(2).Ser() 2 + O(x^16) >>> pari('Mod(0, 7)').Ser() Mod(0, 7)*x^15 + O(x^16)
>>> x = pari([1, 2, 3, 4, 5]) >>> x.Ser() 1 + 2*x + 3*x^2 + 4*x^3 + 5*x^4 + O(x^16) >>> f = x.Ser('v'); print(f) 1 + 2*v + 3*v^2 + 4*v^3 + 5*v^4 + O(v^16) >>> 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)
>>> pari('x^5').Ser(precision=20) x^5 + O(x^25) >>> pari('1/x').Ser(precision=1) x^-1 + O(x^0)
- Str()¶
Str(self): Return the print representation of self as a PARI object.
INPUT:
self
- gen
OUTPUT:
gen
- a PARI Gen of type t_STR, i.e., a PARI string
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari([1,2,['abc',1]]).Str() "[1, 2, [abc, 1]]" >>> pari([1,1, 1.54]).Str() "[1, 1, 1.54000000000000]" >>> pari(1).Str() # 1 is automatically converted to string rep "1" >>> x = pari('x') # PARI variable "x" >>> x.Str() # is converted to string rep. "x" >>> x.Str().type() 't_STR'
- Strexpand()¶
Concatenate the entries of the vector x into a single string, then perform tilde expansion and environment variable expansion similar to shells.
INPUT:
x
– PARI gen. Either a vector or an element which is then treated like [x].
OUTPUT:
PARI string (type
t_STR
)
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('"~/subdir"').Strexpand() "..." >>> pari('"$SHELL"').Strexpand() "..."
Tests:
>>> a = pari('"$HOME"') >>> a.Strexpand() != a True
- Strtex()¶
Strtex(x): Translates the vector x of PARI gens to TeX format and returns the resulting concatenated strings as a PARI t_STR.
INPUT:
x
– PARI gen. Either a vector or an element which is then treated like [x].
OUTPUT:
PARI string (type
t_STR
)
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> v = pari('x^2') >>> v.Strtex() "x^2" >>> v = pari(['1/x^2','x']) >>> v.Strtex() "\\frac{1}{x^2}x" >>> v = pari(['1 + 1/x + 1/(y+1)','x-1']) >>> v.Strtex() "\\frac{ \\left(y\n + 2\\right) \\*x\n + \\left(y\n + 1\\right) }{ \\left(y\n + 1\\right) \\*x}x\n - 1"
- Zn_issquare(n)¶
Return
True
ifself
is a square modulo n,False
if not.INPUT:
self
– integern
– integer or factorisation matrix
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(3).Zn_issquare(4) False >>> pari(4).Zn_issquare(pari(30).factor()) True
- Zn_sqrt(n)¶
Return a square root of
self
modulo n, if such a square root exists; otherwise, raise aValueError
.INPUT:
self
– integern
– integer or factorisation matrix
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(3).Zn_sqrt(4) Traceback (most recent call last): ... ValueError: 3 is not a square modulo 4 >>> pari(4).Zn_sqrt(pari(30).factor()) 22
- allocatemem(*args)¶
Do not use this. Use
pari.allocatemem()
instead.Tests:
>>> from cypari2 import Pari >>> pari = Pari() >>> pari(2**10).allocatemem(2**20) Traceback (most recent call last): ... NotImplementedError: the method allocatemem() should not be used; use pari.allocatemem() instead
- arity()¶
Return the number of arguments of this
t_CLOSURE
.>>> from cypari2 import Pari >>> pari = Pari() >>> pari("() -> 42").arity() 0 >>> pari("(x) -> x").arity() 1 >>> pari("(x,y,z) -> x+y+z").arity() 3
- bernfrac()¶
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:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(18).bernfrac() 43867/798 >>> [pari(n).bernfrac() for n in range(10)] [1, -1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0]
- bernreal(precision)¶
The Bernoulli number B_x, as for the function bernfrac, but B_x is returned as a real number (with the current precision).
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(18).bernreal() 54.9711779448622
- besselk(x, precision)¶
nu.besselk(x): K-Bessel function (modified Bessel function of the second kind) of index nu, which can be complex, and argument x.
If nu or x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If the arguments are inexact (e.g. real), the smallest of their precisions is used in the computation, and the parameter precision is ignored.
INPUT:
nu
- a complex numberx
- real number (positive or negative)
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(complex(2, 1)).besselk(3) 0.0455907718407551 + 0.0289192946582081*I
>>> pari(complex(2, 1)).besselk(-3) -4.34870874986752 - 5.38744882697109*I
>>> pari(complex(2, 1)).besselk(300) 3.74224603319728 E-132 + 2.49071062641525 E-134*I
- bid_get_cyc()¶
Returns the structure of the group (O_K/I)^*, where I is the ideal represented by
self
.NOTE:
self
must be a “big ideal” (bid
) as returned byidealstar
for example.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> i = pari('i') >>> K = (i**2 + 1).bnfinit() >>> J = K.idealstar(4*i + 2) >>> J.bid_get_cyc() [4, 2]
- bid_get_gen()¶
Returns a vector of generators of the group (O_K/I)^*, where I is the ideal represented by
self
.NOTE:
self
must be a “big ideal” (bid
) with generators, as returned byidealstar
withflag
= 2.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> i = pari('i') >>> K = (i**2 + 1).bnfinit() >>> J = K.idealstar(4*i + 2, 2) >>> J.bid_get_gen() [7, [-2, -1]~]
We get an exception if we do not supply
flag = 2
toidealstar
:>>> J = K.idealstar(3) >>> J.bid_get_gen() Traceback (most recent call last): ... PariError: missing bid generators. Use idealstar(,,2)
- bittest(n)¶
bittest(x, long n): Returns bit number n (coefficient of 2^n in binary) of the integer x. Negative numbers behave as if modulo a big power of 2.
INPUT:
x
- Gen (pari integer)
OUTPUT:
bool
- a Python bool
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari(6) >>> x.bittest(0) False >>> x.bittest(1) True >>> x.bittest(2) True >>> x.bittest(3) False >>> pari(-3).bittest(0) True >>> pari(-3).bittest(1) False >>> [pari(-3).bittest(n) for n in range(10)] [True, False, True, True, True, True, True, True, True, True]
- bnf_get_cyc()¶
Returns the structure of the class group of this number field as a vector of SNF invariants.
NOTE:
self
must be a “big number field” (bnf
).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**2 + 65).bnfinit() >>> K.bnf_get_cyc() [4, 2]
- bnf_get_fu()¶
Return the fundamental units
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x')
>>> (x**2 - 65).bnfinit().bnf_get_fu() [Mod(x - 8, x^2 - 65)] >>> (x**4 - x**2 + 1).bnfinit().bnf_get_fu() [Mod(x - 1, x^4 - x^2 + 1)] >>> p = x**8 - 40*x**6 + 352*x**4 - 960*x**2 + 576 >>> len(p.bnfinit().bnf_get_fu()) 7
- bnf_get_gen()¶
Returns a vector of generators of the class group of this number field.
NOTE:
self
must be a “big number field” (bnf
).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**2 + 65).bnfinit() >>> G = K.bnf_get_gen(); G [[3, 2; 0, 1], [2, 1; 0, 1]]
- bnf_get_no()¶
Returns the class number of
self
, a “big number field” (bnf
).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**2 + 65).bnfinit() >>> K.bnf_get_no() 8
- bnf_get_reg()¶
Returns the regulator of this number field.
NOTE:
self
must be a “big number field” (bnf
).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**4 - 4*x**2 + 1).bnfinit() >>> K.bnf_get_reg() 2.66089858019037...
- bnf_get_tu()¶
Return the torsion unit
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x')
>>> for p in [x**2 - 65, x**4 - x**2 + 1, x**8 - 40*x**6 + 352*x**4 - 960*x**2 + 576]: ... bnf = p.bnfinit() ... n, z = bnf.bnf_get_tu() ... if pari.version() < (2,11,0) and z.lift().poldegree() == 0: z = z.lift() ... print([p, n, z]) [x^2 - 65, 2, -1] [x^4 - x^2 + 1, 12, Mod(x, x^4 - x^2 + 1)] [x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576, 2, -1]
- bnfunit()¶
Deprecated in cypari 2.1.2
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x')
>>> import warnings >>> with warnings.catch_warnings(record=True) as w: ... warnings.simplefilter('always') ... funits = (x**2 - 65).bnfinit().bnfunit() ... assert len(w) == 1 ... assert issubclass(w[0].category, DeprecationWarning) >>> funits [Mod(x - 8, x^2 - 65)]
- change_variable_name(var)¶
In
self
, which must be at_POL
ort_SER
, set the variable tovar
. If the variable ofself
is alreadyvar
, then returnself
.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:
>>> from cypari2 import Pari >>> pari = Pari()
>>> f = pari('x^3 + 17*x + 3') >>> f.change_variable_name("y") y^3 + 17*y + 3 >>> f = pari('1 + 2*y + O(y^10)') >>> f.change_variable_name("q") 1 + 2*q + O(q^10) >>> 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 withsubst()
:>>> f = pari('x^2 + 1') >>> f.change_variable_name("I") Traceback (most recent call last): ... PariError: I already exists with incompatible valence >>> f.subst("x", "I") 0
- cmp(right)¶
Compare
self
andright
.This uses PARI’s
cmp_universal()
routine, which defines a total ordering on the set of all PARI objects (up to the indistinguishability relation given bygidentical()
).Warning
This comparison is only mathematically meaningful when comparing 2 integers. In particular, when comparing rationals or reals, this does not correspond to the natural ordering.
Examples:
>>> from cypari2 import Pari >>> pari = Pari() >>> pari(5).cmp(pari(5)) 0 >>> pari('x^2 + 1').cmp(pari('I-1')) 1 >>> I = pari('I') >>> I.cmp(I) 0 >>> pari('2/3').cmp(pari('2/5')) -1 >>> two = pari('2.000000000000000000000000') >>> two.cmp(pari(1.0)) 1 >>> two.cmp(pari(2.0)) 1 >>> two.cmp(pari(3.0)) 1 >>> f = pari("0*ffgen(ffinit(29, 10))") >>> pari(0).cmp(f) -1 >>> pari("'x").cmp(f) 1 >>> pari("'x").cmp(0) Traceback (most recent call last): ... TypeError: Cannot convert int to cypari2.gen.Gen_base
- debug(depth)¶
Show the internal structure of self (like the
\x
command in gp).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('[1/2, 1 + 1.0*I]').debug() [&=...] VEC(lg=3):... 1st component = [&=...] FRAC(lg=3):... num = [&=...] INT(lg=3):... (+,lgefint=3):... den = [&=...] INT(lg=3):... (+,lgefint=3):... 2nd component = [&=...] COMPLEX(lg=3):... real = [&=...] INT(lg=3):... (+,lgefint=3):... imag = [&=...] REAL(lg=...):... (+,expo=0):...
- disc()¶
Return the discriminant of this object.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([0, -1, 1, -10, -20]).ellinit() >>> e.disc() -161051 >>> _.factor() [-1, 1; 11, 5]
- eint1(n, precision)¶
x.eint1(n): exponential integral E1(x):
\[\int_{x}^{\infty} \frac{e^{-t}}{t} dt\]If n is present, output the vector [eint1(x), eint1(2*x), …, eint1(n*x)]. This is faster than repeatedly calling eint1(i*x).
If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.
REFERENCE:
See page 262, Prop 5.6.12, of Cohen’s book “A Course in Computational Algebraic Number Theory”.
Examples:
- ellan(n, python_ints)¶
Return the first n Fourier coefficients of the modular form attached to this elliptic curve. See ellak for more details.
INPUT:
n
- a long integerpython_ints
- bool (default is False); if True, return a list of Python ints instead of a PARI Gen wrapper.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([0, -1, 1, -10, -20]).ellinit() >>> e.ellan(3) [1, -2, -1] >>> e.ellan(20) [1, -2, -1, 2, 1, 2, -2, 0, -2, -2, 1, -2, 4, 4, -1, -4, -2, 4, 0, 2] >>> e.ellan(-1) [] >>> v = e.ellan(10, python_ints=True); v [1, -2, -1, 2, 1, 2, -2, 0, -2, -2] >>> type(v) <... 'list'> >>> type(v[0]) <... 'int'>
- ellaplist(n, python_ints)¶
e.ellaplist(n): Returns a PARI list of all the prime-indexed coefficients a_p (up to n) of the L-function of the elliptic curve e, i.e. the Fourier coefficients of the newform attached to e.
INPUT:
self
– an elliptic curven
– a long integerpython_ints
– bool (default is False); if True, return a list of Python ints instead of a PARI Gen wrapper.
Warning
The curve e must be a medium or long vector of the type given by ellinit. For this function to work for every n and not just those prime to the conductor, e must be a minimal Weierstrass equation. If this is not the case, use the function ellminimalmodel first before using ellaplist (or you will get INCORRECT RESULTS!)
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([0, -1, 1, -10, -20]).ellinit() >>> v = e.ellaplist(10); v [-2, -1, 1, -2] >>> type(v) <... 'cypari2.gen.Gen'> >>> v.type() 't_VEC' >>> e.ellan(10) [1, -2, -1, 2, 1, 2, -2, 0, -2, -2] >>> v = e.ellaplist(10, python_ints=True); v [-2, -1, 1, -2] >>> type(v) <... 'list'> >>> type(v[0]) <... 'int'>
Tests:
>>> v = e.ellaplist(1) >>> v, type(v) ([], <... 'cypari2.gen.Gen'>) >>> v = e.ellaplist(1, python_ints=True) >>> v, type(v) ([], <... 'list'>)
- ellisoncurve(x)¶
e.ellisoncurve(x): return True if the point x is on the elliptic curve e, False otherwise.
If the point or the curve have inexact coefficients, an attempt is made to take this into account.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([0,1,1,-2,0]).ellinit() >>> e.ellisoncurve([1,0]) True >>> e.ellisoncurve([1,1]) False >>> e.ellisoncurve([1,0.00000000000000001]) False >>> e.ellisoncurve([1,0.000000000000000001]) True >>> e.ellisoncurve([0]) True
- ellminimalmodel()¶
ellminimalmodel(e): return the standard minimal integral model of the rational elliptic curve e and the corresponding change of variables. INPUT:
e
- Gen (that defines an elliptic curve)
OUTPUT:
gen
- minimal modelgen
- change of coordinates
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([1,2,3,4,5]).ellinit() >>> F, ch = e.ellminimalmodel() >>> F[:5] [1, -1, 0, 4, 3] >>> ch [1, -1, 0, -1] >>> e.ellchangecurve(ch)[:5] [1, -1, 0, 4, 3]
- elltors()¶
Return information about the torsion subgroup of the given elliptic curve.
INPUT:
e
- elliptic curve over QQ
OUTPUT:
gen
- the order of the torsion subgroup, a.k.a. the number of points of finite ordergen
- vector giving the structure of the torsion subgroup as a product of cyclic groups, sorted in non-increasing ordergen
- vector giving points on e generating these cyclic groups
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([1,0,1,-19,26]).ellinit() >>> e.elltors() [12, [6, 2], [[1, 2], [3, -2]]]
- ellwp(z, n, flag, precision)¶
Return the value or the series expansion of the Weierstrass P-function at z on the lattice self (or the lattice defined by the elliptic curve self).
INPUT:
self
– an elliptic curve created usingellinit
or a list[om1, om2]
representing generators for a lattice.z
– (default: ‘z’) a complex number or a variable name (as string or PARI variable).n
– (default: 20) if ‘z’ is a variable, compute the series expansion up to at least O(z^n).flag
– (default = 0): Ifflag
is 0, compute only P(z). Ifflag
is 1, compute [P(z), P’(z)].
OUTPUT:
- P(z) (if
flag
is 0) or [P(z), P’(z)] (ifflag
is 1). numbers
- P(z) (if
Examples:
We first define the elliptic curve X_0(11):
>>> from cypari2 import Pari >>> pari = Pari()
>>> E = pari([0,-1,1,-10,-20]).ellinit()
Compute P(1):
>>> E.ellwp(1) 13.9658695257485
Compute P(1+i), where i = sqrt(-1):
>>> E.ellwp(pari(complex(1, 1))) -1.11510682565555 + 2.33419052307470*I >>> E.ellwp(complex(1, 1)) -1.11510682565555 + 2.33419052307470*I
The series expansion, to the default O(z^20) precision:
>>> 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:
>>> 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:
>>> pari([1.2692, complex(0.63, 1.45)]).ellwp(1) 13.9656146936689 + 0.000644829272810...*I
With flag=1, compute the pair P(z) and P’(z):
>>> E.ellwp(1, flag=1) [13.9658695257485, 101.123860176015]
- eval(*args, **kwds)¶
Evaluate
self
with the given arguments.This is currently implemented in 3 cases:
univariate polynomials, rational functions, power series and Laurent series (using a single unnamed argument or keyword arguments),
any PARI object supporting the PARI function pari:substvec (in particular, multivariate polynomials) using keyword arguments,
objects of type
t_CLOSURE
(functions in GP bytecode form) using unnamed arguments.
In no case is mixing unnamed and keyword arguments allowed.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> f = pari('x^2 + 1') >>> f.type() 't_POL' >>> f.eval(pari('I')) 0 >>> f.eval(x=2) 5 >>> (1/f).eval(x=1) 1/2
The notation
f(x)
is an alternative forf.eval(x)
:>>> f(3) == f.eval(3) True
>>> f = pari('Mod(x^2 + x + 1, 3)') >>> f(2) Mod(1, 3)
Evaluating a power series:
>>> f = pari('1 + x + x^3 + O(x^7)') >>> 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:
>>> pari('1 + O(x^3)').eval(0) 1 >>> pari('1/x').eval(0) Traceback (most recent call last): ... PariError: impossible inverse in gdiv: 0 >>> pari('1/x + O(x^2)').eval(0) Traceback (most recent call last): ... PariError: impossible inverse in gsubst: 0 >>> pari('1/x + O(x^2)').eval(pari('O(x^3)')) Traceback (most recent call last): ... PariError: impossible inverse in ... >>> pari('O(x^0)').eval(0) Traceback (most recent call last): ... PariError: forbidden substitution t_SER , t_INT
Evaluating multivariate polynomials:
>>> f = pari('y^2 + x^3') >>> f(1) # Dangerous, depends on PARI variable ordering y^2 + 1 >>> f(x=1) # Safe y^2 + 1 >>> f(y=1) x^3 + 1 >>> f(1, 2) Traceback (most recent call last): ... TypeError: evaluating PARI t_POL takes exactly 1 argument (2 given) >>> f(y='x', x='2*y') x^2 + 8*y^3 >>> f() x^3 + y^2
It’s not an error to substitute variables which do not appear:
>>> f.eval(z=37) x^3 + y^2 >>> pari(42).eval(t=0) 42
We can define and evaluate closures as follows:
>>> T = pari('n -> n + 2') >>> T.type() 't_CLOSURE' >>> T.eval(3) 5
>>> T = pari('() -> 42') >>> T() 42
>>> pr = pari('s -> print(s)') >>> pr.eval('"hello world"') hello world
>>> f = pari('myfunc(x,y) = x*y') >>> f.eval(5, 6) 30
Default arguments work, missing arguments are treated as zero (like in GP):
>>> f = pari("(x, y, z=1.0) -> [x, y, z]") >>> f(1, 2, 3) [1, 2, 3] >>> f(1, 2) [1, 2, 1.00000000000000] >>> f(1) [1, 0, 1.00000000000000] >>> f() [0, 0, 1.00000000000000]
Variadic closures are supported as well (Sage ticket #18623):
>>> f = pari("(v[..])->length(v)") >>> f('a', f) 2 >>> g = pari("(x,y,z[..])->[x,y,z]") >>> 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:
>>> nf = pari('x^2 + 1').nfinit() >>> nf [x^2 + 1, [0, 1], -4, 1, [Mat([1, 0.E-38 + 1.00000000000000*I]), [1, 1.00000000000000; 1, -1.00000000000000], ..., [2, 0; 0, -2], [2, 0; 0, 2], [1, 0; 0, -1], [1, [0, -1; 1, 0]], [2]], [0.E-38 + 1.00000000000000*I], [1, x], [1, 0; 0, 1], [1, 0, 0, -1; 0, 1, 1, 0]] >>> nf(x='y') [y^2 + 1, [0, 1], -4, 1, [Mat([1, 0.E-38 + 1.00000000000000*I]), [1, 1.00000000000000; 1, -1.00000000000000], ..., [2, 0; 0, -2], [2, 0; 0, 2], [1, 0; 0, -1], [1, [0, -1; 1, 0]], [2]], [0.E-38 + 1.00000000000000*I], [1, y], [1, 0; 0, 1], [1, 0, 0, -1; 0, 1, 1, 0]]
Tests:
>>> T = pari('n -> 1/n') >>> T.type() 't_CLOSURE' >>> T(0) Traceback (most recent call last): ... PariError: _/_: impossible inverse in gdiv: 0 >>> pari('() -> 42')(1,2,3) Traceback (most recent call last): ... PariError: too many parameters in user-defined function call >>> pari('n -> n')(n=2) Traceback (most recent call last): ... TypeError: cannot evaluate a PARI closure using keyword arguments >>> pari('x + y')(4, y=1) Traceback (most recent call last): ... TypeError: mixing unnamed and keyword arguments not allowed when evaluating a PARI object >>> pari("12345")(4) Traceback (most recent call last): ... TypeError: cannot evaluate PARI t_INT using unnamed arguments
- factor(limit, proof)¶
Return the factorization of x.
INPUT:
limit
– (default: -1) is optional and can be set whenever x is of (possibly recursive) rational type. If limit is set, return partial factorization, using primes up to limit.proof
– optional flag. IfFalse
(not the default), returned factors larger than 2^{64} may only be pseudoprimes. IfTrue
, always check primality. If not given, use the global PARI defaultfactor_proven
which isTrue
by default in cypari.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> 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] >>> 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] >>> pari(2**100-1).factor(proof=True) [3, 1; 5, 3; 11, 1; 31, 1; 41, 1; 101, 1; 251, 1; 601, 1; 1801, 1; 4051, 1; 8101, 1; 268501, 1] >>> 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:
>>> pari(pari(10**50).nextprime()*pari(10**60).nextprime()*pari(10**4).nextprime()).factor(10**5) [10007, 1; 100000000000000000000000000000000000000000000000151000000000700000000000000000000000000000000000000000000001057, 1]
Setting a limit is invalid when factoring polynomials:
>>> pari('x^11 + 1').factor(limit=17) Traceback (most recent call last): ... PariError: incorrect type in boundfact (t_POL)
- factorpadic(p, r)¶
p-adic factorization of the polynomial
pol
to precisionr
.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pol = pari('x^2 - 1')**2 >>> 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] >>> 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]
- ffprimroot()¶
Return a primitive root of the multiplicative group of the definition field of the given finite field element.
INPUT:
self
– a PARI finite field element (FFELT
)
OUTPUT:
A generator of the multiplicative group of the finite field generated by
self
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> b = pari(9).ffgen().ffprimroot() >>> b.fforder() 8
- fibonacci()¶
Return the Fibonacci number of index x.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(18).fibonacci() 2584 >>> [pari(n).fibonacci() for n in range(10)] [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
- galoissubfields(flag, v)¶
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 bygaloissubgroups()
.INPUT:
self
– A Galois group as generated bygaloisinit()
.flag
– Has the same meaning as ingaloisfixedfield()
.v
– Has the same meaning as ingaloisfixedfield()
.
OUTPUT:
A vector of all subfields of this group. Each entry is as described in the
galoisfixedfield()
method.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> G = pari('x^6 + 108').galoisinit() >>> G.galoissubfields(flag=1) [x, x^2 + 972, x^3 + 54, x^3 + 864, x^3 - 54, x^6 + 108] >>> G = pari('x^4 + 1').galoisinit() >>> G.galoissubfields(flag=2, v='z')[3] [...^2 + 2, Mod(x^3 + x, x^4 + 1), [x^2 - z*x - 1, x^2 + z*x - 1]]
- gequal(b)¶
Check whether a and b are equal using PARI’s
gequal
.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> a = pari(1); b = pari(1.0); c = pari('"some_string"') >>> a.gequal(a) True >>> b.gequal(b) True >>> c.gequal(c) True >>> a.gequal(b) True >>> a.gequal(c) False
WARNING: this relation is not transitive:
>>> a = pari('[0]'); b = pari(0); c = pari('[0,0]') >>> a.gequal(b) True >>> b.gequal(c) True >>> a.gequal(c) False
- gequal0()¶
Check whether a is equal to zero.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(0).gequal0() True >>> pari(1).gequal0() False >>> pari(1e-100).gequal0() False >>> pari("0.0 + 0.0*I").gequal0() True >>> (pari('ffgen(3^20)')*0).gequal0() True
- gequal_long(b)¶
Check whether a is equal to the
long int
b using PARI’sgequalsg
.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> a = pari(1); b = pari(2.0); c = pari('3*matid(3)') >>> a.gequal_long(1) True >>> a.gequal_long(-1) False >>> a.gequal_long(0) False >>> b.gequal_long(2) True >>> b.gequal_long(-2) False >>> c.gequal_long(3) True >>> c.gequal_long(-3) False
- getattr(attr)¶
Return the PARI attribute with the given name.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> K = pari("nfinit(x^2 - x - 1)") >>> K.getattr("pol") x^2 - x - 1 >>> K.getattr("disc") 5
>>> K.getattr("reg") Traceback (most recent call last): ... PariError: _.reg: incorrect type in reg (t_VEC) >>> K.getattr("zzz") Traceback (most recent call last): ... PariError: not a function in function call
- idealmoddivisor(ideal)¶
Return a ‘small’ ideal equivalent to
ideal
in the ray class group that the bnr structureself
encodes.INPUT:
self
– a bnr structure as outputted from bnrinit.ideal
– an ideal in the underlying number field of the bnr structure.
OUTPUT: An ideal representing the same ray class as
ideal
but with ‘small’ generators. Ifideal
is not coprime to the modulus of the bnr, this results in an error.Examples:
>>> from cypari2 import Pari >>> pari = Pari() >>> i = pari('i') >>> K = (i**4 - 2).bnfinit() >>> R = K.bnrinit(5,1) >>> R.idealmoddivisor(K[6][6][1]) [2, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1] >>> R.idealmoddivisor(K.idealhnf(5)) Traceback (most recent call last): ... PariError: elements not coprime in idealaddtoone: [5, 0, 0, 0; 0, 5, 0, 0; 0, 0, 5, 0; 0, 0, 0, 5] [5, 0, 0, 0; 0, 5, 0, 0; 0, 0, 5, 0; 0, 0, 0, 5]
- ispower(k)¶
Determine whether or not self is a perfect k-th power. If k is not specified, find the largest k so that self is a k-th power.
INPUT:
k
- int (optional)
OUTPUT:
power
- int, what power it isg
- what it is a power of
Examples:
>>> from cypari2 import Pari >>> pari = Pari() >>> pari(9).ispower() (2, 3) >>> pari(17).ispower() (1, 17) >>> pari(17).ispower(2) (False, None) >>> pari(17).ispower(1) (1, 17) >>> pari(2).ispower() (1, 2)
- isprime(flag)¶
Return True if x is a PROVEN prime number, and False otherwise.
INPUT:
flag
– If flag is 0 or omitted, use a combination of algorithms. If flag is 1, the primality is certified by the Pocklington-Lehmer Test. If flag is 2, the primality is certified using the APRCL test. If flag is 3, use ECPP.
OUTPUT: bool
Examples:
>>> from cypari2 import Pari >>> pari = Pari() >>> pari(9).isprime() False >>> pari(17).isprime() True >>> n = pari(561) # smallest Carmichael number >>> n.isprime() # not just a pseudo-primality test! False >>> n.isprime(1) False >>> n.isprime(2) False >>> n = pari(2**31-1) >>> n.isprime(1) True
- isprimepower()¶
Check whether
self
is a prime power (with an exponent >= 1).INPUT:
self
- A PARI integer
OUTPUT:
A tuple
(k, p)
where k is a Python integer and p a PARI integer.If the input was a prime power, p is the prime and k the power.
Otherwise, k = 0 and p is
self
.
See also
If you don’t need a proof that p is prime, you can use
ispseudoprimepower()
instead.Examples:
>>> from cypari2 import Pari >>> pari = Pari() >>> pari(9).isprimepower() (2, 3) >>> pari(17).isprimepower() (1, 17) >>> pari(18).isprimepower() (0, 18) >>> pari(3**12345).isprimepower() (12345, 3)
- ispseudoprime(flag)¶
ispseudoprime(x, flag=0): Returns True if x is a pseudo-prime number, and False otherwise.
INPUT:
flag
- int 0 (default): checks whether x is a Baillie-Pomerance-Selfridge-Wagstaff pseudo prime (strong Rabin-Miller pseudo prime for base 2, followed by strong Lucas test for the sequence (P,-1), P smallest positive integer such that P^2 - 4 is not a square mod x). 0: checks whether x is a strong Miller-Rabin pseudo prime for flag randomly chosen bases (with end-matching to catch square roots of -1).
OUTPUT:
bool
- True or False, or when flag=1, either False or a tuple (True, cert) wherecert
is a primality certificate.
Examples:
>>> from cypari2 import Pari >>> pari = Pari() >>> pari(9).ispseudoprime() False >>> pari(17).ispseudoprime() True >>> n = pari(561) # smallest Carmichael number >>> n.ispseudoprime(2) False
- ispseudoprimepower()¶
Check whether
self
is the power (with an exponent >= 1) of a pseudo-prime.INPUT:
self
- A PARI integer
OUTPUT:
A tuple
(k, p)
where k is a Python integer and p a PARI integer.If the input was a pseudoprime power, p is the pseudoprime and k the power.
Otherwise, k = 0 and p is
self
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(3**12345).ispseudoprimepower() (12345, 3) >>> p = pari(2**1500 + 1465) # nextprime(2^1500) >>> (p**11).ispseudoprimepower()[0] # very fast 11
- issquare(find_root)¶
issquare(x,n):
True
if x is a square,False
if not. Iffind_root
is given, also returns the exact square root.
- issquarefree()¶
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(10).issquarefree() True >>> pari(20).issquarefree() False
- j()¶
Return the j-invariant of this object.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([0, -1, 1, -10, -20]).ellinit() >>> e.j() -122023936/161051 >>> _.factor() [-1, 1; 2, 12; 11, -5; 31, 3]
- lift_centered(v)¶
Same as
lift
, except thatt_INTMOD
andt_PADIC
components are lifted using centered residues:for a
t_INTMOD
\(x\in \mathbb{Z}/n\mathbb{Z}\), the lift \(y\) is such that \(-n/2 < y <= n/2\).a
t_PADIC
\(x\) is lifted in the same way as above (modulo \(p^padicprec(x)\)) if its valuation \(v\) is nonnegative; if not, returns the fraction \(p^v\)centerlift
\((x p^{-v})\); in particular, rational reconstruction is not attempted. Usebestappr
for this.
For backward compatibility,
centerlift(x,'v)
is allowed as an alias forlift(x,'v)
.
- list()¶
Convert
self
to a Python list withGen
components.Examples:
A PARI vector becomes a Python list:
>>> from cypari2 import Pari >>> pari = Pari()
>>> L = pari("vector(10,i,i^2)").list() >>> L [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>> type(L) <... 'list'> >>> type(L[0]) <... 'cypari2.gen.Gen'>
For polynomials, list() returns the list of coefficients:
>>> 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:
>>> pari('x^2 + O(x^8)').list() [1, 0, 0, 0, 0, 0] >>> pari('x^-2 + O(x^0)').list() [1, 0]
For matrices, we get a list of columns:
>>> M = pari.matrix(3,2,[1,4,2,5,3,6]); M [1, 4; 2, 5; 3, 6] >>> M.list() [[1, 2, 3]~, [4, 5, 6]~]
- log_gamma(precision)¶
Principal branch of the logarithm of the gamma function of \(x\). This function is analytic on the complex plane with nonpositive 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
- matkerint(flag)¶
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:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('[2,1;2,1]').matkerint() [1; -2] >>> import warnings >>> with warnings.catch_warnings(record=True) as w: ... warnings.simplefilter('always') ... pari('[2,1;2,1]').matkerint(1) ... assert len(w) == 1 ... assert issubclass(w[0].category, DeprecationWarning) [1; -2]
- mattranspose()¶
Transpose of the matrix self.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('[1,2,3; 4,5,6; 7,8,9]').mattranspose() [1, 4, 7; 2, 5, 8; 3, 6, 9]
Unlike PARI, this always returns a matrix:
>>> pari('[1,2,3]').mattranspose() [1; 2; 3] >>> pari('[1,2,3]~').mattranspose() Mat([1, 2, 3])
- mod()¶
Given an INTMOD or POLMOD
Mod(a,m)
, return the modulus m.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(4).Mod(5).mod() 5 >>> pari("Mod(x, x*y)").mod() y*x >>> pari("[Mod(4,5)]").mod() Traceback (most recent call last): ... TypeError: Not an INTMOD or POLMOD in mod()
- multiplicative_order(o)¶
\(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 nonzero multiple of the order of \(x\), see
DLfun
(in the PARI manual); the preferred format for this parameter is[ord, factor(ord)]
, whereord = eulerphi(n)
is the cardinality of the group.
- ncols()¶
Return the number of columns of self.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('matrix(19,8)').ncols() 8
- nextprime(add_one)¶
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:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(1).nextprime() 2 >>> pari(2).nextprime() 2 >>> pari(2).nextprime(add_one = 1) 3 >>> pari(2**100).nextprime() 1267650600228229401496703205653
- nf_get_diff()¶
Returns the different of this number field as a PARI ideal.
INPUT:
self
– A PARI number field being the output ofnfinit()
,bnfinit()
orbnrinit()
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**4 - 4*x**2 + 1).nfinit() >>> K.nf_get_diff() [12, 0, 0, 0; 0, 12, 8, 0; 0, 0, 4, 0; 0, 0, 0, 4]
- nf_get_pol()¶
Returns the defining polynomial of this number field.
INPUT:
self
– A PARI number field being the output ofnfinit()
,bnfinit()
orbnrinit()
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**4 - 4*x**2 + 1).bnfinit() >>> bnr = K.bnrinit(2*x) >>> bnr.nf_get_pol() x^4 - 4*x^2 + 1
For relative number fields, this returns the relative polynomial:
>>> y = pari.varhigher('y') >>> L = K.rnfinit(y**2 - 5) >>> L.nf_get_pol() y^2 - 5
An error is raised for invalid input:
>>> pari("[0]").nf_get_pol() Traceback (most recent call last): ... PariError: incorrect type in pol (t_VEC)
- nf_get_sign()¶
Returns a Python list
[r1, r2]
, wherer1
andr2
are Python ints representing the number of real embeddings and pairs of complex embeddings of this number field, respectively.INPUT:
self
– A PARI number field being the output ofnfinit()
,bnfinit()
orbnrinit()
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**4 - 4*x**2 + 1).nfinit() >>> s = K.nf_get_sign(); s [4, 0] >>> type(s); type(s[0]) <... 'list'> <... 'int'> >>> pari.polcyclo(15).nfinit().nf_get_sign() [0, 4]
- nf_get_zk()¶
Returns a vector with a ZZ-basis for the ring of integers of this number field. The first element is always 1.
INPUT:
self
– A PARI number field being the output ofnfinit()
,bnfinit()
orbnrinit()
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> x = pari('x') >>> K = (x**4 - 4*x**2 + 1).nfinit() >>> K.nf_get_zk() [1, x, x^3 - 4*x, x^2 - 2]
- nf_subst(z)¶
Given a PARI number field
self
, return the same PARI number field but in the variablez
.INPUT:
self
– A PARI number field being the output ofnfinit()
,bnfinit()
orbnrinit()
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> K = pari('y^2 + 5').nfinit()
We can substitute in a PARI
nf
structure:>>> K.nf_get_pol() y^2 + 5 >>> L = K.nf_subst('a') >>> L.nf_get_pol() a^2 + 5
We can also substitute in a PARI
bnf
structure:>>> K = pari('y^2 + 5').bnfinit() >>> K.nf_get_pol() y^2 + 5 >>> K.bnf_get_cyc() # Structure of class group [2] >>> L = K.nf_subst('a') >>> L.nf_get_pol() a^2 + 5 >>> L.bnf_get_cyc() # We still have a bnf after substituting [2]
- nfbasis(flag, fa)¶
Integral basis of the field QQ[a], where
a
is a root of the polynomial x.INPUT:
flag
: if set to 1 andfa
is not given: assume that no square of a prime > 500000 divides the discriminant ofx
.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
.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> 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:>>> p = pari(10**10).nextprime(); q = (p+1).nextprime() >>> x = pari('x'); f = x**2 + p**2*q >>> pari(f).nfbasis(1) # Wrong result [1, x] >>> pari(f).nfbasis() # Correct result [1, 1/10000000019*x] >>> pari(f).nfbasis(fa=10**6) # Check primes up to 10^6: wrong result [1, x] >>> pari(f).nfbasis(fa="[2,2; %s,2]"%p) # Correct result and faster [1, 1/10000000019*x] >>> pari(f).nfbasis(fa=[2,p]) # Equivalent with the above [1, 1/10000000019*x]
The following alternative syntax closer to PARI/GP can be used
>>> pari.nfbasis([f, 1]) [1, x] >>> pari.nfbasis(f) [1, 1/10000000019*x] >>> pari.nfbasis([f, 10**6]) [1, x] >>> pari.nfbasis([f, "[2,2; %s,2]"%p]) [1, 1/10000000019*x] >>> pari.nfbasis([f, [2,p]]) [1, 1/10000000019*x]
- nfbasis_d(flag, fa)¶
Like
nfbasis()
, but return a tuple(B, D)
where B is the integral basis and D the discriminant.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> F = pari('x^3 - 2').nfinit() >>> F[0].nfbasis_d() ([1, x, x^2], -108)
>>> G = pari('x^5 - 11').nfinit() >>> G[0].nfbasis_d() ([1, x, x^2, x^3, x^4], 45753125)
>>> pari([-2,0,0,1]).Polrev().nfbasis_d() ([1, x, x^2], -108)
- nfbasistoalg_lift(x)¶
Transforms the column vector
x
on the integral basis into a polynomial representing the algebraic number.INPUT:
nf
– a number fieldx
– a column of rational numbers of length equal to the degree ofnf
or a single rational number
OUTPUT:
nf.nfbasistoalg(x).lift()
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> K = pari('x^3 - 17').nfinit() >>> K.nf_get_zk() [1, 1/3*x^2 - 1/3*x + 1/3, x] >>> K.nfbasistoalg_lift(42) 42 >>> K.nfbasistoalg_lift("[3/2, -5, 0]~") -5/3*x^2 + 5/3*x - 1/6 >>> K.nf_get_zk() * pari("[3/2, -5, 0]~") -5/3*x^2 + 5/3*x - 1/6
- nfeltval(x, p)¶
Return the valuation of the number field element x at the prime p.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> nf = pari('x^2 + 1').nfinit() >>> p = nf.idealprimedec(5)[0] >>> nf.nfeltval('50 - 25*x', p) 3
- nrows()¶
Return the number of rows of self.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('matrix(19,8)').nrows() 19
- omega()¶
Return the basis for the period lattice of this elliptic curve.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> e = pari([0, -1, 1, -10, -20]).ellinit() >>> e.omega() [1.26920930427955, 0.634604652139777 - 1.45881661693850*I]
The precision is determined by the
ellinit
call:>>> e = pari([0, -1, 1, -10, -20]).ellinit(precision=256) >>> e.omega().bitprecision() 256
This also works over quadratic imaginary number fields:
>>> e = pari.ellinit([0, -1, 1, -10, -20], "nfinit(y^2 - 2)") >>> if pari.version() >= (2, 10, 1): ... w = e.omega()
- padicprime()¶
The uniformizer of the p-adic ring this element lies in, as a t_INT.
INPUT:
x
- gen, of type t_PADIC
OUTPUT:
p
- gen, of type t_INT
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> y = pari('11^-10 + 5*11^-7 + 11^-6 + O(11)') >>> y.padicprime() 11 >>> y.padicprime().type() 't_INT'
- polinterpolate(ya, x)¶
self.polinterpolate(ya,x,e): polynomial interpolation at x according to data vectors self, ya (i.e. return P such that P(self[i]) = ya[i] for all i). Also return an error estimate on the returned value.
- polred(*args, **kwds)¶
This function is deprecated, use
polredbest()
instead.
- polylog(m, flag, precision)¶
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:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(10).polylog(3) 5.64181141475134 - 8.32820207698027*I >>> pari(10).polylog(3,0) 5.64181141475134 - 8.32820207698027*I >>> pari(10).polylog(3,1) 0.523778453502411 >>> pari(10).polylog(3,2) -0.400459056163451
- pr_get_e()¶
Returns the ramification index (over QQ) of this prime ideal.
NOTE:
self
must be a PARI prime ideal (as returned byidealprimedec
for example).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> i = pari('i') >>> K = (i**2 + 1).nfinit() >>> K.idealprimedec(2)[0].pr_get_e() 2 >>> K.idealprimedec(3)[0].pr_get_e() 1 >>> K.idealprimedec(5)[0].pr_get_e() 1
- pr_get_f()¶
Returns the residue class degree (over QQ) of this prime ideal.
NOTE:
self
must be a PARI prime ideal (as returned byidealprimedec
for example).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> i = pari('i') >>> K = (i**2 + 1).nfinit() >>> K.idealprimedec(2)[0].pr_get_f() 1 >>> K.idealprimedec(3)[0].pr_get_f() 2 >>> K.idealprimedec(5)[0].pr_get_f() 1
- pr_get_gen()¶
Returns the second generator of this PARI prime ideal, where the first generator is
self.pr_get_p()
.NOTE:
self
must be a PARI prime ideal (as returned byidealprimedec
for example).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> i = pari('i') >>> K = (i**2 + 1).nfinit() >>> g = K.idealprimedec(2)[0].pr_get_gen(); g [1, 1]~ >>> g = K.idealprimedec(3)[0].pr_get_gen(); g [3, 0]~ >>> g = K.idealprimedec(5)[0].pr_get_gen(); g [-2, 1]~
- pr_get_p()¶
Returns the prime of ZZ lying below this prime ideal.
NOTE:
self
must be a PARI prime ideal (as returned byidealprimedec
for example).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> i = pari('i') >>> K = (i**2 + 1).nfinit() >>> F = K.idealprimedec(5); F [[5, [-2, 1]~, 1, 1, [2, -1; 1, 2]], [5, [2, 1]~, 1, 1, [-2, -1; 1, -2]]] >>> F[0].pr_get_p() 5
- python()¶
Return the closest Python equivalent of the given PARI object.
See
gen_to_python()
for more informations.Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('1.2').python() 1.2 >>> pari('389/17').python() Fraction(389, 17)
- python_list()¶
Return a Python list of the PARI gens. This object must be of type t_VEC or t_COL.
INPUT: None
OUTPUT:
list
- Python list whose elements are the elements of the input gen.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> v = pari([1,2,3,10,102,10]) >>> w = v.python_list() >>> w [1, 2, 3, 10, 102, 10] >>> type(w[0]) <... 'cypari2.gen.Gen'> >>> pari("[1,2,3]").python_list() [1, 2, 3]
>>> pari("[1,2,3]~").python_list() [1, 2, 3]
- python_list_small()¶
Return a Python list of the PARI gens. This object must be of type t_VECSMALL, and the resulting list contains python ‘int’s.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> v=pari([1,2,3,10,102,10]).Vecsmall() >>> w = v.python_list_small() >>> w [1, 2, 3, 10, 102, 10] >>> type(w[0]) <... 'int'>
- qfrep(B, flag)¶
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 at_VECSMALL
instead of at_VEC
(which is faster).Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> M = pari("[5,1,1;1,3,1;1,1,1]") >>> M.qfrep(20) [1, 1, 2, 2, 2, 4, 4, 3, 3, 4, 2, 4, 6, 0, 4, 6, 4, 5, 6, 4] >>> 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] >>> 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])
- round(estimate)¶
round(x,estimate=False): If x is a real number, returns x rounded to the nearest integer (rounding up). If the optional argument estimate is True, also returns the binary exponent e of the difference between the original and the rounded value (the “fractional part”) (this is the integer ceiling of log_2(error)).
When x is a general PARI object, this function returns the result of rounding every coefficient at every level of PARI object. Note that this is different than what the truncate function does (see the example below).
One use of round is to get exact results after a long approximate computation, when theory tells you that the coefficients must be integers.
INPUT:
x
- genestimate
- (optional) bool, False by default
OUTPUT:
if estimate is False, return a single gen.
if estimate is True, return rounded version of x and error estimate in bits, both as gens.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('1.5').round() 2 >>> pari('1.5').round(True) (2, -1) >>> pari('1.5 + 2.1*I').round() 2 + 2*I >>> pari('1.0001').round(True) (1, -14) >>> pari('(2.4*x^2 - 1.7)/x').round() (2*x^2 - 2)/x >>> pari('(2.4*x^2 - 1.7)/x').truncate() 2.40000000000000*x
- sage(locals)¶
Return the closest SageMath equivalent of the given PARI object.
INPUT:
locals
– optional dictionary used in fallback cases that involvesage_eval
See
gen_to_sage()
for more information.
- sizebyte()¶
Return the total number of bytes occupied by the complete tree of the object x. Note that this number depends on whether the computer is 32-bit or 64-bit.
INPUT:
x
- gen
OUTPUT: int (a Python int)
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> import sys >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' >>> pari('1').sizebyte() == (12 if bitness == '32' else 24) True
- sizeword()¶
Return the total number of machine words occupied by the complete tree of the object x. A machine word is 32 or 64 bits, depending on the computer.
INPUT:
x
- gen
OUTPUT: int (a Python int)
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('0').sizeword() 2 >>> pari('1').sizeword() 3 >>> pari('1000000').sizeword() 3
>>> import sys >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' >>> pari('10^100').sizeword() == (13 if bitness == '32' else 8) True >>> pari(1.0).sizeword() == (4 if bitness == '32' else 3) True
>>> pari('x + 1').sizeword() 10 >>> pari('[x + 1, 1]').sizeword() 16
- sqrtn(n, precision)¶
x.sqrtn(n): return the principal branch of the n-th root of x, i.e., the one such that arg(sqrt(x)) in ]-pi/n, pi/n]. Also returns a second argument which is a suitable root of unity allowing one to recover all the other roots. If it was not possible to find such a number, then this second return value is 0. If the argument is present and no square root exists, return 0 instead of raising an error.
If x is an exact argument, it is first converted to a real or complex number using the optional parameter precision (in bits). If x is inexact (e.g. real), its own precision is used in the computation, and the parameter precision is ignored.
Note
intmods (modulo a prime) and p-adic numbers are allowed as arguments.
INPUT:
x
- genn
- integer
OUTPUT:
gen
- principal n-th root of xgen
- root of unity z that gives the other roots
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> s, z = pari(2).sqrtn(5) >>> z 0.309016994374947 + 0.951056516295154*I >>> s 1.14869835499704 >>> s**5 2.00000000000000 >>> (s*z)**5 2.00000000000000 + 0.E-19*I
>>> import sys >>> bitness = '64' if sys.maxsize > (1 << 32) else '32' >>> s = str(z**5) >>> s == ('1.00000000000000 - 2.710505431 E-20*I' if bitness == '32' else '1.00000000000000 - 2.71050543121376 E-20*I') True
- sumdiv()¶
Return the sum of the divisors of n.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(10).sumdiv() 18
- sumdivk(k)¶
Return the sum of the k-th powers of the divisors of n.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(10).sumdivk(2) 130
- truncate(estimate)¶
truncate(x,estimate=False): Return the truncation of x. If estimate is True, also return the number of error bits.
When x is in the real numbers, this means that the part after the decimal point is chopped away, e is the binary exponent of the difference between the original and truncated value (the “fractional part”). If x is a rational function, the result is the integer part (Euclidean quotient of numerator by denominator) and if requested the error estimate is 0.
When truncate is applied to a power series (in X), it transforms it into a polynomial or a rational function with denominator a power of X, by chopping away the O(X^k). Similarly, when applied to a p-adic number, it transforms it into an integer or a rational number by chopping away the O(p^k).
INPUT:
x
- genestimate
- (optional) bool, which is False by default
OUTPUT:
if estimate is False, return a single gen.
if estimate is True, return rounded version of x and error estimate in bits, both as gens.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari('(x^2+1)/x').round() (x^2 + 1)/x >>> pari('(x^2+1)/x').truncate() x >>> pari('1.043').truncate() 1 >>> pari('1.043').truncate(True) (1, -5) >>> pari('1.6').truncate() 1 >>> pari('1.6').round() 2 >>> pari('1/3 + 2 + 3^2 + O(3^3)').truncate() 34/3 >>> pari('sin(x+O(x^10))').truncate() 1/362880*x^9 - 1/5040*x^7 + 1/120*x^5 - 1/6*x^3 + x >>> pari('sin(x+O(x^10))').round() # each coefficient has abs < 1 x + O(x^10)
- type()¶
Return the PARI type of self as a string.
Note
In Cython, it is much faster to simply use typ(self.g) for checking PARI types.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari(7).type() 't_INT' >>> pari('x').type() 't_POL' >>> pari('oo').type() 't_INFINITY'
- vecmax()¶
Return the maximum of the elements of the vector/matrix x.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari([1, '-5/3', 8.0]).vecmax() 8.00000000000000
- vecmin()¶
Return the minimum of the elements of the vector/matrix x.
Examples:
>>> from cypari2 import Pari >>> pari = Pari()
>>> pari([1, '-5/3', 8.0]).vecmin() -5/3
- class cypari2.gen.Gen_base¶
Wrapper for a PARI
GEN
containing auto-generated methods.This class does not manage the
GEN
inside in any way. It is just a dumb wrapper. In particular, it might be invalid if theGEN
is on the PARI stack and the PARI stack has been garbage collected.You almost certainly want to use one of the derived class
Gen
instead. That being said,Gen_base
can be used by itself to pass around a temporaryGEN
within Python where we cannot use C calls.- Col(n)¶
Transforms the object \(x\) into a column vector. The dimension of the resulting vector can be optionally specified via the extra parameter \(n\).
If \(n\) is omitted or \(0\), the dimension depends on the type of \(x\); the vector has a single component, except when \(x\) is
a vector or a quadratic form (in which case the resulting vector is simply the initial object considered as a row vector),
a polynomial or a power series. In the case of a polynomial, the coefficients of the vector start with the leading coefficient of the polynomial, while for power series only the significant coefficients are taken into account, but this time by increasing order of degree. In this last case,
Vec
is the reciprocal function ofPol
andSer
respectively,a matrix (the column of row vector comprising the matrix is returned),
a character string (a vector of individual characters is returned).
In the last two cases (matrix and character string), \(n\) is meaningless and must be omitted or an error is raised. Otherwise, if \(n\) is given, \(0\) entries are appended at the end of the vector if \(n > 0\), and prepended at the beginning if \(n < 0\). The dimension of the resulting vector is \(\|n\|\).
See ??Vec for examples.
- Colrev(n)¶
As \(Col (x, -n)\), then reverse the result. In particular,
Colrev
is the reciprocal function ofPolrev
: the coefficients of the vector start with the constant coefficient of the polynomial and the others follow by increasing degree.
- List()¶
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\).
- Map()¶
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, creates an empty map, which may be filled later via
mapput
.
- Mat()¶
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 attached big matrix is returned. If \(x\) is a binary quadratic form, creates the attached \(2 x 2\) matrix. Otherwise, this creates a \(1 x 1\) matrix containing \(x\).
? Mat(x + 1) %1 = [x + 1] ? Vec( matid(3) ) %2 = [[1, 0, 0]~, [0, 1, 0]~, [0, 0, 1]~] ? Mat(%) %3 = [1 0 0] [0 1 0] [0 0 1] ? Col( [1,2; 3,4] ) %4 = [[1, 2], [3, 4]]~ ? Mat(%) %5 = [1 2] [3 4] ? Mat(Qfb(1,2,3)) %6 = [1 1] [1 3]
- Mod(b)¶
In its basic form, create an intmod or a polmod \((a mod b)\); \(b\) must be an integer or a polynomial. We then obtain a
t_INTMOD
and at_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(-x, 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 %11 = 5 ? x = Mod(4,5); x + 1 %12 = Mod(0,5)
Note that such “modular” objects can be lifted via
lift
orcenterlift
. The modulus of at_INTMOD
ort_POLMOD
\(z\) can be recovered via:math:`z
.mod`.
- Pol(v)¶
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 nonnegative 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
) isVec
(resp.Vecrev
).? Vec(Pol([1,2,3])) %1 = [1, 2, 3] ? Vecrev( Polrev([1,2,3]) ) %2 = [1, 2, 3]
Warning. This is not a substitution function. It will not transform an object containing variables of higher priority than \(v\).
? Pol(x + y, y) *** at top-level: Pol(x+y,y) *** ^---------- *** Pol: variable must have higher priority in gtopoly.
- Polrev(v)¶
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
) isVec
(resp.Vecrev
).
- Qfb(b, c, D, precision)¶
Creates the binary quadratic form \(ax^2+bxy+cy^2\). If \(b^2-4ac > 0\), initialize Shanks’ distance function to \(D\). Negative definite forms are not implemented, use their positive definite counterpart instead.
- Ser(v, d, serprec)¶
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? \ps seriesprecision = 16 significant terms ? Ser(1) \\ 16 terms by default %1 = 1 + O(x^16) ? Ser(1, 'y, 5) %2 = 1 + O(y^5) ? Ser(x^2,, 5) %3 = x^2 + O(x^7) ? T = polcyclo(100) %4 = x^40 - x^30 + x^20 - x^10 + 1 ? Ser(T, 'x, 11) %5 = 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.
For the remaining types, vectors and power series, we first explain what occurs if \(d\) is omitted. In this case, the function uses exactly the amount of information given in the input:
If \(s\) is already a power series in \(v\), we return it verbatim;
If \(s\) is a vector, the coefficients of the vector are understood to be the coefficients of the power series starting from the constant term (as in
Polrev
\((x)\)); in other words we convertt_VEC
/t_COL
to the power series whose significant terms are exactly given by the vector entries.
On the other hand, if \(d\) is explicitly given, we abide by its value and return a series, truncated or extended with zeros as needed, with \(d\) significant terms.
? v = [1,2,3]; ? Ser(v, t) \\ 3 terms: seriesprecision is ignored! %7 = 1 + 2*t + 3*t^2 + O(t^3) ? Ser(v, t, 7) \\ 7 terms as explicitly requested %8 = 1 + 2*t + 3*t^2 + O(t^7) ? s = 1+x+O(x^2); ? Ser(s) %10 = 1 + x + O(x^2) \\ 2 terms: seriesprecision is ignored ? Ser(s, x, 7) \\ extend to 7 terms %11 = 1 + x + O(x^7) ? Ser(s, x, 1) \\ truncate to 1 term %12 = 1 + O(x)
The warning given for
Pol
also applies here: this is not a substitution function.
- Set()¶
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 typest_VEC
,t_COL
,t_LIST
andt_VECSMALL
are converted to the set with corresponding elements. All others are converted to a set with one element.? Set([1,2,4,2,1,3]) %1 = [1, 2, 3, 4] ? Set(x) %2 = [x] ? Set(Vecsmall([1,3,2,1,3])) %3 = [1, 2, 3]
- Strchr()¶
Deprecated alias for strchr.
- Vec(n)¶
Transforms the object \(x\) into a row vector. The dimension of the resulting vector can be optionally specified via the extra parameter \(n\). If \(n\) is omitted or \(0\), the dimension depends on the type of \(x\); the vector has a single component, except when \(x\) is
a vector or a quadratic form: returns the initial object considered as a row vector,
a polynomial or a power series: returns a vector consisting of the coefficients. In the case of a polynomial, the coefficients of the vector start with the leading coefficient of the polynomial, while for power series only the significant coefficients are taken into account, but this time by increasing order of degree. In particular the valuation is ignored (which makes the function useful for series of negative valuation):
? Vec(3*x^2 + x) %1 = [3, 1, 0] ? Vec(x^2 + 3*x^3 + O(x^5)) %2 = [1, 3, 0] ? Vec(x^-2 + 3*x^-1 + O(x)) %3 = [1, 3, 0]
Vec
is the reciprocal function ofPol
for a polynomial and ofSer
for power series of valuation \(0\).a matrix: returns the vector of columns comprising the matrix,
? m = [1,2,3;4,5,6] %4 = [1 2 3] [4 5 6] ? Vec(m) %5 = [[1, 4]~, [2, 5]~, [3, 6]~]
a character string: returns the vector of individual characters,
? Vec("PARI") %6 = ["P", "A", "R", "I"]
a map: returns the vector of the domain of the map,
an error context (
t_ERROR
): returns the error components, seeiferr
.
In the last four cases (matrix, character string, map, 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\|\). This allows to write a conversion function for series that takes positive valuations into account:
? serVec(s) = Vec(s, -serprec(s,variable(s))); ? Vec(x^2 + 3*x^3 + O(x^5)) %2 = [0, 0, 1, 3, 0]
(That function is not intended for series of negative valuation.)
- Vecrev(n)¶
As \(Vec (x, -n)\), then reverse the result. In particular,
Vecrev
is the reciprocal function ofPolrev
: the coefficients of the vector start with the constant coefficient of the polynomial and the others follow by increasing degree.
- Vecsmall(n)¶
Transforms the object \(x\) into a row vector of type
t_VECSMALL
. The dimension of the resulting vector can be optionally specified via the extra parameter \(n\).This acts as
Vec
\((x,n)\), but only on a limited set of objects: the result must be representable as a vector of small integers. If \(x\) is a character string, a vector of individual characters in ASCII encoding is returned (strchr
yields back the character string).
- abs(precision)¶
Absolute value of \(x\) (modulus if \(x\) is complex). Rational functions are not allowed. Contrary to most transcendental functions, an exact argument is not converted to a real number before applying
abs
and an exact result is returned if possible.? abs(-1) %1 = 1 ? abs(3/7 + 4/7*I) %2 = 5/7 ? abs(1 + I) %3 = 1.414213562373095048801688724
If \(x\) is a polynomial, returns \(-x\) if the leading coefficient is real and negative else returns \(x\). For a power series, the constant coefficient is considered instead.
- acos(precision)¶
Principal branch of \(\cos^{-1}(x) = -i \log (x + i\sqrt{1-x^2})\). In particular, \(\Re (acos(x))\in [0,\pi]\) and if \(x\in \mathbb{R}\) and \(\|x\| > 1\), then \(acos(x)\) is complex. The branch cut is in two pieces: \(]- oo ,-1]\) , continuous with quadrant II, and \([1,+ oo [\), continuous with quadrant IV. We have \(acos(x) = \pi/2 - asin(x)\) for all \(x\).
- acosh(precision)¶
Principal branch of \(\cosh^{-1}(x) = 2 \log (\sqrt{(x+1)/2} + \sqrt{(x-1)/2})\). In particular, \(\Re (acosh(x)) >= 0\) and \(\Im (acosh(x))\in ]-\pi,\pi]\); if \(x\in \mathbb{R}\) and \(x < 1\), then \(acosh(x)\) is complex.
- addprimes()¶
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.? addprimes(37975227936943673922808872755445627854565536638199) ? factor(15226050279225333605356183781326374297180681149613806\ 88657908494580122963258952897654000350692006139) %2 = [37975227936943673922808872755445627854565536638199 1] [40094690950920881030683735292761468389214899724061 1] ? ## *** last result computed in 0 ms.
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 useremoveprimes
.
- agm(y, precision)¶
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.
- airy(precision)¶
Airy \([Ai,Bi]\) functions of argument \(z\).
? [A,B] = airy(1); ? A %2 = 0.13529241631288141552414742351546630617 ? B %3 = 1.2074235949528712594363788170282869954
- algadd(x, y)¶
Given two elements \(x\) and \(y\) in al, computes their sum \(x+y\) in the algebra al.
? A = alginit(nfinit(y),[-1,1]); ? algadd(A,[1,0]~,[1,2]~) %2 = [2, 2]~
Also accepts matrices with coefficients in al.
- algalgtobasis(x)¶
Given an element x in the central simple algebra al output by
alginit
, transforms it to a column vector on the integral basis of al. This is the inverse function ofalgbasistoalg
.? A = alginit(nfinit(y^2-5),[2,y]); ? algalgtobasis(A,[y,1]~) %2 = [0, 2, 0, -1, 2, 0, 0, 0]~ ? algbasistoalg(A,algalgtobasis(A,[y,1]~)) %3 = [Mod(Mod(y, y^2 - 5), x^2 - 2), 1]~
- algaut()¶
Given a cyclic algebra \(al = (L/K,\sigma,b)\) output by
alginit
, returns the automorphism \(\sigma\).? nf = nfinit(y); ? p = idealprimedec(nf,7)[1]; ? p2 = idealprimedec(nf,11)[1]; ? A = alginit(nf,[3,[[p,p2],[1/3,2/3]],[0]]); ? algaut(A) %5 = -1/3*x^2 + 1/3*x + 26/3
- algb()¶
Given a cyclic algebra \(al = (L/K,\sigma,b)\) output by
alginit
, returns the element \(b\in K\).nf = nfinit(y); ? p = idealprimedec(nf,7)[1]; ? p2 = idealprimedec(nf,11)[1]; ? A = alginit(nf,[3,[[p,p2],[1/3,2/3]],[0]]); ? algb(A) %5 = Mod(-77, y)
- algbasis()¶
Given a central simple algebra al output by
alginit
, returns a \(\mathbb{Z}\)-basis of the order \(O_0\) stored in al with respect to the natural order in al. It is a maximal order if one has been computed.A = alginit(nfinit(y), [-1,-1]); ? algbasis(A) %2 = [1 0 0 1/2] [0 1 0 1/2] [0 0 1 1/2] [0 0 0 1/2]
- algbasistoalg(x)¶
Given an element x in the central simple algebra al output by
alginit
, transforms it to its algebraic representation in al. This is the inverse function ofalgalgtobasis
.? A = alginit(nfinit(y^2-5),[2,y]); ? z = algbasistoalg(A,[0,1,0,0,2,-3,0,0]~); ? liftall(z) %3 = [(-1/2*y - 2)*x + (-1/4*y + 5/4), -3/4*y + 7/4]~ ? algalgtobasis(A,z) %4 = [0, 1, 0, 0, 2, -3, 0, 0]~
- algcenter()¶
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 byalginit
, 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 form the center.
? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]]; ? A = algtableinit(mt); ? algcenter(A) \\ = (I_2) %3 = [1] [0] [0]
An example in the central simple case:
? nf = nfinit(y^3-y+1); ? A = alginit(nf, [-1,-1]); ? algcenter(A).pol %3 = y^3 - y + 1
- algcentralproj(z, maps)¶
Given a table algebra al output by
algtableinit
and at_VEC
\(z = [z_1,...,z_n]\) of orthogonal central idempotents, returns at_VEC
\([al_1,...,al_n]\) of algebras such that \(al_i = z_i al\). If \(maps = 1\), each \(al_i\) is at_VEC
\([quo,proj,lift]\) where quo is the quotient algebra, proj is at_MAT
representing the projection onto this quotient and lift is at_MAT
representing a lift.A simple example: \(\mathbb{F}_2 x \mathbb{F}_4\), generated by \(1 = (1,1)\), \(e = (1,0)\) and \(x\) such that \(x^2+x+1 = 0\). We have \(e^2 = e\), \(x^2 = x+1\) and \(ex = 0\).
? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,2); ? e = [0,1,0]~; ? e2 = algsub(A,[1,0,0]~,e); ? [a,a2] = algcentralproj(A,[e,e2]); ? algdim(a) %6 = 1 ? algdim(a2) %7 = 2
- algchar()¶
Given an algebra al output by
alginit
oralgtableinit
, returns the characteristic of al.? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,13); ? algchar(A) %3 = 13
- algcharpoly(b, v, abs)¶
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
or if \(abs = 1\), 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 byalginit
and \(abs = 0\), 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 ? algcharpoly(al, [0,1]~,,1) %3 = x^4 + 2*x^2 + 1 ? nf = nfinit(y^2-5); ? al = alginit(nf,[-1,y]); ? a = [y,1+x]~*Mod(1,y^2-5)*Mod(1,x^2+1); ? P = lift(algcharpoly(al,a)) %7 = x^2 - 2*y*x + (-2*y + 5) ? algcharpoly(al,a,,1) %8 = x^8 - 20*x^6 - 80*x^5 + 110*x^4 + 800*x^3 + 1500*x^2 - 400*x + 25 ? lift(P*subst(P,y,-y)*Mod(1,y^2-5))^2 %9 = x^8 - 20*x^6 - 80*x^5 + 110*x^4 + 800*x^3 + 1500*x^2 - 400*x + 25
Also accepts a square matrix with coefficients in al.
- algdegree()¶
Given a central simple algebra al output by
alginit
, returns the degree of al.? nf = nfinit(y^3-y+1); ? A = alginit(nf, [-1,-1]); ? algdegree(A) %3 = 2
- algdep(k, flag)¶
\(z\) being real/complex, or \(p\)-adic, finds a polynomial (in the variable
'x
) of degree at most \(k\), with integer coefficients, having \(z\) 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 (usesubst
), or by computing the roots of the polynomial given byalgdep
(usepolroots
orpolrootspadic
).Internally,
lindep
\(([1,z,...,z^k], flag)\) is used. A nonzero 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: if \(flag > 0\) the computation is done with an accuracy of \(flag\) decimal digits; to get meaningful results, the parameter \(flag\) should be smaller than the number of correct decimal digits in the input. But default values are usually sufficient, so try without \(flag\) first:? \p200 ? z = 2^(1/6)+3^(1/5); ? algdep(z, 30); \\ right in 280ms ? algdep(z, 30, 100); \\ wrong in 169ms ? algdep(z, 30, 170); \\ right in 288ms ? algdep(z, 30, 200); \\ wrong in 320ms ? \p250 ? z = 2^(1/6)+3^(1/5); \\ recompute to new, higher, accuracy ! ? algdep(z, 30); \\ right in 329ms ? algdep(z, 30, 200); \\ right in 324ms ? \p500 ? algdep(2^(1/6)+3^(1/5), 30); \\ right in 677ms ? \p1000 ? algdep(2^(1/6)+3^(1/5), 30); \\ right in 1.5s
The changes in
realprecision
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 195 digits, and from then on a steady stream of correct results:\\ assume T contains the correct result, for comparison forstep(d=100, 250, 5, localprec(d);\ print(d, " ", algdep(2^(1/6)+3^(1/5),30) == T))
The above example is the test case studied in a 2000 paper by Borwein and Lisonek: Applications of integer relation algorithms, Discrete Math., 217, p. 65–82. The version of PARI tested there was 1.39, which succeeded reliably from precision 265 on, in about 200 as much time as the current version.
- algdim(abs)¶
If al is a table algebra output by
algtableinit
or if \(abs = 1\), returns the dimension of al over its prime subfield (\(\mathbb{Q}\) or \(\mathbb{F}_p\)). If al is a central simple algebra output byalginit
and \(abs = 0\), returns the dimension of al over its center.? nf = nfinit(y^3-y+1); ? A = alginit(nf, [-1,-1]); ? algdim(A) %3 = 4 ? algdim(A,1) %4 = 12
- algdisc()¶
Given a central simple algebra al output by
alginit
, computes the discriminant of the order \(O_0\) stored in al, that is the determinant of the trace form \(\rm{Tr} : O_0 x 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 = algdim(A,1); ? h = vector(#h, i, n - gcd(n,h[i])); ? n^D * nf.disc^(n^2) * idealnorm(nf, idealfactorback(nf,PR,h))^n %4 = 12960000 ? algdisc(A) %5 = 12960000
- algdivl(x, y)¶
Given two elements \(x\) and \(y\) in al, computes their left quotient \(x\backslash y\) in the algebra al: an element \(z\) such that \(xz = y\) (such an element is not unique when \(x\) is a zerodivisor). If \(x\) is invertible, this is the same as \(x^{-1}y\). Assumes that \(y\) is left divisible by \(x\) (i.e. that \(z\) exists). Also accepts matrices with coefficients in al.
- algdivr(x, y)¶
Given two elements \(x\) and \(y\) in al, returns \(xy^{-1}\). Also accepts matrices with coefficients in al.
- alggroup(p)¶
Initializes the group algebra \(K[G]\) over \(K = \mathbb{Q}\) (\(p\) omitted) or \(\mathbb{F}_p\) where \(G\) is the underlying group of the
galoisinit
structure gal. The input gal is also allowed to be at_VEC
of permutations that is closed under products.Example:
? K = nfsplitting(x^3-x+1); ? gal = galoisinit(K); ? al = alggroup(gal); ? algissemisimple(al) %4 = 1 ? G = [Vecsmall([1,2,3]), Vecsmall([1,3,2])]; ? al2 = alggroup(G, 2); ? algissemisimple(al2) %8 = 0
- alggroupcenter(p, cc)¶
Initializes the center \(Z(K[G])\) of the group algebra \(K[G]\) over \(K = \mathbb{Q}\) (\(p = 0\) or omitted) or \(\mathbb{F}_p\) where \(G\) is the underlying group of the
galoisinit
structure gal. The input gal is also allowed to be at_VEC
of permutations that is closed under products. Sets cc to at_VEC
\([elts,conjclass,rep,flag]\) where elts is a sortedt_VEC
containing the list of elements of \(G\), conjclass is at_VECSMALL
of the same length as elts containing the index of the conjugacy class of the corresponding element (an integer between \(1\) and the number of conjugacy classes), and rep is at_VECSMALL
of length the number of conjugacy classes giving for each conjugacy class the index in elts of a representative of this conjugacy class. Finally flag is \(1\) if and only if the permutation representation of \(G\) is transitive, in which case the \(i\)-th element of elts is characterized by \(g[1] = i\); this is always the case when gal is agaloisinit
structure. The basis of \(Z(K[G])\) as output consists of the indicator functions of the conjugacy classes in the ordering given by cc. Example:? K = nfsplitting(x^4+x+1); ? gal = galoisinit(K); \\ S4 ? al = alggroupcenter(gal,,&cc); ? algiscommutative(al) %4 = 1 ? #cc[3] \\ number of conjugacy classes of S4 %5 = 5 ? gal = [Vecsmall([1,2,3]),Vecsmall([1,3,2])]; \\ C2 ? al = alggroupcenter(gal,,&cc); ? cc[3] %8 = Vecsmall([1, 2]) ? cc[4] %9 = 0
- alghasse(pl)¶
Given a central simple algebra al output by
alginit
and a prime ideal or an integer between \(1\) and \(r_1+r_2\), returns at_FRAC
\(h\) : the local Hasse invariant of al at the place specified by pl.? nf = nfinit(y^2-5); ? A = alginit(nf, [-1,y]); ? alghasse(A, 1) %3 = 1/2 ? alghasse(A, 2) %4 = 0 ? alghasse(A, idealprimedec(nf,2)[1]) %5 = 1/2 ? alghasse(A, idealprimedec(nf,5)[1]) %6 = 0
- alghassef()¶
Given a central simple algebra al output by
alginit
, returns at_VEC
\([PR, h_f]\) describing the local Hasse invariants at the finite places of the center:PR
is at_VEC
of primes and \(h_f\) is at_VECSMALL
of integers modulo the degree \(d\) of al. The Hasse invariant of al at the primes outsidePR
is \(0\), butPR
can include primes at which the Hasse invariant is \(0\).? nf = nfinit(y^2-5); ? A = alginit(nf, [-1,2*y-1]); ? [PR,hf] = alghassef(A); ? PR %4 = [[19, [10, 2]~, 1, 1, [-8, 2; 2, -10]], [2, [2, 0]~, 1, 2, 1]] ? hf %5 = Vecsmall([1, 0])
- alghassei()¶
Given a central simple algebra al output by
alginit
, returns at_VECSMALL
\(h_i\) of \(r_1\) integers modulo the degree \(d\) of al, where \(r_1\) is the number of real places of the center: the local Hasse invariants of al at infinite places.? nf = nfinit(y^2-5); ? A = alginit(nf, [-1,y]); ? alghassei(A) %3 = Vecsmall([1, 0])
- algindex(pl)¶
Returns 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_k(D)\). If pl is set, it should be a prime ideal of \(K\) or an integer between \(1\) and \(r_1+r_2\), and in that case return the local index at the place pl instead.
? nf = nfinit(y^2-5); ? A = alginit(nf, [-1,y]); ? algindex(A, 1) %3 = 2 ? algindex(A, 2) %4 = 1 ? algindex(A, idealprimedec(nf,2)[1]) %5 = 2 ? algindex(A, idealprimedec(nf,5)[1]) %6 = 1 ? algindex(A) %7 = 2
- alginit(C, v, maxord)¶
Initializes the central simple algebra defined by data \(B\), \(C\) and variable \(v\), as follows.
(multiplication table) \(B\) is the base number field \(K\) in
nfinit
form, \(C\) is a “multiplication table” over \(K\). As a \(K\)-vector space, the algebra is generated by a basis \((e_1 = 1,..., e_n)\); the table is given as at_VEC
of \(n\) matrices in \(M_n(K)\), giving the left multiplication by the basis elements \(e_i\), in the given basis. Assumes that \(e_1 = 1\), that the multiplication table is integral, and that \((\bigoplus_{i = 1}^nK e_i,C)\) describes a central simple algebra over \(K\).
{ mi = [0,-1,0, 0; 1, 0,0, 0; 0, 0,0,-1; 0, 0,1, 0]; mj = [0, 0,-1,0; 0, 0, 0,1; 1, 0, 0,0; 0,-1, 0,0]; mk = [0, 0, 0, 0; 0, 0,-1, 0; 0, 1, 0, 0; 1, 0, 0,-1]; A = alginit(nfinit(y), [matid(4), mi,mj,mk], 0); }
represents (in a complicated way) the quaternion algebra \((-1,-1)_\mathbb{Q}\). See below for a simpler solution.
(cyclic algebra) \(B\) is an
rnf
structure attached to a cyclic number field extension \(L/K\) of degree \(d\), \(C\) is at_VEC
[sigma,b]
with 2 components:sigma
is at_POLMOD
representing an automorphism generating \(Gal(L/K)\), \(b\) is an element in \(K^*\). This represents the cyclic algebra \((L/K,\sigma,b)\). Currently the element \(b\) has to be integral.
? Q = nfinit(y); T = polcyclo(5, 'x); F = rnfinit(Q, T); ? A = alginit(F, [Mod(x^2,T), 3]);
defines the cyclic algebra \((L/\mathbb{Q}, \sigma, 3)\), where \(L = \mathbb{Q} (\zeta_5)\) and \(\sigma:\zeta:--->\zeta^2\) generates \(Gal(L/\mathbb{Q})\).
(quaternion algebra, special case of the above) \(B\) is an
nf
structure attached to a number field \(K\), \(C = [a,b]\) is a vector containing two elements of \(K^*\) with \(a\) not a square in \(K\), returns the quaternion algebra \((a,b)_K\). The variable \(v\) ('x
by default) must have higher priority than the variable of \(K\).pol
and is used to represent elements in the splitting field \(L = K[x]/(x^2-a)\).
? Q = nfinit(y); A = alginit(Q, [-1,-1]); \\ (-1,-1)_Q
(algebra/\(K\) defined by local Hasse invariants) \(B\) is an
nf
structure attached to a number field \(K\), \(C = [d, [PR,h_f], h_i]\) is a triple containing an integer \(d > 1\), a pair \([PR, h_f]\) describing the Hasse invariants at finite places, and \(h_i\) the Hasse invariants at archimedean (real) places. A local Hasse invariant belongs to \((1/d)\mathbb{Z}/\mathbb{Z} \subset \mathbb{Q}/\mathbb{Z}\), and is given either as at_FRAC
(lift to \((1/d)\mathbb{Z}\)), at_INT
ort_INTMOD
modulo \(d\) (lift to \(\mathbb{Z}/d\mathbb{Z}\)); a whole vector of local invariants can also be given as at_VECSMALL
, whose entries are handled ast_INT
s.PR
is a list of prime ideals (prid
structures), and \(h_f\) is a vector of the same length giving the local invariants at those maximal ideals. The invariants at infinite real places are indexed by the real roots \(K\).roots
: if the Archimedean place \(v\) is attached to the \(j\)-th root, the value of \(h_v\) is given by \(h_i[j]\), must be \(0\) or \(1/2\) (or \(d/2\) modulo \(d\)), and can be nonzero only if \(d\) is even.
By class field theory, provided the local invariants \(h_v\) sum to \(0\), up to Brauer equivalence, there is a unique central simple algebra over \(K\) with given local invariants and trivial invariant elsewhere. In particular, up to isomorphism, there is a unique such algebra \(A\) of degree \(d\).
We realize \(A\) as a cyclic algebra through class field theory. The variable \(v\) (
'x
by default) must have higher priority than the variable of \(K\).pol
and is used to represent elements in the (cyclic) splitting field extension \(L/K\) for \(A\).? nf = nfinit(y^2+1); ? PR = idealprimedec(nf,5); #PR %2 = 2 ? hi = []; ? hf = [PR, [1/3,-1/3]]; ? A = alginit(nf, [3,hf,hi]); ? algsplittingfield(A).pol %6 = x^3 - 21*x + 7
(matrix algebra, toy example) \(B\) is an
nf
structure attached to a number field \(K\), \(C = d\) is a positive integer. Returns a cyclic algebra isomorphic to the matrix algebra \(M_d(K)\).
In all cases, this function computes a maximal order for the algebra by default, which may require a lot of time. Setting \(maxord = 0\) prevents this computation.
The pari object representing such an algebra \(A\) is a
t_VEC
with the following data:A splitting field \(L\) of \(A\) of the same degree over \(K\) as \(A\), in
rnfinit
format, accessed withalgsplittingfield
.The Hasse invariants at the real places of \(K\), accessed with
alghassei
.The Hasse invariants of \(A\) at the finite primes of \(K\) that ramify in the natural order of \(A\), accessed with
alghassef
.A basis of an order \(O_0\) expressed on the basis of the natural order, accessed with
algbasis
.A basis of the natural order expressed on the basis of \(O_0\), accessed with
alginvbasis
.The left multiplication table of \(O_0\) on the previous basis, accessed with
algmultable
.The characteristic of \(A\) (always \(0\)), accessed with
algchar
.The absolute traces of the elements of the basis of \(O_0\).
If \(A\) was constructed as a cyclic algebra \((L/K,\sigma,b)\) of degree \(d\), a
t_VEC
\([\sigma,\sigma^2,...,\sigma^{d-1}]\). The functionalgaut
returns \(\sigma\).If \(A\) was constructed as a cyclic algebra \((L/K,\sigma,b)\), the element \(b\), accessed with
algb
.If \(A\) was constructed with its multiplication table \(mt\) over \(K\), the
t_VEC
oft_MAT
\(mt\), accessed withalgrelmultable
.If \(A\) was constructed with its multiplication table \(mt\) over \(K\), a
t_VEC
with three components: at_COL
representing an element of \(A\) generating the splitting field \(L\) as a maximal subfield of \(A\), at_MAT
representing an \(L\)-basis \(B\) of \(A\) expressed on the \(\mathbb{Z}\)-basis of \(O_0\), and at_MAT
representing the \(\mathbb{Z}\)-basis of \(O_0\) expressed on \(B\). This data is accessed withalgsplittingdata
.
- alginv(x)¶
Given an element \(x\) in al, computes its inverse \(x^{-1}\) in the algebra al. Assumes that \(x\) is invertible.
? A = alginit(nfinit(y), [-1,-1]); ? alginv(A,[1,1,0,0]~) %2 = [1/2, 1/2, 0, 0]~
Also accepts matrices with coefficients in al.
- alginvbasis()¶
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 \(O_0\) stored in al.A = alginit(nfinit(y), [-1,-1]); ? alginvbasis(A) %2 = [1 0 0 -1] [0 1 0 -1] [0 0 1 -1] [0 0 0 2]
- algisassociative(p)¶
Returns 1 if the multiplication table
mt
is suitable foralgtableinit(mt,p)
, 0 otherwise. More precisely,mt
should be at_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 byalgtableinit
(\(p\) is ignored in this case).
- algiscommutative()¶
al being a table algebra output by
algtableinit
or a central simple algebra output byalginit
, tests whether the algebra al is commutative.? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]]; ? A = algtableinit(mt); ? algiscommutative(A) %3 = 0 ? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,2); ? algiscommutative(A) %6 = 1
- algisdivision(pl)¶
Given a central simple algebra al output by
alginit
, tests 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 tests 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
- algisdivl(x, y, z)¶
Given two elements \(x\) and \(y\) in al, tests whether \(y\) is left divisible by \(x\), that is whether there exists \(z\) in al such that \(xz = y\), and sets \(z\) to this element if it exists.
? A = alginit(nfinit(y), [-1,1]); ? algisdivl(A,[x+2,-x-2]~,[x,1]~) %2 = 0 ? algisdivl(A,[x+2,-x-2]~,[-x,x]~,&z) %3 = 1 ? z %4 = [Mod(-2/5*x - 1/5, x^2 + 1), 0]~
Also accepts matrices with coefficients in al.
- algisinv(x, ix)¶
Given an element \(x\) in al, tests whether \(x\) is invertible, and sets \(ix\) to the inverse of \(x\).
? A = alginit(nfinit(y), [-1,1]); ? algisinv(A,[-1,1]~) %2 = 0 ? algisinv(A,[1,2]~,&ix) %3 = 1 ? ix %4 = [Mod(Mod(-1/3, y), x^2 + 1), Mod(Mod(2/3, y), x^2 + 1)]~
Also accepts matrices with coefficients in al.
- algisramified(pl)¶
Given a central simple algebra al output by
alginit
, tests 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 tests whether al is locally ramified at the place pl instead.? nf = nfinit(y^2-5); ? A = alginit(nf, [-1,y]); ? algisramified(A, 1) %3 = 1 ? algisramified(A, 2) %4 = 0 ? algisramified(A, idealprimedec(nf,2)[1]) %5 = 1 ? algisramified(A, idealprimedec(nf,5)[1]) %6 = 0 ? algisramified(A) %7 = 1
- algissemisimple()¶
al being a table algebra output by
algtableinit
or a central simple algebra output byalginit
, tests whether the algebra al is semisimple.? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]]; ? A = algtableinit(mt); ? algissemisimple(A) %3 = 0 ? m_i=[0,-1,0,0;1,0,0,0;0,0,0,-1;0,0,1,0]; \\ quaternion algebra (-1,-1) ? m_j=[0,0,-1,0;0,0,0,1;1,0,0,0;0,-1,0,0]; ? m_k=[0,0,0,-1;0,0,-1,0;0,1,0,0;1,0,0,0]; ? mt = [matid(4), m_i, m_j, m_k]; ? A = algtableinit(mt); ? algissemisimple(A) %9 = 1
- algissimple(ss)¶
al being a table algebra output by
algtableinit
or a central simple algebra output byalginit
, 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 product F_4 x F_2 ? algissimple(A) %13 = 0
- algissplit(pl)¶
Given a central simple algebra al output by
alginit
, tests 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 tests 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
- alglatadd(lat1, lat2, ptinter)¶
Given an algebra al and two lattices lat1 and lat2 in al, computes the sum \(lat1 + lat2\). If ptinter is present, set it to the intersection \(lat1 \cap lat2\).
? al = alginit(nfinit(y^2+7), [-1,-1]); ? lat1 = alglathnf(al,[1,1,0,0,0,0,0,0]~); ? lat2 = alglathnf(al,[1,0,1,0,0,0,0,0]~); ? latsum = alglatadd(al,lat1,lat2,&latinter); ? matdet(latsum[1]) %5 = 4 ? matdet(latinter[1]) %6 = 64
- alglatcontains(lat, x, ptc)¶
Given an algebra al, a lattice lat and x in al, tests whether \(x\in lat\). If ptc is present, sets it to the
t_COL
of coordinates of \(x\) in the basis of lat.? al = alginit(nfinit(y^2+7), [-1,-1]); ? a1 = [1,-1,0,1,2,0,1,2]~; ? lat1 = alglathnf(al,a1); ? alglatcontains(al,lat1,a1,&c) %4 = 1 ? c %5 = [-1, -2, -1, 1, 2, 0, 1, 1]~
- alglatelement(lat, c)¶
Given an algebra al, a lattice lat and a
t_COL
c, returns the element of al whose coordinates on the mathbb{Z}-basis of lat are given by c.? al = alginit(nfinit(y^2+7), [-1,-1]); ? a1 = [1,-1,0,1,2,0,1,2]~; ? lat1 = alglathnf(al,a1); ? c = [1..8]~; ? elt = alglatelement(al,lat1,c); ? alglatcontains(al,lat1,elt,&c2) %6 = 1 ? c==c2 %7 = 1
- alglathnf(m, d)¶
Given an algebra al and a matrix m with columns representing elements of al, returns the lattice \(L\) generated by the columns of m. If provided, d must be a rational number such that \(L\) contains d times the natural basis of al. The argument m is also allowed to be a
t_VEC
oft_MAT
, in which case m is replaced by the concatenation of the matrices, or at_COL
, in which case m is replaced by its left multiplication table as an element of al.? al = alginit(nfinit(y^2+7), [-1,-1]); ? a = [1,1,-1/2,1,1/3,-1,1,1]~; ? mt = algtomatrix(al,a,1); ? lat = alglathnf(al,mt); ? lat[2] %5 = 1/6
- alglatindex(lat1, lat2)¶
Given an algebra al and two lattices lat1 and lat2 in al, computes the generalized index of lat1 relative to lat2, i.e. \(\|lat2/lat1\cap lat2\|/\|lat1/lat1\cap lat2\|\).
? al = alginit(nfinit(y^2+7), [-1,-1]); ? lat1 = alglathnf(al,[1,1,0,0,0,0,0,0]~); ? lat2 = alglathnf(al,[1,0,1,0,0,0,0,0]~); ? alglatindex(al,lat1,lat2) %4 = 1 ? lat1==lat2 %5 = 0
- alglatinter(lat1, lat2, ptsum)¶
Given an algebra al and two lattices lat1 and lat2 in al, computes the intersection \(lat1\cap lat2\). If ptsum is present, sets it to the sum \(lat1 + lat2\).
? al = alginit(nfinit(y^2+7), [-1,-1]); ? lat1 = alglathnf(al,[1,1,0,0,0,0,0,0]~); ? lat2 = alglathnf(al,[1,0,1,0,0,0,0,0]~); ? latinter = alglatinter(al,lat1,lat2,&latsum); ? matdet(latsum[1]) %5 = 4 ? matdet(latinter[1]) %6 = 64
- alglatlefttransporter(lat1, lat2)¶
Given an algebra al and two lattices lat1 and lat2 in al, computes the left transporter from lat1 to lat2, i.e. the set of \(x\in al\) such that \(x.lat1 \subset lat2\).
? al = alginit(nfinit(y^2+7), [-1,-1]); ? lat1 = alglathnf(al,[1,-1,0,1,2,0,5,2]~); ? lat2 = alglathnf(al,[0,1,-2,-1,0,0,3,1]~); ? tr = alglatlefttransporter(al,lat1,lat2); ? a = alglatelement(al,tr,[0,0,0,0,0,0,1,0]~); ? alglatsubset(al,alglatmul(al,a,lat1),lat2) %6 = 1 ? alglatsubset(al,alglatmul(al,lat1,a),lat2) %7 = 0
- alglatmul(lat1, lat2)¶
Given an algebra al and two lattices lat1 and lat2 in al, computes the lattice generated by the products of elements of lat1 and lat2. One of lat1 and lat2 is also allowed to be an element of al; in this case, computes the product of the element and the lattice.
? al = alginit(nfinit(y^2+7), [-1,-1]); ? a1 = [1,-1,0,1,2,0,1,2]~; ? a2 = [0,1,2,-1,0,0,3,1]~; ? lat1 = alglathnf(al,a1); ? lat2 = alglathnf(al,a2); ? lat3 = alglatmul(al,lat1,lat2); ? matdet(lat3[1]) %7 = 29584 ? lat3 == alglathnf(al, algmul(al,a1,a2)) %8 = 0 ? lat3 == alglatmul(al, lat1, a2) %9 = 0 ? lat3 == alglatmul(al, a1, lat2) %10 = 0
- alglatrighttransporter(lat1, lat2)¶
Given an algebra al and two lattices lat1 and lat2 in al, computes the right transporter from lat1 to lat2, i.e. the set of \(x\in al\) such that \(lat1.x \subset lat2\).
? al = alginit(nfinit(y^2+7), [-1,-1]); ? lat1 = alglathnf(al,matdiagonal([1,3,7,1,2,8,5,2])); ? lat2 = alglathnf(al,matdiagonal([5,3,8,1,9,8,7,1])); ? tr = alglatrighttransporter(al,lat1,lat2); ? a = alglatelement(al,tr,[0,0,0,0,0,0,0,1]~); ? alglatsubset(al,alglatmul(al,lat1,a),lat2) %6 = 1 ? alglatsubset(al,alglatmul(al,a,lat1),lat2) %7 = 0
- alglatsubset(lat1, lat2, ptindex)¶
Given an algebra al and two lattices lat1 and lat2 in al, tests whether \(lat1\subset lat2\). If it is true and ptindex is present, sets it to the index of lat1 in lat2.
? al = alginit(nfinit(y^2+7), [-1,-1]); ? lat1 = alglathnf(al,[1,1,0,0,0,0,0,0]~); ? lat2 = alglathnf(al,[1,0,1,0,0,0,0,0]~); ? alglatsubset(al,lat1,lat2) %4 = 0 ? latsum = alglatadd(al,lat1,lat2); ? alglatsubset(al,lat1,latsum,&index) %6 = 1 ? index %7 = 4
- algmakeintegral(maps)¶
mt being a multiplication table over \(\mathbb{Q}\) in the same format as the input of
algtableinit
, computes an integral multiplication table mt2 for an isomorphic algebra. When \(maps = 1\), returns at_VEC
\([mt2,S,T]\) where S and T are matrices respectively representing the map from the algebra defined by mt to the one defined by mt2 and its inverse.? mt = [matid(2),[0,-1/4;1,0]]; ? algtableinit(mt); *** at top-level: algtableinit(mt) *** ^---------------- *** algtableinit: domain error in algtableinit: denominator(mt) != 1 ? mt2 = algmakeintegral(mt); ? al = algtableinit(mt2); ? algisassociative(al) %4 = 1 ? [mt2, S, T] = algmakeintegral(mt,1); ? S %6 = [1 0] [0 1/4] ? T %7 = [1 0] [0 4] ? vector(#mt, i, S * (mt * T[,i]) * T) == mt2 %8 = 1
- algmul(x, y)¶
Given two elements \(x\) and \(y\) in al, computes their product \(xy\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algmul(A,[1,1,0,0]~,[0,0,2,1]~) %2 = [2, 3, 5, -4]~
Also accepts matrices with coefficients in al.
- algmultable()¶
Returns a multiplication table of al over its prime subfield (\(\mathbb{Q}\) or \(\mathbb{F}_p\)), as a
t_VEC
oft_MAT
: the left multiplication tables of basis elements. If al was output byalgtableinit
, returns the multiplication table used to define al. If al was output byalginit
, returns the multiplication table of the order \(O_0\) stored in al.? A = alginit(nfinit(y), [-1,-1]); ? M = algmultable(A); ? #M %3 = 4 ? M[1] \\ multiplication by e_1 = 1 %4 = [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] ? M[2] %5 = [0 -1 1 0] [1 0 1 1] [0 0 1 1] [0 0 -2 -1]
- algneg(x)¶
Given an element \(x\) in al, computes its opposite \(-x\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algneg(A,[1,1,0,0]~) %2 = [-1, -1, 0, 0]~
Also accepts matrices with coefficients in al.
- algnorm(x, abs)¶
Given an element x in al, computes its norm. If al is a table algebra output by
algtableinit
or if \(abs = 1\), 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 byalginit
and \(abs = 0\) (default), 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 ? nf = nfinit(y^2-5); ? B = alginit(nf,[-1,y]); ? b = [x,1]~; ? n = algnorm(B,b) %7 = Mod(-y + 1, y^2 - 5) ? algnorm(B,b,1) %8 = 16 ? nfeltnorm(nf,n)^algdegree(B) %9 = 16
Also accepts a square matrix with coefficients in al.
- algpoleval(T, b)¶
Given an element \(b\) in al and a polynomial \(T\) in \(K[X]\), computes \(T(b)\) in al. Also accepts as input a
t_VEC
\([b,mb]\) where \(mb\) is the left multiplication table of \(b\).? nf = nfinit(y^2-5); ? al = alginit(nf,[y,-1]); ? b = [1..8]~; ? pol = algcharpoly(al,b,,1); ? algpoleval(al,pol,b)==0 %5 = 1 ? mb = algtomatrix(al,b,1); ? algpoleval(al,pol,[b,mb])==0 %7 = 1
- algpow(x, n)¶
Given an element \(x\) in al and an integer \(n\), computes the power \(x^n\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algpow(A,[1,1,0,0]~,7) %2 = [8, -8, 0, 0]~
Also accepts a square matrix with coefficients in al.
- algprimesubalg()¶
al being the output of
algtableinit
representing a semisimple algebra of positive characteristic, returns a basis of the prime subalgebra of al. The prime subalgebra of al is the subalgebra fixed by the Frobenius automorphism of the center of al. It is abstractly isomorphic to a product of copies of \(\mathbb{F}_p\).? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,2); ? algprimesubalg(A) %3 = [1 0] [0 1] [0 0]
- algquotient(I, maps)¶
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 \(maps = 1\), returns at_VEC
\([al/I,proj,lift]\) where proj and lift are matrices respectively representing the projection map and a section of it.? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,2); ? AQ = algquotient(A,[0;1;0]); ? algdim(AQ) %4 = 2
- algradical()¶
al 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)\), with the basis \((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}\), with basis \(I_2\), \(a = [0,1;0,0]\) and \(b = [0,0;0,1]\), such that \(a^2 = 0\), \(ab = a\), \(ba = 0\), \(b^2 = b\):
? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]]; ? A = algtableinit(mt); ? algradical(A) \\ = (a) %6 = [0] [1] [0]
- algramifiedplaces()¶
Given a central simple algebra al output by
alginit
, returns at_VEC
containing the list of places of the center of al that are ramified in al. Each place is described as an integer between \(1\) and \(r_1\) or as a prime ideal.? nf = nfinit(y^2-5); ? A = alginit(nf, [-1,y]); ? algramifiedplaces(A) %3 = [1, [2, [2, 0]~, 1, 2, 1]]
- algrandom(b)¶
Given an algebra al and an integer b, returns a random element in al with coefficients in \([-b,b]\).
- algrelmultable()¶
Given a central simple algebra al output by
alginit
defined by a multiplication table over its center (a number field), returns this multiplication table.? nf = nfinit(y^3-5); a = y; b = y^2; ? {m_i = [0,a,0,0; 1,0,0,0; 0,0,0,a; 0,0,1,0];} ? {m_j = [0, 0,b, 0; 0, 0,0,-b; 1, 0,0, 0; 0,-1,0, 0];} ? {m_k = [0, 0,0,-a*b; 0, 0,b, 0; 0,-a,0, 0; 1, 0,0, 0];} ? mt = [matid(4), m_i, m_j, m_k]; ? A = alginit(nf,mt,'x); ? M = algrelmultable(A); ? M[2] == m_i %8 = 1 ? M[3] == m_j %9 = 1 ? M[4] == m_k %10 = 1
- algsimpledec(maps)¶
al being the output of
algtableinit
, returns at_VEC
\([J,[al_1,al_2,...,al_n]]\) where \(J\) is a basis of the Jacobson radical of al and \(al/J\) is isomorphic to the direct product of the simple algebras \(al_i\). When \(maps = 1\), each \(al_i\) is replaced with at_VEC
\([al_i,proj_i,lift_i]\) where \(proj_i\) and \(lift_i\) are matrices respectively representing the projection map \(al \to al_i\) and a section of it. Modulo \(J\), the images of the \(lift_i\) form a direct sum in \(al/J\), so that the images of \(1\inal_i\) under \(lift_i\) are central primitive idempotents of \(al/J\). The factors are sorted by increasing dimension, then increasing dimension of the center. This ensures that the ordering of the isomorphism classes of the factors is deterministic over finite fields, but not necessarily over \(\mathbb{Q}\).
- algsplit(v)¶
If al is a table algebra over \(\mathbb{F}_p\) output by
algtableinit
that represents a simple algebra, computes an isomorphism between al and a matrix algebra \(M_d(\mathbb{F}_{p^n})\) where \(N = nd^2\) is the dimension of al. Returns at_VEC
\([map,mapi]\), where:map is a
t_VEC
of \(N\) matrices of size \(d x d\) witht_FFELT
coefficients using the variable v, representing the image of the basis of al under the isomorphism.mapi is an \(N x N\) matrix with
t_INT
coefficients, representing the image in al by the inverse isomorphism of the basis \((b_i)\) of \(M_d(\mathbb{F}_p[\alpha])\) (where \(\alpha\) has degree \(n\) over \(\mathbb{F}_p\)) defined as follows: let \(E_{i,j}\) be the matrix having all coefficients \(0\) except the \((i,j)\)-th coefficient equal to \(1\), and define
\[ \begin{align}\begin{aligned} b_{i_3+n(i_2+di_1)+1} = E_{i_1+1,i_2+1} \alpha^{i_3},\\where :math:`0 <= i_1,i_2 < d` and :math:`0 <= i_3 < n`.\end{aligned}\end{align} \]Example:
? al0 = alginit(nfinit(y^2+7), [-1,-1]); ? al = algtableinit(algmultable(al0), 3); \\ isomorphic to M_2(F_9) ? [map,mapi] = algsplit(al, 'a); ? x = [1,2,1,0,0,0,0,0]~; fx = map*x %4 = [2*a 0] [ 0 2] ? y = [0,0,0,0,1,0,0,1]~; fy = map*y %5 = [1 2*a] [2 a + 2] ? map*algmul(al,x,y) == fx*fy %6 = 1 ? map*mapi[,6] %7 = [0 0] [a 0]
Warning. If al is not simple,
algsplit(al)
can trigger an error, but can also run into an infinite loop. Example:? al = alginit(nfinit(y),[-1,-1]); \\ ramified at 2 ? al2 = algtableinit(algmultable(al),2); \\ maximal order modulo 2 ? algsplit(al2); \\ not semisimple, infinite loop
- algsplittingdata()¶
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 at_VEC
[t,Lbas,Lbasinv]
with \(3\) components:an element \(t\) of al such that \(L = K(t)\) is a maximal subfield of al;
a matrix
Lbas
expressing a \(L\)-basis of al (given an \(L\)-vector space structure by multiplication on the right) on the integral basis of al;a matrix
Lbasinv
expressing the integral basis of al on the previous \(L\)-basis.
? nf = nfinit(y^3-5); a = y; b = y^2; ? {m_i = [0,a,0,0; 1,0,0,0; 0,0,0,a; 0,0,1,0];} ? {m_j = [0, 0,b, 0; 0, 0,0,-b; 1, 0,0, 0; 0,-1,0, 0];} ? {m_k = [0, 0,0,-a*b; 0, 0,b, 0; 0,-a,0, 0; 1, 0,0, 0];} ? mt = [matid(4), m_i, m_j, m_k]; ? A = alginit(nf,mt,'x); ? [t,Lb,Lbi] = algsplittingdata(A); ? t %8 = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]~; ? matsize(Lb) %9 = [12, 2] ? matsize(Lbi) %10 = [2, 12]
- algsplittingfield()¶
Given a central simple algebra al output by
alginit
, returns anrnf
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
- algsqr(x)¶
Given an element \(x\) in al, computes its square \(x^2\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algsqr(A,[1,0,2,0]~) %2 = [-3, 0, 4, 0]~
Also accepts a square matrix with coefficients in al.
- algsub(x, y)¶
Given two elements \(x\) and \(y\) in al, computes their difference \(x-y\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algsub(A,[1,1,0,0]~,[1,0,1,0]~) %2 = [0, 1, -1, 0]~
Also accepts matrices with coefficients in al.
- algsubalg(B)¶
al being a table algebra output by
algtableinit
and B being a basis of a subalgebra of al represented by a matrix, computes an algebra al2 isomorphic to B.Returns \([al2,B2]\) where B2 is a possibly different basis of the subalgebra al2, with respect to which the multiplication table of al2 is defined.
? 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[1]) %5 = 2 ? m = matcompanion(x^4+1); ? mt = [m^i | i <- [0..3]]; ? al = algtableinit(mt); ? B = [1,0;0,0;0,1/2;0,0]; ? al2 = algsubalg(al,B); ? algdim(al2[1]) ? al2[2] %13 = [1 0] [0 0] [0 1] [0 0]
- algtableinit(p)¶
Initializes 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 usealginit
directly.The point of this function is to input a finite dimensional \(K\)-algebra, so as to later compute its radical, then to split the quotient algebra as a product of simple algebras over \(K\).
The pari object representing such an algebra \(A\) is a
t_VEC
with the following data:The characteristic of \(A\), accessed with
algchar
.The multiplication table of \(A\), accessed with
algmultable
.The traces of the elements of the basis.
A simple example: the \(2 x 2\) upper triangular matrices over \(\mathbb{Q}\), generated by \(I_2\), \(a = [0,1;0,0]\) and \(b = [0,0;0,1]\), such that \(a^2 = 0\), \(ab = a\), \(ba = 0\), \(b^2 = b\):
? mt = [matid(3),[0,0,0;1,0,1;0,0,0],[0,0,0;0,0,0;1,0,1]]; ? A = algtableinit(mt); ? algradical(A) \\ = (a) %6 = [0] [1] [0] ? algcenter(A) \\ = (I_2) %7 = [1] [0] [0]
- algtensor(al2, maxord)¶
Given two algebras al1 and al2, computes their tensor product. 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\).
- algtomatrix(x, abs)¶
Given an element x in al, returns the image of x under a homomorphism to a matrix algebra. If al is a table algebra output by
algtableinit
or if \(abs = 1\), returns the left multiplication table on the integral basis; if al is a central simple algebra and \(abs = 0\), returns \(\phi (x)\) where \(\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\)) is an isomorphism stored in al. Also accepts a square matrix with coefficients in al.? A = alginit(nfinit(y), [-1,-1]); ? algtomatrix(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)] ? algtomatrix(A,[0,1,0,0]~,1) %2 = [0 -1 1 0] [1 0 1 1] [0 0 1 1] [0 0 -2 -1] ? algtomatrix(A,[0,x]~,1) %3 = [-1 0 0 -1] [-1 0 1 0] [-1 -1 0 -1] [ 2 0 0 1]
Also accepts matrices with coefficients in al.
- algtrace(x, abs)¶
Given an element x in al, computes its trace. If al is a table algebra output by
algtableinit
or if \(abs = 1\), returns the absolute trace of x, which is an element of \(\mathbb{F}_p\) or \(\mathbb{Q}\); if al is the output ofalginit
and \(abs = 0\) (default), 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 ? algtrace(A,[5,0,0,1]~,1) %3 = 22 ? nf = nfinit(y^2-5); ? A = alginit(nf,[-1,y]); ? a = [1+x+y,2*y]~*Mod(1,y^2-5)*Mod(1,x^2+1); ? t = algtrace(A,a) %7 = Mod(2*y + 2, y^2 - 5) ? algtrace(A,a,1) %8 = 8 ? algdegree(A)*nfelttrace(nf,t) %9 = 8
Also accepts a square matrix with coefficients in al.
- algtype()¶
Given an algebra al output by
alginit
or byalgtableinit
, returns an integer indicating the type of algebra:\(0\): not a valid algebra.
\(1\): table algebra output by
algtableinit
.\(2\): central simple algebra output by
alginit
and represented by a multiplication table over its center.\(3\): central simple algebra output by
alginit
and represented by a cyclic algebra.
? algtype([]) %1 = 0 ? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,2); ? algtype(A) %4 = 1 ? nf = nfinit(y^3-5); ? a = y; b = y^2; ? {m_i = [0,a,0,0; 1,0,0,0; 0,0,0,a; 0,0,1,0];} ? {m_j = [0, 0,b, 0; 0, 0,0,-b; 1, 0,0, 0; 0,-1,0, 0];} ? {m_k = [0, 0,0,-a*b; 0, 0,b, 0; 0,-a,0, 0; 1, 0,0, 0];} ? mt = [matid(4), m_i, m_j, m_k]; ? A = alginit(nf,mt,'x); ? algtype(A) %12 = 2 ? A = alginit(nfinit(y), [-1,-1]); ? algtype(A) %14 = 3
- apply(A)¶
Apply the
t_CLOSURE
f
to the entries ofA
.If
A
is a scalar, returnf(A)
.If
A
is a polynomial or power series \(\sum a_i x^i\) (\(+ O(x^N)\)), applyf
on all coefficients and return \(\sum f(a_i) x^i\) (\(+ O(x^N)\)).If
A
is a vector or list \([a_1,...,a_n]\), return the vector or list \([f(a_1),..., f(a_n)]\). IfA
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 ? apply(sign, 2 - 3* x + 4*x^2 + O(x^3)) %4 = 1 - x + x^2 + O(x^3)
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_VECSMALL
,t_LIST
ort_MAT
, the alternative set-notations[g(x) | x <- v, f(x)] [x | x <- v, f(x)] [g(x) | x <- v]
are available as shortcuts for
apply(g, select(f, Vec(v))) select(f, Vec(v)) apply(g, Vec(v))
respectively:
? L = List([Mod(1,3), Mod(2,4)]); ? [ lift(x) | x<-L ] %2 = [1, 2]
- arg(precision)¶
Argument of the complex number \(x\), such that \(-\pi < \arg (x) <= \pi\).
- arity()¶
Return the arity of the closure \(C\), i.e., the number of its arguments.
? f1(x,y=0)=x+y; ? arity(f1) %1 = 2 ? f2(t,s[..])=print(t,":",s); ? arity(f2) %2 = 2
Note that a variadic argument, such as \(s\) in
f2
above, is counted as a single argument.
- asin(precision)¶
Principal branch of \(\sin^{-1}(x) = -i \log (ix + \sqrt{1 - x^2})\). In particular, \(\Re (asin(x))\in [-\pi/2,\pi/2]\) and if \(x\in \mathbb{R}\) and \(\|x\| > 1\) then \(asin(x)\) is complex. The branch cut is in two pieces: \(]- oo ,-1]\), continuous with quadrant II, and \([1,+ oo [\) continuous with quadrant IV. The function satisfies \(i asin(x) = asinh(ix)\).
- asinh(precision)¶
Principal branch of \(\sinh^{-1}(x) = \log (x + \sqrt{1+x^2})\). In particular \(\Im (asinh(x))\in [-\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.
- asympnum(alpha, precision)¶
Asymptotic expansion of expr, corresponding to a sequence \(u(n)\), assuming it has the shape
\[u(n) ~ \sum_{i >= 0} a_i n^{-i\alpha}\]with rational coefficients \(a_i\) with reasonable height; the algorithm is heuristic and performs repeated calls to limitnum, with
alpha
as inlimitnum
. As inlimitnum
, \(u(n)\) may be given either by a closure \(n:---> u(n)\) or as a closure \(N:---> [u(1),...,u(N)]\), the latter being often more efficient.? f(n) = n! / (n^n*exp(-n)*sqrt(n)); ? asympnum(f) %2 = [] \\ failure ! ? localprec(57); l = limitnum(f) %3 = 2.5066282746310005024157652848110452530 ? asympnum(n->f(n)/l) \\ normalize %4 = [1, 1/12, 1/288, -139/51840, -571/2488320, 163879/209018880, 5246819/75246796800]
and we indeed get a few terms of Stirling’s expansion. Note that it definitely helps to normalize with a limit computed to higher accuracy (as a rule of thumb, multiply the bit accuracy by \(1.612\)):
? l = limitnum(f) ? asympnum(n->f(n) / l) \\ failure again !!! %6 = []
We treat again the example of the Motzkin numbers \(M_n\) given in
limitnum
:\\ [M_k, M_{k*2}, ..., M_{k*N}] / (3^n / n^(3/2)) ? vM(N, k = 1) = { my(q = k*N, V); if (q == 1, return ([1/3])); V = vector(q); V[1] = V[2] = 1; for(n = 2, q - 1, V[n+1] = ((2*n + 1)*V[n] + 3*(n - 1)*V[n-1]) / (n + 2)); f = (n -> 3^n / n^(3/2)); return (vector(N, n, V[n*k] / f(n*k))); } ? localprec(100); l = limitnum(n->vM(n,10)); \\ 3/sqrt(12*Pi) ? \p38 ? asympnum(n->vM(n,10)/l) %2 = [1, -3/32, 101/10240, -1617/1638400, 505659/5242880000, ...]
If
alpha
is not a rational number, loss of accuracy is expected, so it should be precomputed to double accuracy, say:? \p38 ? asympnum(n->log(1+1/n^Pi),Pi) %1 = [0, 1, -1/2, 1/3, -1/4, 1/5] ? localprec(76); a = Pi; ? asympnum(n->log(1+1/n^Pi), a) \\ more terms %3 = [0, 1, -1/2, 1/3, -1/4, 1/5, -1/6, 1/7, -1/8, 1/9, -1/10, 1/11, -1/12] ? asympnum(n->log(1+1/sqrt(n)),1/2) \\ many more terms %4 = 49
The expression is evaluated for \(n = 1, 2,..., N\) for an \(N = O(B)\) if the current bit accuracy is \(B\). If it is not defined for one of these values, translate or rescale accordingly:
? asympnum(n->log(1-1/n)) \\ can't evaluate at n = 1 ! *** at top-level: asympnum(n->log(1-1/n)) *** ^----------------------- *** in function asympnum: log(1-1/n) *** ^---------- *** log: domain error in log: argument = 0 ? asympnum(n->-log(1-1/(2*n))) %5 = [0, 1/2, 1/8, 1/24, ...] ? asympnum(n->-log(1-1/(n+1))) %6 = [0, 1, -1/2, 1/3, -1/4, ...]
- asympnumraw(N, alpha, precision)¶
Return the \(N+1\) first terms of asymptotic expansion of expr, corresponding to a sequence \(u(n)\), as floating point numbers. Assume that the expansion has the shape
\[u(n) ~ \sum_{i >= 0} a_i n^{-i\alpha}\]and return approximation of \([a_0, a_1,..., a_N]\). The algorithm is heuristic and performs repeated calls to limitnum, with
alpha
as inlimitnum
. As inlimitnum
, \(u(n)\) may be given either by a closure \(n:---> u(n)\) or as a closure \(N:---> [u(1),...,u(N)]\), the latter being often more efficient. This function is related to, but more flexible than,asympnum
, which requires rational asymptotic expansions.? f(n) = n! / (n^n*exp(-n)*sqrt(n)); ? asympnum(f) %2 = [] \\ failure ! ? v = asympnumraw(f, 10); ? v[1] - sqrt(2*Pi) %4 = 0.E-37 ? bestappr(v / v[1], 2^60) %5 = [1, 1/12, 1/288, -139/51840, -571/2488320, 163879/209018880,...]
and we indeed get a few terms of Stirling’s expansion (the first 9 terms are correct). If \(u(n)\) has an asymptotic expansion in \(n^{-\alpha}\) with \(\alpha\) not an integer, the default \(alpha = 1\) is inaccurate:
? f(n) = (1+1/n^(7/2))^(n^(7/2)); ? v1 = asympnumraw(f,10); ? v1[1] - exp(1) %8 = 4.62... E-12 ? v2 = asympnumraw(f,10,7/2); ? v2[1] - exp(1) %7 0.E-37
As in
asympnum
, ifalpha
is not a rational number, loss of accuracy is expected, so it should be precomputed to double accuracy, say.
- atan(precision)¶
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 \(atan(x) = -iatanh(ix)\) for all \(x != ± i\).
- atanh(precision)¶
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\in \mathbb{R}\) and \(\|x\| > 1\) then \(atanh(x)\) is complex.
- besselh1(x, precision)¶
\(H^1\)-Bessel function of index nu and argument \(x\).
- besselh2(x, precision)¶
\(H^2\)-Bessel function of index nu and argument \(x\).
- besseli(x, precision)¶
\(I\)-Bessel function of index nu and argument \(x\). If \(x\) converts to a power series, the initial factor \((x/2)^\nu/\Gamma (\nu+1)\) is omitted (since it cannot be represented in PARI when \(\nu\) is not integral).
- besselj(x, precision)¶
\(J\)-Bessel function of index nu and argument \(x\). If \(x\) converts to a power series, the initial factor \((x/2)^\nu/\Gamma (\nu+1)\) is omitted (since it cannot be represented in PARI when \(\nu\) is not integral).
- besseljh(x, precision)¶
\(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.13.3, this function is not very accurate when \(x\) is small.
- besselk(x, precision)¶
\(K\)-Bessel function of index nu and argument \(x\).
- besseln(x, precision)¶
Deprecated alias for
bessely
.
- bessely(x, precision)¶
\(Y\)-Bessel function of index nu and argument \(x\).
- bestappr(B)¶
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, returns the best approximation affordable given the input accuracy; if you are looking for true rational numbers, presumably approximated to sufficient accuracy, you should first try that option. Otherwise, \(B\) must be a positive real scalar (impose \(0 < b <= B\)).
If \(x\) is a
t_REAL
or at_FRAC
, this function uses continued fractions.
? bestappr(Pi, 100) %1 = 22/7 ? bestappr(0.1428571428571428571428571429) %2 = 1/7 ? bestappr([Pi, sqrt(2) + 'x], 10^3) %3 = [355/113, x + 1393/985]
By definition, \(a/b\) is the best rational approximation to \(x\) if \(\|b x - a\| < \|v x - u\|\) for all integers \((u,v)\) with \(0 < v <= B\). (Which implies that \(n/d\) is a convergent of the continued fraction of \(x\).)
If \(x\) is a
t_INTMOD
modulo \(N\) or at_PADIC
of precision \(N = p^k\), this function performs rational modular reconstruction modulo \(N\). The routine then returns the unique rational number \(a/b\) in coprime integers \(\|a\| < N/2B\) and \(b <= B\) which is congruent to \(x\) modulo \(N\). Omitting \(B\) amounts to choosing it of the order of \(\sqrt{N/2}\). If rational reconstruction is not possible (no suitable \(a/b\) exists), returns \([]\).
? bestappr(Mod(18526731858, 11^10)) %1 = 1/7 ? bestappr(Mod(18526731858, 11^20)) %2 = [] ? bestappr(3 + 5 + 3*5^2 + 5^3 + 3*5^4 + 5^5 + 3*5^6 + O(5^7)) %2 = -1/3
In most concrete uses, \(B\) is a prime power and we performed Hensel lifting to obtain \(x\).
The function applies recursively to components of complex objects (polynomials, vectors,…). If rational reconstruction fails for even a single entry, returns \([]\).
- bestapprPade(B)¶
Using variants of the extended Euclidean algorithm (Padé approximants), 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 nonnegative real (impose \(0 <= degree(b) <= B\)).
If \(x\) is a
t_POLMOD
modulo \(N\) this function performs rational modular reconstruction modulo \(N\). The routine then returns the unique rational function \(a/b\) in coprime polynomials, with \(degree(b) <= B\) and \(degree(a)\) minimal, which is congruent to \(x\) modulo \(N\). Omitting \(B\) amounts to choosing it equal to the floor of \(degree(N) / 2\). If rational reconstruction is not possible (no suitable \(a/b\) exists), returns \([]\).
? T = Mod(x^3 + x^2 + x + 3, x^4 - 2); ? bestapprPade(T) %2 = (2*x - 1)/(x - 1) ? U = Mod(1 + x + x^2 + x^3 + x^5, x^9); ? bestapprPade(U) \\ internally chooses B = 4 %3 = [] ? bestapprPade(U, 5) \\ with B = 5, a solution exists %4 = (2*x^4 + x^3 - x - 1)/(-x^5 + x^3 + x^2 - 1)
If \(x\) is a
t_SER
, we implicitly convert the input to at_POLMOD
modulo \(N = t^k\) where \(k\) is the series absolute precision.
? T = 1 + t + t^2 + t^3 + t^4 + t^5 + t^6 + O(t^7); \\ mod t^7 ? bestapprPade(T) %1 = 1/(-t + 1)
If \(x\) is a
t_RFRAC
, we implicitly convert the input to at_POLMOD
modulo \(N = t^k\) where \(k = 2B + 1\). If \(B\) was omitted, we return \(x\):
? T = (4*t^2 + 2*t + 3)/(t+1)^10; ? bestapprPade(T,1) %2 = [] \\ impossible ? bestapprPade(T,2) %3 = 27/(337*t^2 + 84*t + 9) ? bestapprPade(T,3) %4 = (4253*t - 3345)/(-39007*t^3 - 28519*t^2 - 8989*t - 1115)
The function applies recursively to components of complex objects (polynomials, vectors,…). If rational reconstruction fails for even a single entry, return \([]\).
- bestapprnf(T, rootT, precision)¶
\(T\) being an integral polynomial and \(V\) being a scalar, vector, or matrix with complex coefficients, return a reasonable approximation of \(V\) with polmods modulo \(T\). \(T\) can also be any number field structure, in which case the minimal polynomial attached to the structure (
:math:`T`
.pol) is used. The rootT argument, if present, must be an element ofpolroots(:math:`T
)` (or:math:`T`
.pol), i.e. a complex root of \(T\) fixing an embedding of \(\mathbb{Q}[x]/(T)\) into \(\mathbb{C}\).? bestapprnf(sqrt(5), polcyclo(5)) %1 = Mod(-2*x^3 - 2*x^2 - 1, x^4 + x^3 + x^2 + x + 1) ? bestapprnf(sqrt(5), polcyclo(5), exp(4*I*Pi/5)) %2 = Mod(2*x^3 + 2*x^2 + 1, x^4 + x^3 + x^2 + x + 1)
When the output has huge rational coefficients, try to increase the working
realbitprecision
: if the answer does not stabilize, consider that the reconstruction failed. Beware that if \(T\) is not Galois over \(\mathbb{Q}\), some embeddings may not allow to reconstruct \(V\):? T = x^3-2; vT = polroots(T); z = 3*2^(1/3)+1; ? bestapprnf(z, T, vT[1]) %2 = Mod(3*x + 1, x^3 - 2) ? bestapprnf(z, T, vT[2]) %3 = 4213714286230872/186454048314072 \\ close to 3*2^(1/3) + 1
- bezout(y)¶
Deprecated alias for
gcdext
- bezoutres(B, v)¶
Deprecated alias for
polresultantext
- bigomega()¶
Number of prime divisors of the integer \(\|x\|\) counted with multiplicity:
? factor(392) %1 = [2 3] [7 2] ? bigomega(392) %2 = 5; \\ = 3+2 ? omega(392) %3 = 2; \\ without multiplicity
- binary()¶
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.
? binary(10) %1 = [1, 0, 1, 0] ? binary(3.14) %2 = [[1, 1], [0, 0, 1, 0, 0, 0, [...]] ? binary([1,2]) %3 = [[1], [1, 0]]
For integer \(x >= 1\), the number of bits is \(logint (x,2) + 1\). By convention, \(0\) has no digits:
? binary(0) %4 = []
- binomial(k)¶
binomial coefficient \(binom{x}{k}\). Here \(k\) must be an integer, but \(x\) can be any PARI object.
? binomial(4,2) %1 = 6 ? n = 4; vector(n+1, k, binomial(n,k-1)) %2 = [1, 4, 6, 4, 1]
The argument \(k\) may be omitted if \(x = n\) is a nonnegative integer; in this case, return the vector with \(n+1\) components whose \(k+1\)-th entry is
binomial
\((n,k)\)? binomial(4) %3 = [1, 4, 6, 4, 1]
- bitand(y)¶
Bitwise
and
of two integers \(x\) and \(y\), that is the integer\[\sum_i (x_i and y_i) 2^i\]Negative numbers behave \(2\)-adically, i.e. the result is the \(2\)-adic limit of
bitand
\((x_n,y_n)\), where \(x_n\) and \(y_n\) are nonnegative integers tending to \(x\) and \(y\) respectively. (The result is an ordinary integer, possibly negative.)? bitand(5, 3) %1 = 1 ? bitand(-5, 3) %2 = 3 ? bitand(-5, -3) %3 = -7
- bitneg(n)¶
bitwise negation of an integer \(x\), truncated to \(n\) bits, \(n >= 0\), that is the integer
\[\sum_{i = 0}^{n-1} not (x_i) 2^i.\]The special case \(n = -1\) means no truncation: an infinite sequence of leading \(1\) is then represented as a negative number.
See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bitnegimply(y)¶
Bitwise negated imply of two integers \(x\) and \(y\) (or
not
\((x ==> y)\)), that is the integer\[\sum (x_i and not (y_i)) 2^i\]See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bitor(y)¶
bitwise (inclusive)
or
of two integers \(x\) and \(y\), that is the integer\[\sum (x_i or y_i) 2^i\]See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bitprecision(n)¶
The function behaves differently according to whether \(n\) is present or not. If \(n\) is missing, the function returns the (floating point) precision in bits of the PARI object \(x\).
If \(x\) is an exact object, the function returns
+oo
.? bitprecision(exp(1e-100)) %1 = 512 \\ 512 bits ? bitprecision( [ exp(1e-100), 0.5 ] ) %2 = 128 \\ minimal accuracy among components ? bitprecision(2 + x) %3 = +oo \\ exact object
Use
getlocalbitprec()
to retrieve the working bit precision (as modified by possiblelocalbitprec
statements).If \(n\) is present and positive, the function creates a new object equal to \(x\) with the new bit-precision roughly \(n\). In fact, the smallest multiple of 64 (resp. 32 on a 32-bit machine) larger than or equal to \(n\).
For \(x\) a vector or a matrix, the operation is done componentwise; for series and polynomials, the operation is done coefficientwise. For real \(x\), \(n\) is the number of desired significant bits. If \(n\) is smaller than the precision of \(x\), \(x\) is truncated, otherwise \(x\) is extended with zeros. For exact or non-floating-point types, no change.
? bitprecision(Pi, 10) \\ actually 64 bits ~ 19 decimal digits %1 = 3.141592653589793239 ? bitprecision(1, 10) %2 = 1 ? bitprecision(1 + O(x), 10) %3 = 1 + O(x) ? bitprecision(2 + O(3^5), 10) %4 = 2 + O(3^5)
- bittest(n)¶
Outputs the \(n-th\) bit of \(x\) starting from the right (i.e. the coefficient of \(2^n\) in the binary expansion of \(x\)). The result is 0 or 1. For \(x >= 1\), the highest 1-bit is at \(n = logint (x)\) (and bigger \(n\) gives \(0\)).
? bittest(7, 0) %1 = 1 \\ the bit 0 is 1 ? bittest(7, 2) %2 = 1 \\ the bit 2 is 1 ? bittest(7, 3) %3 = 0 \\ the bit 3 is 0
See
bitand
(in the PARI manual) for the behavior at negative arguments.
- bitxor(y)¶
Bitwise (exclusive)
or
of two integers \(x\) and \(y\), that is the integer\[\sum (x_i xor y_i) 2^i\]See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bnfcertify(flag)¶
\(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: precision too low in makeunits [use bnfinit(,1)]. ? 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
- bnfdecodemodule(m)¶
If \(m\) is a module as output in the first component of an extension given by
bnrdisclist
, outputs the true module.? K = bnfinit(x^2+23); L = bnrdisclist(K, 10); s = L[2] %1 = [[[Vecsmall([8]), Vecsmall([1])], [[0, 0, 0]]], [[Vecsmall([9]), Vecsmall([1])], [[0, 0, 0]]]] ? bnfdecodemodule(K, s[1][1]) %2 = [2 0] [0 1] ? bnfdecodemodule(K,s[2][1]) %3 = [2 1] [0 1]
- bnfinit(flag, tech, precision)¶
Initializes a
bnf
structure. Used in programs such asbnfisprincipal
,bnfisunit
orbnfnarrow
. By default, the results are conditional on the GRH, seeGRHbnf
(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. The meaning of flag is as follows:
\(flag = 0\) (default). This is the historical behavior, kept for compatibility reasons and speed. It has severe drawbacks but is likely to be a little faster than the alternative, twice faster say, so only use it if speed is paramount, you obtain a useful speed gain for the fields under consideration, and you are only interested in the field invariants such as the classgroup structure or its regulator. The computations involve exact algebraic numbers which are replaced by floating point embeddings for the sake of speed. If the precision is insufficient,
gp
may not be able to compute fundamental units, nor to solve some discrete logarithm problems. It may be possible to increase the precision of thebnf
structure usingnfnewprec
but this may fail, in particular when fundamental units are large. In short, the resultingbnf
structure is correct and contains useful information but later function calls tobnfisprincpal
orbnrclassfield
may fail.
When \(flag = 1\), we keep an exact algebraic version of all floating point data and this allows to guarantee that functions using the structure will always succeed, as well as to compute the fundamental units exactly. The units are computed in compact form, as a product of small \(S\)-units, possibly with huge exponents. This flag also allows
bnfisprincipal
to compute generators of principal ideals in factored form as well. Be warned that expanding such products explicitly can take a very long time, but they can easily be mapped to floating point or \(\ell\)-adic embeddings of bounded accuracy, or to \(K^*/(K^*)^\ell\), and this is enough for applications. In short, this flag should be used by default, unless you have a very good reason for it, for instance building massive tables of class numbers, and you do not care about units or the effect large units would have on your computation.\(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 are technical. 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]\) contains a dummy \(0\).
\(bnf[7]\) or
:emphasis:`bnf
.nf` is equal to the number field data \(nf\) as would be given bynfinit
.\(bnf[8]\) is a vector containing the classgroup
:emphasis:`bnf
.clgp` as a finite abelian group, the regulator:emphasis:`bnf
.reg`, the number of roots of unity and a generator:emphasis:`bnf
.tu`, the fundamental units in expanded form:emphasis:`bnf
.fu`. If the fundamental units were omitted in the bnf,:emphasis:`bnf
.fu` returns the sentinel value \(0\). If \(flag = 1\), this vector contain also algebraic data corresponding to the fundamental units and to the discrete logarithm problem (seebnfisprincipal
). In particular, if \(flag = 1\) we may only know the units in factored form: the first call to:emphasis:`bnf
.fu` expands them, which may be very costly, then caches the result.\(bnf[9]\) is a 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 ofbnf.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 thebnf.gen[i]^bnf.cyc[i]
. Then \(bnf[9] = [U_r, g_a, GD_a]\), followed by technical exact components which allow to recompute \(g_a\) and \(GD_a\) to higher accuracy.\(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 idealsbnf.gen[i]^bnf.cyc[i]
(during a call tobnrisprincipal
), or those corresponding to the relations in \(W\) and \(B\) (when thebnf
internal precision needs to be increased).
- bnfisintnorm(x)¶
Computes a complete system of solutions (modulo units of positive norm) of the absolute norm equation \(\mathrm{Norm} (a) = x\), where \(a\) is an integer in \(bnf\). If \(bnf\) has not been certified, the correctness of the result depends on the validity of GRH.
See also
bnfisnorm
.
- bnfisnorm(x, flag)¶
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, you may set \(flag = 0\) (in this case, \(x\) is a norm iff \(b = 1\)). If \(flag\) is nonzero the program adds to \(S\) the following prime ideals, depending on the sign of \(flag\). If \(flag > 0\), the ideals of norm less than \(flag\). And if \(flag < 0\) the ideals dividing \(flag\).
Assuming GRH, the answer is guaranteed (i.e. \(x\) is a norm iff \(b = 1\)), if \(S\) contains all primes less than \(12\log (\mathrm{disc} (Bnf))^2\), where \(Bnf\) is the Galois closure of \(bnf\).
See also
bnfisintnorm
.
- bnfisprincipal(x, flag)¶
\(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 a 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 bybnf.gen
andbnf.cyc
). The routine returns a row vector \([e,t]\), where \(e\) is a vector of exponents \(0 <= e_i < d_i\), and \(t\) is a number field element such that\[x = (t) \prod_i g_i^{e_i}.\]For given \(g_i\) (i.e. for a given
bnf
), the \(e_i\) are unique, and \(t\) is unique modulo units.In particular, \(x\) is principal if and only if \(e\) is the zero vector. Note that the empty vector, which is returned when the class number is \(1\), is considered to be a zero vector (of dimension \(0\)).
? K = bnfinit(y^2+23); ? K.cyc %2 = [3] ? K.gen %3 = [[2, 0; 0, 1]] \\ a prime ideal above 2 ? P = idealprimedec(K,3)[1]; \\ a prime ideal above 3 ? v = bnfisprincipal(K, P) %5 = [[2]~, [3/4, 1/4]~] ? idealmul(K, v[2], idealfactorback(K, K.gen, v[1])) %6 = [3 0] [0 1] ? % == idealhnf(K, P) %7 = 1
The binary digits of flag mean:
\(1\): If set, outputs \([e,t]\) as explained above, otherwise returns only \(e\), which is much easier to compute. The following idiom only tests whether an ideal is principal:
is_principal(bnf, x) = !bnfisprincipal(bnf,x,0);
\(2\): It may not be possible to recover \(t\), given the initial accuracy to which the
bnf
structure was computed. In that case, a warning is printed and \(t\) is set equal to the empty vector[]~
. If this bit is set, increase the precision and recompute needed quantities until \(t\) can be computed. Warning: setting this may induce lengthy computations and you should consider using flag \(4\) instead.\(4\): Return \(t\) in factored form (compact representation), as a small product of \(S\)-units for a small set of finite places \(S\), possibly with huge exponents. This kind of result can be cheaply mapped to \(K^*/(K^*)^\ell\) or to \(\mathbb{C}\) or \(\mathbb{Q}_p\) to bounded accuracy and this is usually enough for applications. Explicitly expanding such a compact representation is possible using
nffactorback
but may be very costly. The algorithm is guaranteed to succeed if thebnf
was computed usingbnfinit(,1)
. If not, the algorithm may fail to compute a huge generator in this case (and replace it by[]~
). This is orders of magnitude faster than flag \(2\) when the generators are indeed large.
- bnfissunit(sfu, x)¶
This function is obsolete, use
bnfisunit
.
- bnfisunit(x, U)¶
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 but the last one (\(i = r+1\)) is only defined modulo the order \(w\) of \(\zeta\) and is guaranteed to be in \([0,w[\).Note that bnf need not contain the fundamental units explicitly: it may contain the placeholder \(0\) instead:
? setrand(1); bnf = bnfinit(x^2-x-100000); ? bnf.fu %2 = 0 ? u = [119836165644250789990462835950022871665178127611316131167, \ 379554884019013781006303254896369154068336082609238336]~; ? bnfisunit(bnf, u) %3 = [-1, 0]~
The given \(u\) is \(1/u_1\), where \(u_1\) is the fundamental unit implicitly stored in bnf. In this case, \(u_1\) was not computed and stored in algebraic form since the default accuracy was too low. Re-run the
bnfinit
command at\g1
or higher to see such diagnostics.This function allows \(x\) to be given in factored form, but it then assumes that \(x\) is an actual unit. (Because it is general too costly to check whether this is the case.)
? { v = [2, 85; 5, -71; 13, -162; 17, -76; 23, -37; 29, -104; [224, 1]~, -66; [-86, 1]~, 86; [-241, 1]~, -20; [44, 1]~, 30; [124, 1]~, 11; [125, -1]~, -11; [-214, 1]~, 33; [-213, -1]~, -33; [189, 1]~, 74; [190, -1]~, 104; [-168, 1]~, 2; [-167, -1]~, -8]; } ? bnfisunit(bnf,v) %5 = [1, 0]~
Note that \(v\) is the fundamental unit of
bnf
given in compact (factored) form.If the argument
U
is present, as output bybnfunits(bnf, S)
, then the function decomposes \(x\) on the \(S\)-units generators given inU[1]
.? bnf = bnfinit(x^4 - x^3 + 4*x^2 + 3*x + 9, 1); ? bnf.sign %2 = [0, 2] ? S = idealprimedec(bnf,5); #S %3 = 2 ? US = bnfunits(bnf,S); ? g = US[1]; #g \\ #S = #g, four S-units generators, in factored form %5 = 4 ? g[1] %6 = [[6, -3, -2, -2]~ 1] ? g[2] %7 = [[-1, 1/2, -1/2, -1/2]~ 1] [ [4, -2, -1, -1]~ 1] ? [nffactorback(bnf, x) | x <- g] %8 = [[6, -3, -2, -2]~, [-5, 5, 0, 0]~, [-1, 1, -1, 0]~, [1, -1, 0, 0]~] ? u = [10,-40,24,11]~; ? a = bnfisunit(bnf, u, US) %9 = [2, 0, 1, 4]~ ? nffactorback(bnf, g, a) \\ prod_i g[i]^a[i] still in factored form %10 = [[6, -3, -2, -2]~ 2] [ [0, 0, -1, -1]~ 1] [ [2, -1, -1, 0]~ -2] [ [1, 1, 0, 0]~ 2] [ [-1, 1, 1, 1]~ -1] [ [1, -1, 0, 0]~ 4] ? nffactorback(bnf,%) \\ u = prod_i g[i]^a[i] %11 = [10, -40, 24, 11]~
- bnflog(l)¶
Let bnf be a bnf structure attached to the number field \(F\) and let \(l\) be a prime number (hereafter denoted \(\ell\) for typographical reasons). Return the logarithmic \(\ell\)-class group \(~{Cl}_F\) of \(F\). This is an abelian group, conjecturally finite (known to be finite if \(F/\mathbb{Q}\) is abelian). The function returns if and only if the group is indeed finite (otherwise it would run into an infinite loop). Let \(S = { p_1,..., p_k}\) be the set of \(\ell\)-adic places (maximal ideals containing \(\ell\)). The function returns \([D, G(\ell), G']\), where
\(D\) is the vector of elementary divisors for \(~{Cl}_F\).
\(G(\ell)\) is the vector of elementary divisors for the (conjecturally finite) abelian group
\[ \begin{align}\begin{aligned} ~{\mathrm{Cl}}(\ell) = \{ a = \sum_{i <= k} a_i p_i : \deg_F a = 0},\\where the :math:`p_i` are the :math:`\ell`-adic places of :math:`F`; this is a subgroup of :math:`~{\mathrm{Cl}}`.\end{aligned}\end{align} \]\(G'\) is the vector of elementary divisors for the \(\ell\)-Sylow \(Cl'\) of the \(S\)-class group of \(F\); the group \(~{\mathrm{Cl}}\) maps to \(Cl'\) with a simple co-kernel.
- bnflogdegree(A, l)¶
Let nf be a nf structure attached to a number field \(F\), and let \(l\) be a prime number (hereafter denoted \(\ell\)). The \(\ell\)-adified group of id\`{e}les of \(F\) quotiented by the group of logarithmic units is identified to the \(\ell\)-group of logarithmic divisors \(\oplus \mathbb{Z}_\ell [p]\), generated by the maximal ideals of \(F\).
The degree map \(\deg_F\) is additive with values in \(\mathbb{Z}_\ell\), defined by \(\deg_F p = ~{f}_{p} \deg_\ell p\), where the integer \(~{f}_{p}\) is as in
bnflogef
and \(\deg_\ell p\) is \(\log_\ell p\) for \(p != \ell\), \(\log_\ell (1 + \ell)\) for \(p = \ell != 2\) and \(\log_\ell (1 + 2^2)\) for \(p = \ell = 2\).Let \(A = \prod p^{n_{p}}\) be an ideal and let \(~{A} = \sum n_p [p]\) be the attached logarithmic divisor. Return the exponential of the \(\ell\)-adic logarithmic degree \(\deg_F A\), which is a natural number.
- bnflogef(pr)¶
Let nf be a nf structure attached to a number field \(F\) and let pr be a prid structure attached to a maximal ideal \(p / p\). Return \([~{e}(F_p / \mathbb{Q}_p), ~{f}(F_p / \mathbb{Q}_p)]\) the logarithmic ramification and residue degrees. Let \(\mathbb{Q}_p^c/\mathbb{Q}_p\) be the cyclotomic \(\mathbb{Z}_p\)-extension, then \(~{e} = [F_p : F_p \cap \mathbb{Q}_p^c]\) and \(~{f} = [F_p \cap \mathbb{Q}_p^c : \mathbb{Q}_p]\). Note that \(~{e}~{f} = e(p/p) f(p/p)\), where \(e(p/p)\) and \(f(p/p)\) denote the usual ramification and residue degrees.
? F = nfinit(y^6 - 3*y^5 + 5*y^3 - 3*y + 1); ? bnflogef(F, idealprimedec(F,2)[1]) %2 = [6, 1] ? bnflogef(F, idealprimedec(F,5)[1]) %3 = [1, 2]
- bnfnarrow()¶
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`: 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 ofbnrinit
; the bnf need not contain fundamental units.
- bnfsignunit()¶
\(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 K.tu, K.fu */ tpuexpo(K)= { my(M, S = bnfsignunit(K), [m,n] = matsize(S)); \\ m = K.r1, n = r1+r2-1 S = matrix(m,n, i,j, if (S[i,j] < 0, 1,0)); S = concat(vectorv(m,i,1), S); \\ add sign(-1) M = matkermod(S, 2); if (M, mathnfmodid(M, 2), 2*matid(n+1)) } /* totally positive fundamental units of bnf K */ tpu(K)= { my(ex = tpuexpo(K)[,^1]); \\ remove ex[,1], corresponds to 1 or -1 my(v = concat(K.tu[2], K.fu)); [ nffactorback(K, v, c) | c <- ex]; }
- bnfsunit(S, precision)¶
Computes the fundamental \(S\)-units of the number field \(bnf\) (output by
bnfinit
), where \(S\) is a list of prime ideals (output byidealprimedec
). 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 obsoleted component, now the empty vector.
\(v[4]\) is the \(S\)-regulator (this is the product of the regulator, the \(S\)-class number and the natural logarithms of the norms of the ideals in \(S\)).
\(v[5]\) gives the \(S\)-class group structure, in the usual abelian group format: a vector whose three components give in order the \(S\)-class number, the cyclic components and the generators.
\(v[6]\) is a copy of \(S\).
- bnfunits(S)¶
Return the fundamental units of the number field bnf output by bnfinit; if \(S\) is present and is a list of prime ideals, compute fundamental \(S\)-units instead. The first component of the result contains independent integral \(S\)-units generators: first nonunits, then \(r_1+r_2-1\) fundamental units, then the torsion unit. The result may be used as an optional argument to bnfisunit. The units are given in compact form: no expensive computation is attempted if the bnf does not already contain units.
? bnf = bnfinit(x^4 - x^3 + 4*x^2 + 3*x + 9, 1); ? bnf.sign \\ r1 + r2 - 1 = 1 %2 = [0, 2] ? U = bnfunits(bnf); u = U[1]; ? #u \\ r1 + r2 = 2 units %5 = 2; ? u[1] \\ fundamental unit as factorization matrix %6 = [[0, 0, -1, -1]~ 1] [[2, -1, -1, 0]~ -2] [ [1, 1, 0, 0]~ 2] [ [-1, 1, 1, 1]~ -1] ? u[2] \\ torsion unit as factorization matrix %7 = [[1, -1, 0, 0]~ 1] ? [nffactorback(bnf, z) | z <- u] \\ same units in expanded form %8 = [[-1, 1, -1, 0]~, [1, -1, 0, 0]~]
Now an example involving \(S\)-units for a nontrivial \(S\):
? S = idealprimedec(bnf,5); #S %9 = 2 ? US = bnfunits(bnf, S); uS = US[1]; ? g = [nffactorback(bnf, z) | z <- uS] \\ now 4 units %11 = [[6, -3, -2, -2]~, [-5, 5, 0, 0]~, [-1, 1, -1, 0]~, [1, -1, 0, 0]~] ? bnfisunit(bnf,[10,-40,24,11]~) %12 = []~ \\ not a unit ? e = bnfisunit(bnf, [10,-40,24,11]~, US) %13 = [2, 0, 1, 4]~ \\ ...but an S-unit ? nffactorback(bnf, g, e) %14 = [10, -40, 24, 11]~ ? nffactorback(bnf, uS, e) \\ in factored form %15 = [[6, -3, -2, -2]~ 2] [ [0, 0, -1, -1]~ 1] [ [2, -1, -1, 0]~ -2] [ [1, 1, 0, 0]~ 2] [ [-1, 1, 1, 1]~ -1] [ [1, -1, 0, 0]~ 4]
Note that in more complicated cases, any
nffactorback
fully expanding an element in factored form could be very expensive. On the other hand, the final example expands a factorization whose components are themselves in factored form, hence the result is a factored form: this is a cheap operation.
- bnrL1(H, flag, precision)¶
Let bnr be the number field data output by
bnrinit
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 attached to \(\chi\). For the value at \(s = 0\), the function returns in fact for each \(\chi\) a vector \([r_\chi, c_\chi]\) where\[L(s, \chi) = c.s^r + O(s^{r + 1})\]near \(0\).
The argument flag is optional, its binary digits mean 1: compute at \(s = 0\) if unset or \(s = 1\) if set, 2: compute the primitive \(L\)-function attached 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); bnrL1(bnr)
returns the order and the first nonzero 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); bnrL1(bnr2,,2)
returns the order and the first nonzero 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 asbnrL1(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).
- bnrchar(g, v)¶
Returns all characters \(\chi\) on
bnr.clgp
such that \(\chi (g_i) = e(v_i)\), where \(e(x) = \exp (2i\pi x)\). If \(v\) is omitted, returns all characters that are trivial on the \(g_i\). Else the vectors \(g\) and \(v\) must have the same length, the \(g_i\) must be ideals in any form, and each \(v_i\) is a rational number whose denominator must divide the order of \(g_i\) in the ray class group. For convenience, the vector of the \(g_i\) can be replaced by a matrix whose columns give their discrete logarithm, as given bybnrisprincipal
; this allows to specify abstractly a subgroup of the ray class group.? bnr = bnrinit(bnfinit(x), [160,[1]], 1); /* (Z/160Z)^* */ ? bnr.cyc %2 = [8, 4, 2] ? g = bnr.gen; ? bnrchar(bnr, g, [1/2,0,0]) %4 = [[4, 0, 0]] \\ a unique character ? bnrchar(bnr, [g[1],g[3]]) \\ all characters trivial on g[1] and g[3] %5 = [[0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 0, 0]] ? bnrchar(bnr, [1,0,0;0,1,0;0,0,2]) %6 = [[0, 0, 1], [0, 0, 0]] \\ characters trivial on given subgroup
- bnrclassfield(subgp, flag, precision)¶
bnr being as output by
bnrinit
, returns a relative equation for the class field corresponding to the congruence group defined by \((bnr,subgp)\) (the full ray class field if subgp is omitted). The subgroup can also be at_INT
\(n\), meaning \(n.Cl_f\). The function also handles a vector of subgroup, e.g, fromsubgrouplist
and returns the vector of individual results in this case.If \(flag = 0\), returns a vector of polynomials such that the compositum of the corresponding fields is the class field; if \(flag = 1\) returns a single polynomial; if \(flag = 2\) returns a single absolute polynomial.
? bnf = bnfinit(y^3+14*y-1); bnf.cyc %1 = [4, 2] ? pol = bnrclassfield(bnf,,1) \\ Hilbert class field %2 = x^8 - 2*x^7 + ... + Mod(11*y^2 - 82*y + 116, y^3 + 14*y - 1) ? rnfdisc(bnf,pol)[1] %3 = 1 ? bnr = bnrinit(bnf,3*5*7); bnr.cyc %4 = [24, 12, 12, 2] ? bnrclassfield(bnr,2) \\ maximal 2-elementary subextension %5 = [x^2 + (-21*y - 105), x^2 + (-5*y - 25), x^2 + (-y - 5), x^2 + (-y - 1)] \\ quadratic extensions of maximal conductor ? bnrclassfield(bnr, subgrouplist(bnr,[2])) %6 = [[x^2 - 105], [x^2 + (-105*y^2 - 1260)], [x^2 + (-105*y - 525)], [x^2 + (-105*y - 105)]] ? #bnrclassfield(bnr,subgrouplist(bnr,[2],1)) \\ all quadratic extensions %7 = 15
When the subgroup contains \(n Cl_f\), where \(n\) is fixed, it is advised to directly compute the
bnr
modulo \(n\) to avoid expensive discrete logarithms:? bnf = bnfinit(y^2-5); p = 1594287814679644276013; ? bnr = bnrinit(bnf,p); \\ very slow time = 24,146 ms. ? bnrclassfield(bnr, 2) \\ ... even though the result is trivial %3 = [x^2 - 1594287814679644276013] ? bnr2 = bnrinit(bnf,p,,2); \\ now fast time = 1 ms. ? bnrclassfield(bnr2, 2) %5 = [x^2 - 1594287814679644276013]
This will save a lot of time when the modulus contains a maximal ideal whose residue field is large.
- bnrclassno(B, C)¶
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 attached 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. Seebnrclassnolist
if you need ray class numbers for all moduli less than some bound.
- bnrclassnolist(list)¶
\(bnf\) being as output by
bnfinit
, and list being a list of moduli (with units) as output byideallist
orideallistarch
, 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 ofl[i].mod
, i.e. the finite part of the conductor. (This is cosmetic: since by construction the Archimedean part is trivial, I do not want to see it). This tells us that the ray class groups modulo the ideals of norm 98 (printed as%5
) have respectively order \(1\), \(3\) and \(1\). Indeed, we may check directly:? bnrclassno(bnf, ids[2]) %6 = 3
- bnrconductor(B, C, flag)¶
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)\), without generators unless the input contained a bnr with generators.In place of a subgroup \(H\), this function also accepts a character
chi
\(= (a_j)\), expressed as usual in terms of the generatorsbnr.gen
: \(\chi (g_j) = \exp (2i\pi a_j / d_j)\), where \(g_j\) has order \(d_j = bnr.cyc[j]\). In which case, the function returns respectivelyIf \(flag = 0\), the conductor \(f\) of \(Ker \chi\).
If \(flag = 1\), \([f, Cl_f, \chi_f]\), where \(\chi_f\) is \(\chi\) expressed on the minimal ray class group, whose modulus is the conductor.
If \(flag = 2\), \([f, bnr (f), \chi_f]\).
Note. Using this function with \(flag != 0\) is usually a bad idea and kept for compatibility and convenience only: \(flag = 1\) has always been useless, since it is no faster than \(flag = 2\) and returns less information; \(flag = 2\) is mostly OK with two subtle drawbacks:
it returns the full bnr attached to the full ray class group, whereas in applications we only need \(Cl_f\) modulo \(N\)-th powers, where \(N\) is any multiple of the exponent of \(Cl_f/H\). Computing directly the conductor, then calling
bnrinit
with optional argument \(N\) avoids this problem.computing the bnr needs only be done once for each conductor, which is not possible using this function.
For maximal efficiency, the recommended procedure is as follows. Starting from data (character or congruence subgroups) attached to a modulus \(m\), we can first compute the conductors using this function with default \(flag = 0\). Then for all data with a common conductor \(f \| m\), compute (once!) the bnr attached to \(f\) using
bnrinit
(modulo \(N\)-th powers for a suitable \(N\)!) and finally map original data to the new bnr usingbnrmap
.
- bnrconductorofchar(chi)¶
This function is obsolete, use bnrconductor.
- bnrdisc(B, C, flag)¶
\(A\), \(B\), \(C\) defining a class field \(L\) over a ground field \(K\) (of type
[:emphasis:`bnr
]`,[:emphasis:`bnr
, subgroup]`,[:emphasis:`bnr
, character]`,[:emphasis:`bnf
, modulus]` or[:emphasis:`bnf
, modulus, subgroup]`,CFT
(in the PARI manual)), outputs data \([N,r_1,D]\) giving the discriminant and signature of \(L\), depending on the binary digits of flag:1: if this bit is unset, output absolute data related to \(L/\mathbb{Q}\): \(N\) is the absolute degree \([L:\mathbb{Q}]\), \(r_1\) the number of real places of \(L\), and \(D\) the discriminant of \(L/\mathbb{Q}\). Otherwise, output relative data for \(L/K\): \(N\) is the relative degree \([L:K]\), \(r_1\) is the number of real places of \(K\) unramified in \(L\) (so that the number of real places of \(L\) is equal to \(r_1\) times \(N\)), and \(D\) is the relative discriminant ideal of \(L/K\).
2: if this bit is set and if the modulus is not the conductor of \(L\), only return 0.
- bnrdisclist(bound, arch)¶
\(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
orideallistarch
(with units), in which case arch is disregarded.The output \(v\) is a vector, where \(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 attached 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
orbnrdisc
are (much) more efficient.
- bnrgaloisapply(mat, H)¶
Apply the automorphism given by its matrix mat to the congruence subgroup \(H\) given as a HNF matrix. The matrix mat can be computed with
bnrgaloismatrix
.
- bnrgaloismatrix(aut)¶
Return the matrix of the action of the automorphism aut of the base field
bnf.nf
on the generators of the ray class fieldbnr.gen
; aut can be given as a polynomial, an algebraic number, or a vector of automorphisms or a Galois group as output bygaloisinit
, in which case a vector of matrices is returned (in the later case, only for the generatorsaut.gen
).The generators
bnr.gen
need not be explicitly computed in the input bnr, which saves time: the result is well defined in this case also.? K = bnfinit(a^4-3*a^2+253009); B = bnrinit(K,9); B.cyc %1 = [8400, 12, 6, 3] ? G = nfgaloisconj(K) %2 = [-a, a, -1/503*a^3 + 3/503*a, 1/503*a^3 - 3/503*a]~ ? bnrgaloismatrix(B, G[2]) \\ G[2] = Id ... %3 = [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] ? bnrgaloismatrix(B, G[3]) \\ automorphism of order 2 %4 = [799 0 0 2800] [ 0 7 0 4] [ 4 0 5 2] [ 0 0 0 2] ? M = %^2; for (i=1, #B.cyc, M[i,] %= B.cyc[i]); M %5 = \\ acts on ray class group as automorphism of order 2 [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]
See
bnrisgalois
for further examples.
- bnrinit(f, flag, cycmod)¶
\(bnf\) is as output by
bnfinit
(including fundamental units), \(f\) is a modulus, initializes data linked to the ray class group structure corresponding to this module, a so-calledbnr
structure. One can input the attached bid with generators for \(f\) instead of the module itself, saving some time. (As inidealstar
, the finite part of the conductor may be given by a factorization into prime ideals, as produced byidealfactor
.)If the positive integer
cycmod
is present, only compute the ray class group modulocycmod
, which may save a lot of time when some maximal ideals in \(f\) have a huge residue field. In applications, we are given a congruence subgroup \(H\) and study the class field attached to \(Cl_f/H\). If that finite Abelian group has an exponent which dividescycmod
, then we have changed nothing theoretically, while trivializing expensive discrete logs in residue fields (since computations can be made modulocycmod
-th powers). This is useful inbnrclassfield
, for instance when computing \(p\)-elementary extensions.The following member functions are available on the result:
.bnf
is the underlying bnf,.mod
the modulus,.bid
thebid
structure attached 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 explicitly computed, which saves time. Hence
:emphasis:`bnr
.gen` would produce an error. Note that implicit generators are still fixed and stored in the bnr (and guaranteed to be the same for fixed bnf and bid inputs), in terms ofbnr.bnf.gen
andbnr.bid.gen
. The computation which is not performed is the expansion of such products in the ray class group so as to fix eplicit ideal representatives.If \(flag = 1\), as the default, except that generators are computed.
- bnrisconductor(B, C)¶
Fast variant of
bnrconductor
\((A,B,C)\); \(A\), \(B\), \(C\) represent an extension of the base field, given by class field theory (seeCFT
(in the PARI manual)). Outputs 1 if this modulus is the conductor, and 0 otherwise. This is slightly faster thanbnrconductor
when the character or subgroup is not primitive.
- bnrisgalois(gal, H)¶
Check whether the class field attached to the subgroup \(H\) is Galois over the subfield of
bnr.nf
fixed by the group gal, which can be given as output bygaloisinit
, or as a matrix or a vector of matrices as output bybnrgaloismatrix
, the second option being preferable, since it saves the recomputation of the matrices. Note: The function assumes that the ray class field attached 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); B = bnrinit(K,9); G = galoisinit(K); ? [H | H<-subgrouplist(B,3), bnrisgalois(B,G,H)]; time = 160 ms. ? M = bnrgaloismatrix(B,G); ? [H | H<-subgrouplist(B,3), bnrisgalois(B,M,H)] time = 1 ms.
The second computation is much faster since
bnrgaloismatrix(B,G)
is computed only once.
- bnrisprincipal(x, flag)¶
Let bnr be the ray class group data output by
bnrinit
\((,,1)\) and let \(x\) be an ideal in any form, coprime to the modulus \(f = bnr.mod\). Solves the discrete logarithm problem in the ray class group, with respect to the generatorsbnr.gen
, in a way similar tobnfisprincipal
. If \(x\) is not coprime to the modulus of bnr the result is undefined. Note that bnr need not contain the ray class group generators, i.e. it may be created withbnrinit
\((,,0)\); in that case, althoughbnr.gen
is undefined, we can still fix natural generators for the ray class group (in terms of the generators inbnr.bnf.gen
andbnr.bid.gen
) and compute with respect to them.The binary digits of \(flag\) (default \(flag = 1\)) mean:
\(1\): If set returns a 2-component vector \([e,\alpha]\) where \(e\) is the vector of components of \(x\) on the ray class group generators, \(\alpha\) is an element congruent to \(1 mod^* f\) such that \(x = \alpha \prod_i g_i^{e_i}\). If unset, returns only \(e\).
\(4\): If set, returns \([e,\alpha]\) where \(\alpha\) is given in factored form (compact representation). This is orders of magnitude faster.
? K = bnfinit(x^2 - 30); bnr = bnrinit(K, [4, [1,1]]); ? bnr.clgp \\ ray class group is isomorphic to Z/4 x Z/2 x Z/2 %2 = [16, [4, 2, 2]] ? P = idealprimedec(K, 3)[1]; \\ the ramified prime ideal above 3 ? bnrisprincipal(bnr,P) \\ bnr.gen undefined ! %5 = [[3, 0, 0]~, 9] ? bnrisprincipal(bnr,P, 0) \\ omit principal part %5 = [3, 0, 0]~ ? bnr = bnrinit(bnr, bnr.bid, 1); \\ include explicit generators ? bnrisprincipal(bnr,P) \\ ... alpha is different ! %7 = [[3, 0, 0]~, 1/128625]
It may be surprising that the generator \(\alpha\) is different although the underlying bnf and bid are the same. This defines unique generators for the ray class group as ideal classes, whether we use
bnrinit(,0)
orbnrinit(,1)
. But the actual ideal representatives (implicit if the flag is \(0\), computed and stored in the bnr if the flag is \(1\)) are in general different and this is what happens here. Indeed, the implicit generators are naturally expressed expressed in terms ofbnr.bnf.gen
andbnr.bid.gen
and then expanded and simplified (in the same ideal class) so that we obtain ideal representatives forbnr.gen
which are as simple as possible. And indeed the quotient of the two \(\alpha\) found is \(1\) modulo the conductor (and positive at the infinite places it contains), and this is the only guaranteed property.Beware that, when
bnr
is generated usingbnrinit(, cycmod)
, the results are given in \(Cl_f\) modulocycmod
-th powers:? bnr2 = bnrinit(K, bnr.mod,, 2); \\ modulo squares ? bnr2.clgp %9 = [8, [2, 2, 2]] \\ bnr.clgp tensored by Z/2Z ? bnrisprincipal(bnr2,P, 0) %10 = [1, 0, 0]~
- bnrmap(B)¶
This function has two different uses:
if \(A\) and \(B\) are bnr structures for the same bnf attached to moduli \(m_A\) and \(m_B\) with \(m_B \| m_A\), return the canonical surjection from \(A\) to \(B\), i.e. from the ray class group moodulo \(m_A\) to the ray class group modulo \(m_B\). The map is coded by a triple \([M,cyc_A,cyc_B]\): \(M\) gives the image of the fixed ray class group generators of \(A\) in terms of the ones in \(B\), \(cyc_A\) and \(cyc_B\) are the cyclic structures
A.cyc
andB.cyc
respectively. Note that this function does not need \(A\) or \(B\) to contain explicit generators for the ray class groups: they may be created usingbnrinit(,0)
.
If \(B\) is only known modulo \(N\)-th powers (from
bnrinit(,N)
), the result is correct provided \(N\) is a multiple of the exponent of \(A\).if \(A\) is a projection map as above and \(B\) is either a congruence subgroup \(H\), or a ray class character \(\chi\), or a discrete logarithm (from
bnrisprincipal
) modulo \(m_A\) whose conductor divides \(m_B\), return the image of the subgroup (resp. the character, the discrete logarighm) as defined modulo \(m_B\). The main use of this variant is to compute the primitive subgroup or character attached to a bnr modulo their conductor. This is more efficient thanbnrconductor
in two respects: the bnr attached to the conductor need only be computed once and, most importantly, the ray class group can be computed modulo \(N\)-th powers, where \(N\) is a multiple of the exponent of \(Cl_{m_A} / H\) (resp. of the order of \(\chi\)). Whereasbnrconductor
is specified to return a bnr attached to the full ray class group, which may lead to untractable discrete logarithms in the full ray class group instead of a tiny quotient.
- bnrrootnumber(chi, flag, precision)¶
If \(\chi = chi\) is a character over bnr, not necessarily primitive, let \(L(s,\chi) = \sum_{id} \chi (id) N(id)^{-s}\) be the attached Artin L-function. Returns the so-called Artin root number, i.e. the complex number \(W(\chi)\) of modulus 1 such that
\[\Lambda (1-s,\chi) = W(\chi) \Lambda (s,\overline{\chi})\]where \(\Lambda (s,\chi) = A(\chi)^{s/2}\gamma_\chi (s) L(s,\chi)\) is the enlarged L-function attached to \(L\).
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]]); 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\) asbnr.cyc
readily tells us).
- bnrstark(subgroup, precision)¶
bnr being as output by
bnrinit
, 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); bnrstark(bnr)
returns the ray class field of \(\mathbb{Q} (\sqrt{3})\) modulo \(5\). Usually, one wants to apply to the result one of
rnfpolredbest(bnf, pol) \\ compute a reduced relative polynomial rnfpolredbest(bnf, pol, 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. We decided that it was useful to keep the extra information thus made available, hence the user has to take the compositum herself, seenfcompositum
.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
bnrclassfield
:? bnr = bnrinit(bnfinit(y^8-12*y^6+36*y^4-36*y^2+9,1), 2); ? bnrstark(bnr) *** at top-level: bnrstark(bnr) *** ^------------- *** bnrstark: need 3919350809720744 coefficients in initzeta. *** Computation impossible. ? bnrclassfield(bnr) time = 20 ms. %2 = [x^2 + (-2/3*y^6 + 7*y^4 - 14*y^2 + 3)]
- call(A)¶
\(A = [a_1,..., a_n]\) being a vector and \(f\) being a function, returns the evaluation of \(f(a_1,...,a_n)\). \(f\) can also be the name of a built-in GP function. If \(\# A = 1\),
call
(\(f,A\)) =apply
(\(f,A\))[1]. If \(f\) is variadic, the variadic arguments must grouped in a vector in the last component of \(A\).This function is useful
when writing a variadic function, to call another one:
fprintf(file,format,args[..]) = write(file,call(strprintf,[format,args]))
when dealing with function arguments with unspecified arity
The function below implements a global memoization interface:
memo=Map(); memoize(f,A[..])= { my(res); if(!mapisdefined(memo, [f,A], &res), res = call(f,A); mapput(memo,[f,A],res)); res; }
for example:
? memoize(factor,2^128+1) %3 = [59649589127497217,1;5704689200685129054721,1] ? ## *** last result computed in 76 ms. ? memoize(factor,2^128+1) %4 = [59649589127497217,1;5704689200685129054721,1] ? ## *** last result computed in 0 ms. ? memoize(ffinit,3,3) %5 = Mod(1,3)*x^3+Mod(1,3)*x^2+Mod(1,3)*x+Mod(2,3) ? fibo(n)=if(n==0,0,n==1,1,memoize(fibo,n-2)+memoize(fibo,n-1)); ? fibo(100) %7 = 354224848179261915075
to call operators through their internal names without using
alias
matnbelts(M) = call("_*_",matsize(M))
- ceil()¶
Ceiling of \(x\). When \(x\) is in \(\mathbb{R}\), the result is the smallest integer greater than or equal to \(x\). Applied to a rational function, \(ceil (x)\) returns the Euclidean quotient of the numerator by the denominator.
- centerlift(v)¶
Same as
lift
, except thatt_INTMOD
andt_PADIC
components are lifted using centered residues:for a
t_INTMOD
\(x\in \mathbb{Z}/n\mathbb{Z}\), the lift \(y\) is such that \(-n/2 < y <= n/2\).a
t_PADIC
\(x\) is lifted in the same way as above (modulo \(p^padicprec(x)\)) if its valuation \(v\) is nonnegative; if not, returns the fraction \(p^v\)centerlift
\((x p^{-v})\); in particular, rational reconstruction is not attempted. Usebestappr
for this.
For backward compatibility,
centerlift(x,'v)
is allowed as an alias forlift(x,'v)
.
- characteristic()¶
Returns the characteristic of the base ring over which \(x\) is defined (as defined by
t_INTMOD
andt_FFELT
components). The function raises an exception if incompatible primes arise fromt_FFELT
andt_PADIC
components.? characteristic(Mod(1,24)*x + Mod(1,18)*y) %1 = 6
- charconj(chi)¶
Let cyc represent a finite abelian group by its elementary divisors, i.e. \((d_j)\) represents \(\sum_{j <= k} \mathbb{Z}/d_j\mathbb{Z}\) with \(d_k | ... \| d_1\); any object which has a
.cyc
method is also allowed, e.g. the output ofznstar
orbnrinit
. A character on this group is given by a row vector \(\chi = [a_1,...,a_n]\) such that \(\chi (\prod g_j^{n_j}) = \exp (2\pi i\sum a_j n_j / d_j)\), where \(g_j\) denotes the generator (of order \(d_j\)) of the \(j\)-th cyclic component.This function returns the conjugate character.
? cyc = [15,5]; chi = [1,1]; ? charconj(cyc, chi) %2 = [14, 4] ? bnf = bnfinit(x^2+23); ? bnf.cyc %4 = [3] ? charconj(bnf, [1]) %5 = [2]
For Dirichlet characters (when
cyc
isznstar(q,1)
), characters in Conrey representation are available, seedirichletchar
(in the PARI manual) or??character
:? G = znstar(8, 1); \\ (Z/8Z)^* ? charorder(G, 3) \\ Conrey label %2 = 2 ? chi = znconreylog(G, 3); ? charorder(G, chi) \\ Conrey logarithm %4 = 2
- chardiv(a, b)¶
Let cyc represent a finite abelian group by its elementary divisors, i.e. \((d_j)\) represents \(\sum_{j <= k} \mathbb{Z}/d_j\mathbb{Z}\) with \(d_k | ... \| d_1\); any object which has a
.cyc
method is also allowed, e.g. the output ofznstar
orbnrinit
. A character on this group is given by a row vector \(a = [a_1,...,a_n]\) such that \(\chi (\prod g_j^{n_j}) = \exp (2\pi i\sum a_j n_j / d_j)\), where \(g_j\) denotes the generator (of order \(d_j\)) of the \(j\)-th cyclic component.Given two characters \(a\) and \(b\), return the character \(a / b = a \overline{b}\).
? cyc = [15,5]; a = [1,1]; b = [2,4]; ? chardiv(cyc, a,b) %2 = [14, 2] ? bnf = bnfinit(x^2+23); ? bnf.cyc %4 = [3] ? chardiv(bnf, [1], [2]) %5 = [2]
For Dirichlet characters on \((\mathbb{Z}/N\mathbb{Z})^*\), additional representations are available (Conrey labels, Conrey logarithm), see
dirichletchar
(in the PARI manual) or??character
. If the two characters are in the same format, the result is given in the same format, otherwise a Conrey logarithm is used.? G = znstar(100, 1); ? G.cyc %2 = [20, 2] ? a = [10, 1]; \\ usual representation for characters ? b = 7; \\ Conrey label; ? c = znconreylog(G, 11); \\ Conrey log ? chardiv(G, b,b) %6 = 1 \\ Conrey label ? chardiv(G, a,b) %7 = [0, 5]~ \\ Conrey log ? chardiv(G, a,c) %7 = [0, 14]~ \\ Conrey log
- chareval(chi, x, z)¶
Let \(G\) be an abelian group structure affording a discrete logarithm method, e.g \(G = znstar (N, 1)\) for \((\mathbb{Z}/N\mathbb{Z})^*\) or a
bnr
structure, let \(x\) be an element of \(G\) and let chi be a character of \(G\) (see the note below for details). This function returns the value of chi at \(x\).Note on characters. Let \(K\) be some field. If \(G\) is an abelian group, let \(\chi: G \to K^*\) be a character of finite order and let \(o\) be a multiple of the character order such that \(\chi (n) = \zeta^{c(n)}\) for some fixed \(\zeta\in K^*\) of multiplicative order \(o\) and a unique morphism \(c: G \to (\mathbb{Z}/o\mathbb{Z},+)\). Our usual convention is to write
\[G = (\mathbb{Z}/o_1\mathbb{Z}) g_1 \oplus...\oplus (\mathbb{Z}/o_d\mathbb{Z}) g_d\]for some generators \((g_i)\) of respective order \(d_i\), where the group has exponent \(o := lcm_i o_i\). Since \(\zeta^o = 1\), the vector \((c_i)\) in \(\prod (\mathbb{Z}/o_i\mathbb{Z})\) defines a character \(\chi\) on \(G\) via \(\chi (g_i) = \zeta^{c_i (o/o_i)}\) for all \(i\). Classical Dirichlet characters have values in \(K = \mathbb{C}\) and we can take \(\zeta = \exp (2i\pi/o)\).
Note on Dirichlet characters. In the special case where bid is attached to \(G = (\mathbb{Z}/q\mathbb{Z})^*\) (as per
G = znstar(q,1)
), the Dirichlet character chi can be written in one of the usual 3 formats: at_VEC
in terms ofbid.gen
as above, at_COL
in terms of the Conrey generators, or at_INT
(Conrey label); seedirichletchar
(in the PARI manual) or??character
.The character value is encoded as follows, depending on the optional argument \(z\):
If \(z\) is omitted: return the rational number \(c(x)/o\) for \(x\) coprime to \(q\), where we normalize \(0 <= c(x) < o\). If \(x\) can not be mapped to the group (e.g. \(x\) is not coprime to the conductor of a Dirichlet or Hecke character) we return the sentinel value \(-1\).
If \(z\) is an integer \(o\), then we assume that \(o\) is a multiple of the character order and we return the integer \(c(x)\) when \(x\) belongs to the group, and the sentinel value \(-1\) otherwise.
\(z\) can be of the form \([zeta, o]\), where zeta is an \(o\)-th root of \(1\) and \(o\) is a multiple of the character order. We return \(\zeta^{c(x)}\) if \(x\) belongs to the group, and the sentinel value \(0\) otherwise. (Note that this coincides with the usual extension of Dirichlet characters to \(\mathbb{Z}\), or of Hecke characters to general ideals.)
Finally, \(z\) can be of the form \([vzeta, o]\), where vzeta is a vector of powers \(\zeta^0,..., \zeta^{o-1}\) of some \(o\)-th root of \(1\) and \(o\) is a multiple of the character order. As above, we return \(\zeta^{c(x)}\) after a table lookup. Or the sentinel value \(0\).
- chargalois(ORD)¶
Let cyc represent a finite abelian group by its elementary divisors (any object which has a
.cyc
method is also allowed, i.e. the output ofznstar
orbnrinit
). Return a list of representatives for the Galois orbits of complex characters of \(G\). IfORD
is present, select characters depending on their orders:if
ORD
is at_INT
, restrict to orders less than this bound;if
ORD
is at_VEC
ort_VECSMALL
, restrict to orders in the list.
? G = znstar(96); ? #chargalois(G) \\ 16 orbits of characters mod 96 %2 = 16 ? #chargalois(G,4) \\ order less than 4 %3 = 12 ? chargalois(G,[1,4]) \\ order 1 or 4; 5 orbits %4 = [[0, 0, 0], [2, 0, 0], [2, 1, 0], [2, 0, 1], [2, 1, 1]]
Given a character \(\chi\), of order \(n\) (
charorder(G,chi)
), the elements in its orbit are the \(\phi (n)\) characters \(\chi^i\), \((i,n) = 1\).
- charker(chi)¶
Let cyc represent a finite abelian group by its elementary divisors, i.e. \((d_j)\) represents \(\sum_{j <= k} \mathbb{Z}/d_j\mathbb{Z}\) with \(d_k | ... \| d_1\); any object which has a
.cyc
method is also allowed, e.g. the output ofznstar
orbnrinit
. A character on this group is given by a row vector \(\chi = [a_1,...,a_n]\) such that \(\chi (\prod g_j^{n_j}) = \exp (2\pi i\sum a_j n_j / d_j)\), where \(g_j\) denotes the generator (of order \(d_j\)) of the \(j\)-th cyclic component.This function returns the kernel of \(\chi\), as a matrix \(K\) in HNF which is a left-divisor of
matdiagonal(d)
. Its columns express in terms of the \(g_j\) the generators of the subgroup. The determinant of \(K\) is the kernel index.? cyc = [15,5]; chi = [1,1]; ? charker(cyc, chi) %2 = [15 12] [ 0 1] ? bnf = bnfinit(x^2+23); ? bnf.cyc %4 = [3] ? charker(bnf, [1]) %5 = [3]
Note that for Dirichlet characters (when
cyc
isznstar(q, 1)
), characters in Conrey representation are available, seedirichletchar
(in the PARI manual) or??character
.? G = znstar(8, 1); \\ (Z/8Z)^* ? charker(G, 1) \\ Conrey label for trivial character %2 = [1 0] [0 1]
- charmul(a, b)¶
Let cyc represent a finite abelian group by its elementary divisors, i.e. \((d_j)\) represents \(\sum_{j <= k} \mathbb{Z}/d_j\mathbb{Z}\) with \(d_k | ... \| d_1\); any object which has a
.cyc
method is also allowed, e.g. the output ofznstar
orbnrinit
. A character on this group is given by a row vector \(a = [a_1,...,a_n]\) such that \(\chi (\prod g_j^{n_j}) = \exp (2\pi i\sum a_j n_j / d_j)\), where \(g_j\) denotes the generator (of order \(d_j\)) of the \(j\)-th cyclic component.Given two characters \(a\) and \(b\), return the product character \(ab\).
? cyc = [15,5]; a = [1,1]; b = [2,4]; ? charmul(cyc, a,b) %2 = [3, 0] ? bnf = bnfinit(x^2+23); ? bnf.cyc %4 = [3] ? charmul(bnf, [1], [2]) %5 = [0]
For Dirichlet characters on \((\mathbb{Z}/N\mathbb{Z})^*\), additional representations are available (Conrey labels, Conrey logarithm), see
dirichletchar
(in the PARI manual) or??character
. If the two characters are in the same format, their product is given in the same format, otherwise a Conrey logarithm is used.? G = znstar(100, 1); ? G.cyc %2 = [20, 2] ? a = [10, 1]; \\ usual representation for characters ? b = 7; \\ Conrey label; ? c = znconreylog(G, 11); \\ Conrey log ? charmul(G, b,b) %6 = 49 \\ Conrey label ? charmul(G, a,b) %7 = [0, 15]~ \\ Conrey log ? charmul(G, a,c) %7 = [0, 6]~ \\ Conrey log
- charorder(chi)¶
Let cyc represent a finite abelian group by its elementary divisors, i.e. \((d_j)\) represents \(\sum_{j <= k} \mathbb{Z}/d_j\mathbb{Z}\) with \(d_k | ... \| d_1\); any object which has a
.cyc
method is also allowed, e.g. the output ofznstar
orbnrinit
. A character on this group is given by a row vector \(\chi = [a_1,...,a_n]\) such that \(\chi (\prod g_j^{n_j}) = \exp (2\pi i\sum a_j n_j / d_j)\), where \(g_j\) denotes the generator (of order \(d_j\)) of the \(j\)-th cyclic component.This function returns the order of the character
chi
.? cyc = [15,5]; chi = [1,1]; ? charorder(cyc, chi) %2 = 15 ? bnf = bnfinit(x^2+23); ? bnf.cyc %4 = [3] ? charorder(bnf, [1]) %5 = 3
For Dirichlet characters (when
cyc
isznstar(q, 1)
), characters in Conrey representation are available, seedirichletchar
(in the PARI manual) or??character
:? G = znstar(100, 1); \\ (Z/100Z)^* ? charorder(G, 7) \\ Conrey label %2 = 4
- charpoly(v, flag)¶
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\)).
- charpow(a, n)¶
Let cyc represent a finite abelian group by its elementary divisors, i.e. \((d_j)\) represents \(\sum_{j <= k} \mathbb{Z}/d_j\mathbb{Z}\) with \(d_k | ... \| d_1\); any object which has a
.cyc
method is also allowed, e.g. the output ofznstar
orbnrinit
. A character on this group is given by a row vector \(a = [a_1,...,a_n]\) such that \(\chi (\prod g_j^{n_j}) = \exp (2\pi i\sum a_j n_j / d_j)\), where \(g_j\) denotes the generator (of order \(d_j\)) of the \(j\)-th cyclic component.Given \(n\in \mathbb{Z}\) and a character \(a\), return the character \(a^n\).
? cyc = [15,5]; a = [1,1]; ? charpow(cyc, a, 3) %2 = [3, 3] ? charpow(cyc, a, 5) %2 = [5, 0] ? bnf = bnfinit(x^2+23); ? bnf.cyc %4 = [3] ? charpow(bnf, [1], 3) %5 = [0]
For Dirichlet characters on \((\mathbb{Z}/N\mathbb{Z})^*\), additional representations are available (Conrey labels, Conrey logarithm), see
dirichletchar
(in the PARI manual) or??character
and the output uses the same format as the input.? G = znstar(100, 1); ? G.cyc %2 = [20, 2] ? a = [10, 1]; \\ standard representation for characters ? b = 7; \\ Conrey label; ? c = znconreylog(G, 11); \\ Conrey log ? charpow(G, a,3) %6 = [10, 1] \\ standard representation ? charpow(G, b,3) %7 = 43 \\ Conrey label ? charpow(G, c,3) %8 = [1, 8]~ \\ Conrey log
- chinese(y)¶
If \(x\) and \(y\) are both intmods or both polmods, creates (with the same type) a \(z\) in the same residue class as \(x\) and in the same residue class as \(y\), if it is possible.
? chinese(Mod(1,2), Mod(2,3)) %1 = Mod(5, 6) ? chinese(Mod(x,x^2-1), Mod(x+1,x^2+1)) %2 = Mod(-1/2*x^2 + x + 1/2, x^4 - 1)
This function also allows vector and matrix arguments, in which case the operation is recursively applied to each component of the vector or matrix.
? chinese([Mod(1,2),Mod(1,3)], [Mod(1,5),Mod(2,7)]) %3 = [Mod(1, 10), Mod(16, 21)]
For polynomial arguments in the same variable, the function is applied to each coefficient; if the polynomials have different degrees, the high degree terms are copied verbatim in the result, as if the missing high degree terms in the polynomial of lowest degree had been
Mod(0,1)
. Since the latter behavior is usually not the desired one, we propose to convert the polynomials to vectors of the same length first:? P = x+1; Q = x^2+2*x+1; ? chinese(P*Mod(1,2), Q*Mod(1,3)) %4 = Mod(1, 3)*x^2 + Mod(5, 6)*x + Mod(3, 6) ? chinese(Vec(P,3)*Mod(1,2), Vec(Q,3)*Mod(1,3)) %5 = [Mod(1, 6), Mod(5, 6), Mod(4, 6)] ? Pol(%) %6 = Mod(1, 6)*x^2 + Mod(5, 6)*x + Mod(4, 6)
If \(y\) is omitted, and \(x\) is a vector,
chinese
is applied recursively to the components of \(x\), yielding a residue belonging to the same class as all components of \(x\).Finally \(chinese (x,x) = x\) regardless of the type of \(x\); this allows vector arguments to contain other data, so long as they are identical in both vectors.
- cmp(y)¶
Gives the result of a comparison between arbitrary objects \(x\) and \(y\) (as \(-1\), \(0\) or \(1\)). The underlying order relation is transitive, the function returns \(0\) if and only if \(x === y\). It has no mathematical meaning but satisfies the following properties when comparing entries of the same type:
two
t_INT
s compare as usual (i.e.cmp
\((x,y) < 0\) if and only if \(x < y\));two
t_VECSMALL
s of the same length compare lexicographically;two
t_STR
s compare lexicographically.
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 toSet(v)
.
- component(n)¶
Extracts the \(n-th\)-component of \(x\). This is to be understood as follows: every PARI type has one or two initial code words. The components are counted, starting at 1, after these code words. In particular if \(x\) is a vector, this is indeed the \(n-th\)-component of \(x\), if \(x\) is a matrix, the \(n-th\) column, if \(x\) is a polynomial, the \(n-th\) coefficient (i.e. of degree \(n-1\)), and for power series, the \(n-th\) significant coefficient.
For polynomials and power series, one should rather use
polcoeff
, and for vectors and matrices, the[]
operator. Namely, if \(x\) is a vector, thenx[n]
represents the \(n-th\) component of \(x\). If \(x\) is a matrix,x[m,n]
represents the coefficient of rowm
and columnn
of the matrix,x[m,]
represents the \(m-th\) row of \(x\), andx[,n]
represents the \(n-th\) column of \(x\).Using of this function requires detailed knowledge of the structure of the different PARI types, and thus it should almost never be used directly. Some useful exceptions:
? x = 3 + O(3^5); ? component(x, 2) %2 = 81 \\ p^(p-adic accuracy) ? component(x, 1) %3 = 3 \\ p ? q = Qfb(1,2,3); ? component(q, 1) %5 = 1
- concat(y)¶
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, ormatconcat
:? x = [1,2]; ? y = [3,4]; ? concat(x,y) %3 = [1, 2, 3, 4] ? Mat([x,y]~) %4 = [1 2] [3 4] ? matconcat([x;y]) %5 = [1 2] [3 4]
Concatenating a row vector to a matrix having the same number of columns will add the row to the matrix (top row if the vector is \(x\), i.e. comes first, and bottom row otherwise).
The empty matrix
[;]
is considered to have a number of rows compatible with any operation, in particular concatenation. (Note that this is not the case for empty vectors[ ]
or[ ]~
.)If \(y\) is omitted, \(x\) has to be a row vector or a list, in which case its elements are concatenated, from left to right, using the above rules.
? concat([1,2], [3,4]) %1 = [1, 2, 3, 4] ? a = [[1,2]~, [3,4]~]; concat(a) %2 = [1 3] [2 4] ? concat([1,2; 3,4], [5,6]~) %3 = [1 2 5] [3 4 6] ? concat([%, [7,8]~, [1,2,3,4]]) %5 = [1 2 5 7] [3 4 6 8] [1 2 3 4]
- conj()¶
Conjugate of \(x\). The meaning of this is clear, except that for real quadratic numbers, it means conjugation in the real quadratic field. This function has no effect on integers, reals, intmods, fractions or \(p\)-adics. The only forbidden type is polmod (see
conjvec
for this).
- conjvec(precision)¶
Conjugate vector representation of \(z\). If \(z\) is a polmod, equal to
Mod
\((a,T)\), this gives a vector of length \(degree(T)\) containing:the complex embeddings of \(z\) if \(T\) has rational coefficients, i.e. the \(a(r[i])\) where \(r = polroots (T)\);
the conjugates of \(z\) if \(T\) has some intmod coefficients;
if \(z\) is a finite field element, the result is the vector of conjugates \([z,z^p,z^{p^2},...,z^{p^{n-1}}]\) where \(n = degree(T)\).
If \(z\) is an integer or a rational number, the result is \(z\). If \(z\) is a (row or column) vector, the result is a matrix whose columns are the conjugate vectors of the individual elements of \(z\).
- content(D)¶
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
ort_FRAC
), and either \(1\) (inexact input) or \(x\) (exact input) otherwise; the result should be identical togcd(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.The optional argument \(D\) allows to control over which ring we compute and get a more predictable behaviour:
\(1\): we only consider the underlying \(\mathbb{Q}\)-structure and the denominator is a (positive) rational number
a simple variable, say
'x
: all entries are considered as rational functions in \(K(x)\) for some field \(K\) and the content is an element of \(K\).
? f = x + 1/y + 1/2; ? content(f) \\ as a t_POL in x %2 = 1/(2*y) ? content(f, 1) \\ Q-content %3 = 1/2 ? content(f, y) \\ as a rational function in y %4 = 1/2 ? g = x^2*y + y^2*x; ? content(g, x) %6 = y ? content(g, y) %7 = x
- contfrac(b, nmax)¶
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
. Ifnmax
is omitted, the expansion stops at the last significant partial quotient.? \p19 realprecision = 19 significant digits ? contfrac(Pi) %1 = [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2] ? contfrac(Pi,, 3) \\ n = 2 %2 = [3, 7, 15]
\(x\) can also be a rational function or a power series.
If a vector \(b\) is supplied, the numerators are equal to the coefficients of \(b\), instead of all equal to \(1\) as above; more precisely, \(x ~ (1/b_0)(a_0+b_1/(a_1+...+b_n/a_n))\); for a numerical continued fraction (\(x\) real), the \(a_i\) are integers, as large as possible; if \(x\) is a rational function, they are polynomials with \(\deg a_i = \deg b_i + 1\). The length of the result is then equal to the length of \(b\), unless the next partial quotient cannot be reliably computed, in which case the expansion stops. This happens when a partial remainder is equal to zero (or too small compared to the available significant digits for \(x\) a
t_REAL
).A direct implementation of the numerical continued fraction
contfrac(x,b)
described above would be\\ "greedy" generalized continued fraction cf(x, b) = { my( a= vector(#b), t ); x *= b[1]; for (i = 1, #b, a[i] = floor(x); t = x - a[i]; if (!t || i == #b, break); x = b[i+1] / t; ); a; }
There is some degree of freedom when choosing the \(a_i\); the program above can easily be modified to derive variants of the standard algorithm. In the same vein, although no builtin function implements the related Engel expansion (a special kind of Egyptian fraction decomposition: \(x = 1/a_1 + 1/(a_1a_2) +...\) ), it can be obtained as follows:
\\ n terms of the Engel expansion of x engel(x, n = 10) = { my( u = x, a = vector(n) ); for (k = 1, n, a[k] = ceil(1/u); u = u*a[k] - 1; if (!u, break); ); a }
Obsolete hack. (don’t use this): if \(b\) is an integer, nmax is ignored and the command is understood as
contfrac(:math:`x,, b
)`.
- contfraceval(t, lim)¶
Given a continued fraction
CF
output bycontfracinit
, evaluate the firstlim
terms of the continued fraction att
(all terms iflim
is negative or omitted; if positive,lim
must be less than or equal to the length ofCF
.
- contfracinit(lim)¶
Given \(M\) representing the power series \(S = \sum_{n >= 0} M[n+1]z^n\), transform it into a continued fraction in Euler form, using the quotient-difference algorithm; restrict to \(n <= lim\) if latter is nonnegative. \(M\) can be a vector, a power series, a polynomial; if the limiting parameter
lim
is present, a rational function is also allowed (and converted to a power series of that accuracy).The result is a 2-component vector \([A,B]\) such that \(S = M[1] / (1+A[1]z+B[1]z^2/(1+A[2]z+B[2]z^2/(1+...1/(1+A[lim/2]z))))\). Does not work if any coefficient of \(M\) vanishes, nor for series for which certain partial denominators vanish.
- contfracpnqn(n)¶
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,10) %1 = [3, 7, 15, 1, 292, 1, 1, 1, 3] ? allpnqn(x) = contfracpnqn(x,#x) \\ all convergents ? allpnqn(a) %3 = [3 22 333 355 103993 104348 208341 312689 1146408] [1 7 106 113 33102 33215 66317 99532 364913] ? contfracpnqn(a) \\ last two convergents %4 = [1146408 312689] [ 364913 99532] ? contfracpnqn(a,3) \\ first three convergents %5 = [3 22 333 355] [1 7 106 113]
- core(flag)¶
If \(n\) is an integer written as \(n = df^2\) with \(d\) squarefree, returns \(d\). If \(flag\) is nonzero, returns the two-element row vector \([d,f]\). By convention, we write \(0 = 0 x 1^2\), so
core(0, 1)
returns \([0,1]\).
- coredisc(flag)¶
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 nonzero integer \(n\), this routine returns the (unique) fundamental discriminant \(d\) such that \(n = df^2\), \(f\) a positive rational number. If \(flag\) is nonzero, 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 ascoredisc
\((n)\), and also works with rational inputs \(n\in\mathbb{Q}^*\).
- cos(precision)¶
Cosine of \(x\). Note that, for real \(x\), cosine and sine can be obtained simultaneously as
cs(x) = my(z = exp(I*x)); [real(z), imag(z)];
and for general complex \(x\) as
cs2(x) = my(z = exp(I*x), u = 1/z); [(z+u)/2, (z-u)/2];
Note that the latter function suffers from catastrophic cancellation when \(z^2 ~ ±1\).
- cosh(precision)¶
Hyperbolic cosine of \(x\).
- cotan(precision)¶
Cotangent of \(x\).
- cotanh(precision)¶
Hyperbolic cotangent of \(x\).
- denominator(D)¶
Denominator of \(f\). The meaning of this is clear when \(f\) is a rational number or function. If \(f\) 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(f) )
instead. As for modular objects,
t_INTMOD
andt_PADIC
have denominator \(1\), and the denominator of at_POLMOD
is the denominator of its lift.If \(f\) 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 andt_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).The optional argument \(D\) allows to control over which ring we compute the denominator and get a more predictable behaviour:
\(1\): we only consider the underlying \(\mathbb{Q}\)-structure and the denominator is a (positive) rational integer
a simple variable, say
'x
: all entries as rational functions in \(K(x)\) and the denominator is a polynomial in \(x\).
? f = x + 1/y + 1/2; ? denominator(f) \\ a t_POL in x %2 = 1 ? denominator(f, 1) \\ Q-denominator %3 = 2 ? denominator(f, x) \\ as a t_POL in x, seen above %4 = 1 ? denominator(f, y) \\ as a rational function in y %5 = 2*y
- deriv(v)¶
Derivative of \(x\) with respect to the main variable if \(v\) is omitted, and with respect to \(v\) otherwise. The derivative of a scalar type is zero, and the derivative of a vector or matrix is done componentwise. One can use \(x'\) as a shortcut if the derivative is with respect to the main variable of \(x\); and also use \(x"\), etc., for multiple derivatives altough
derivn
is often preferrable.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\).? f = (x/y)^5; ? deriv(f) %2 = 5/y^5*x^4 ? f' %3 = 5/y^5*x^4 ? deriv(f, 'x) \\ same since 'x is the main variable %4 = 5/y^5*x^4 ? deriv(f, 'y) %5 = -5/y^6*x^5
This function also operates on closures, in which case the variable must be omitted. It returns a closure performing a numerical differentiation as per
derivnum
:? f(x) = x^2; ? g = deriv(f) ? g(1) %3 = 2.0000000000000000000000000000000000000 ? f(x) = sin(exp(x)); ? deriv(f)(0) %5 = 0.54030230586813971740093660744297660373 ? cos(1) %6 = 0.54030230586813971740093660744297660373
- derivn(n, v)¶
\(n\)-th derivative of \(x\) with respect to the main variable if \(v\) is omitted, and with respect to \(v\) otherwise; the integer \(n\) must be nonnegative. The derivative of a scalar type is zero, and the derivative of a vector or matrix is done componentwise. One can use \(x'\), \(x"\), etc., 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\).? f = (x/y)^5; ? derivn(f, 2) %2 = 20/y^5*x^3 ? f'' %3 = 20/y^5*x^3 ? derivn(f, 2, 'x) \\ same since 'x is the main variable %4 = 20/y^5*x^3 ? derivn(f, 2, 'y) %5 = 30/y^7*x^5
This function also operates on closures, in which case the variable must be omitted. It returns a closure performing a numerical differentiation as per
derivnum
:? f(x) = x^10; ? g = derivn(f, 5) ? g(1) %3 = 30240.000000000000000000000000000000000 ? derivn(zeta, 2)(0) %4 = -2.0063564559085848512101000267299604382 ? zeta''(0) %5 = -2.0063564559085848512101000267299604382
- diffop(v, d, n)¶
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 variablev[i]
. The value of \(D\) on a scalar type is zero, and \(D\) applies componentwise to a vector or matrix. When applied to at_POLMOD
, if no value is provided for the variable of the modulus, such value is derived using the implicit function theorem.Examples. This function can be used to differentiate formal expressions: if \(E = \exp (X^2)\) then we have \(E' = 2*X*E\). We derivate \(X*exp(X^2)\) as follows:
? diffop(E*X,[X,E],[1,2*X*E]) %1 = (2*X^2 + 1)*E
Let
Sin
andCos
be two function such that \(Sin^2+Cos^2 = 1\) and \(Cos' = -Sin\). We can differentiate \(Sin/Cos\) as follows, 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(x, v, dv, var = i->eval(Str("X",i))); 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), polcoef(x,n,'X)); }
- digits(b)¶
Outputs the vector of the digits of \(\|x\|\) in base \(b\), where \(x\) and \(b\) are integers (\(b = 10\) by default). For \(x >= 1\), the number of digits is \(logint (x,b) + 1\). See
fromdigits
for the reverse operation.? digits(1230) %1 = [1, 2, 3, 0] ? digits(10, 2) \\ base 2 %2 = [1, 0, 1, 0]
By convention, \(0\) has no digits:
? digits(0) %3 = []
- dilog(precision)¶
Principal branch of the dilogarithm of \(x\), i.e. analytic continuation of the power series \(\log_2(x) = \sum_{n >= 1}x^n/n^2\).
- dirdiv(y)¶
\(x\) and \(y\) being vectors of perhaps different lengths but with \(y[1] != 0\) considered as Dirichlet series, computes the quotient of \(x\) by \(y\), again as a vector.
- dirmul(y)¶
\(x\) and \(y\) being vectors of perhaps different lengths representing the Dirichlet series \(\sum_n x_n n^{-s}\) and \(\sum_n y_n n^{-s}\), computes the product of \(x\) by \(y\), again as a vector.
? dirmul(vector(10,n,1), vector(10,n,moebius(n))) %1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
The product length is the minimum of \(\# x* v(y)\) and \(\# y* v(x)\), where \(v(x)\) is the index of the first nonzero coefficient.
? dirmul([0,1], [0,1]); %2 = [0, 0, 0, 1]
- dirpowerssum(x, precision)¶
For positive integer \(n\) and complex number \(x\), return the sum \(1^x + 2^x +...+ n^x\). This is the same as
vecsum(dirpowers(n,x))
, but faster and using only \(O(\sqrt{n})\) memory instead of \(O(n)\).? dirpowers(5, 2) %1 = [1, 4, 9, 16, 25] ? vecsum(%) %2 = 55 ? dirpowerssum(5, 2) %3 = 55 ? \p200 ? dirpowerssum(10^7, 1/2 + I * sqrt(3)); time = 29,884 ms. ? vecsum(dirpowers(10^7, 1/2 + I * sqrt(3))) time = 41,894 ms.
The penultimate command works with default stack size, the last one requires a stacksize of at least 5GB.
When \(n <= 0\), the function returns \(0\).
- dirzetak(b)¶
Gives as a vector the first \(b\) coefficients of the Dedekind zeta function of the number field \(nf\) considered as a Dirichlet series.
- divisors(flag)¶
Creates a row vector whose components are the divisors of \(x\). The factorization of \(x\) (as output by
factor
) can be used instead. If \(flag = 1\), return pairs \([d, factor (d)]\).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.? divisors(12) %1 = [1, 2, 3, 4, 6, 12] ? divisors(12, 1) \\ include their factorization %2 = [[1, matrix(0,2)], [2, Mat([2, 1])], [3, Mat([3, 1])], [4, Mat([2, 2])], [6, [2, 1; 3, 1]], [12, [2, 2; 3, 1]]] ? divisors(x^4 + 2*x^3 + x^2) \\ also works for polynomials %3 = [1, x, x^2, x + 1, x^2 + x, x^3 + x^2, x^2 + 2*x + 1, x^3 + 2*x^2 + x, x^4 + 2*x^3 + x^2]
This function requires a lot of memory if \(x\) has many divisors. The following idiom runs through all divisors using very little memory, in no particular order this time:
F = factor(x); P = F[,1]; E = F[,2]; forvec(e = vectorv(#E,i,[0,E[i]]), d = factorback(P,e); ...)
If the factorization of \(d\) is also desired, then \([P,e]\) almost provides it but not quite: \(e\) may contain \(0\) exponents, which are not allowed in factorizations. These must be sieved out as in:
tofact(P,E) = my(v = select(x->x, E, 1)); Mat([vecextract(P,v), vecextract(E,v)]); ? tofact([2,3,5,7]~, [4,0,2,0]~) %4 = [2 4] [5 2]
We can then run the above loop with
tofact(P,e)
instead of, or together with,factorback
.
- divisorslenstra(r, s)¶
Given three integers \(N > s > r >= 0\) such that \((r,s) = 1\) and \(s^3 > N\), find all divisors \(d\) of \(N\) such that \(d = r (mod s)\). There are at most \(11\) such divisors (Lenstra).
? N = 245784; r = 19; s = 65 ; ? divisorslenstra(N, r, s) %2 = [19, 84, 539, 1254, 3724, 245784] ? [ d | d <- divisors(N), d % s == r] %3 = [19, 84, 539, 1254, 3724, 245784]
When the preconditions are not met, the result is undefined:
? N = 4484075232; r = 7; s = 1303; s^3 > N %4 = 0 ? divisorslenstra(N, r, s) ? [ d | d <- divisors(N), d % s == r ] %6 = [7, 2613, 9128, 19552, 264516, 3407352, 344928864]
(Divisors were missing but \(s^3 < N\).)
- divrem(y, v)¶
Creates a column vector with two components, the first being the Euclidean quotient (
:math:`x
\:math:y`), the second the Euclidean remainder (:math:`x
- (\(x\)\:math:y)*:math:y`), of the division of \(x\) by \(y\). This avoids the need to do two divisions if one needs both the quotient and the remainder. If \(v\) is present, and \(x\), \(y\) are multivariate polynomials, divide with respect to the variable \(v\).Beware that
divrem(:math:`x
,:math:y)[2]` is in general not the same as:math:`x
% \(y\); no GP operator corresponds to it:? divrem(1/2, 3)[2] %1 = 1/2 ? (1/2) % 3 %2 = 2 ? divrem(Mod(2,9), 3)[2] *** at top-level: divrem(Mod(2,9),3)[2 *** ^-------------------- *** forbidden division t_INTMOD \ t_INT. ? Mod(2,9) % 6 %3 = Mod(2,3)
- eint1(n, precision)¶
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 at_REAL
and defaults torealprecision
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 callingeint1(:math:`i
* x)`, but less precise.
- ellE(precision)¶
Complete elliptic integral of the second kind
\[E(k) = \int_0^{\pi/2}(1-k^2\sin (t)^2)^{1/2}dt\]for the complex parameter \(k\) using the agm.
- ellK(precision)¶
Complete elliptic integral of the first kind
\[K(k) = \int_0^{\pi/2}(1-k^2\sin (t)^2)^{-1/2}dt\]for the complex parameter \(k\) using the agm.
- ellL1(r, precision)¶
Returns the value at \(s = 1\) of the derivative of order \(r\) of the \(L\)-function of the elliptic curve \(E\).
? E = ellinit("11a1"); \\ order of vanishing is 0 ? ellL1(E) %2 = 0.2538418608559106843377589233 ? E = ellinit("389a1"); \\ order of vanishing is 2 ? ellL1(E) %4 = -5.384067311837218089235032414 E-29 ? ellL1(E, 1) %5 = 0 ? ellL1(E, 2) %6 = 1.518633000576853540460385214
The main use of this function, after computing at low accuracy the order of vanishing using
ellanalyticrank
, is to compute the leading term at high accuracy to check (or use) the Birch and Swinnerton-Dyer conjecture:? \p18 realprecision = 18 significant digits ? E = ellinit("5077a1"); ellanalyticrank(E) time = 8 ms. %1 = [3, 10.3910994007158041] ? \p200 realprecision = 202 significant digits (200 digits displayed) ? ellL1(E, 3) time = 104 ms. %3 = 10.3910994007158041387518505103609170697263563756570092797[...]
- elladd(z1, z2)¶
Sum of the points \(z1\) and \(z2\) on the elliptic curve corresponding to \(E\).
- ellak(n)¶
Computes the coefficient \(a_n\) of the \(L\)-function of the elliptic curve \(E/\mathbb{Q}\), i.e. coefficients of a newform of weight 2 by the modularity theorem (Taniyama-Shimura-Weil conjecture). \(E\) must be an
ell
structure over \(\mathbb{Q}\) as output byellinit
. \(E\) must be given by an integral model, not necessarily minimal, although a minimal model will make the function faster.? E = ellinit([1,-1,0,4,3]); ? ellak(E, 10) %2 = -3 ? e = ellchangecurve(E, [1/5,0,0,0]); \\ made not minimal at 5 ? ellak(e, 10) \\ 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 = 699 ms. ? for(i=1,10^6, ellak(e,5)) \\ 5 is bad, markedly slower time = 1,079 ms. ? for(i=1,10^5,ellak(E,5*i)) time = 1,477 ms. ? for(i=1,10^5,ellak(e,5*i)) \\ still slower but not so much on average time = 1,569 ms.
- ellan(n)¶
Computes the vector of the first \(n\) Fourier coefficients \(a_k\) corresponding to the elliptic curve \(E\) defined over a number field. If \(E\) is defined over \(\mathbb{Q}\), the curve may be given by an arbitrary model, not necessarily minimal, although a minimal model will make the function faster. Over a more general number field, the model must be locally minimal at all primes above \(2\) and \(3\).
- ellanalyticrank(eps, precision)¶
Returns the order of vanishing at \(s = 1\) of the \(L\)-function of the elliptic curve \(E\) and the value of the first nonzero derivative. To determine this order, it is assumed that any value less than
eps
is zero. Ifeps
is omitted, \(2^{-b/2}\) is used, where \(b\) is the current bit precision.? E = ellinit("11a1"); \\ rank 0 ? ellanalyticrank(E) %2 = [0, 0.2538418608559106843377589233] ? E = ellinit("37a1"); \\ rank 1 ? ellanalyticrank(E) %4 = [1, 0.3059997738340523018204836835] ? E = ellinit("389a1"); \\ rank 2 ? ellanalyticrank(E) %6 = [2, 1.518633000576853540460385214] ? E = ellinit("5077a1"); \\ rank 3 ? ellanalyticrank(E) %8 = [3, 10.39109940071580413875185035]
- ellap(p)¶
Let
E
be anell
structure as output byellinit
, attached to an elliptic curve \(E/K\). If the field \(K = \mathbb{F}_q\) is finite, return the trace of Frobenius \(t\), defined by the equation \(\#E(\mathbb{F}_q) = q+1 - t\).For other fields of definition and \(p\) defining a finite residue field \(\mathbb{F}_q\), return the trace of Frobenius for the reduction of \(E\): the argument \(p\) is best left omitted if \(K = \mathbb{Q}_\ell\) (else we must have \(p = \ell\)) and must be a prime number (\(K = \mathbb{Q}\)) or prime ideal (\(K\) a general number field) with residue field \(\mathbb{F}_q\) otherwise. The equation need not be minimal or even integral at \(p\); of course, a minimal model will be more efficient.
For a number field \(K\), the trace of Frobenius is the \(a_p\) coefficient in the Euler product defining the curve \(L\)-series, whence the function name:
\[L(E/K,s) = \prod_{bad p} (1-a_p (Np)^{-s})^{-1} \prod_{good p} (1-a_p (Np)^{-s} + (Np)^{1-2s})^{-1}.\]When the characteristic of the finite field is large, the availability of the
seadata
package will speed up the computation.? 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 ? a = ffgen(ffinit(11,3), 'a); \\ defines F_q := F_{11^3} ? E = ellinit([a+1,a]); \\ y^2 = x^3 + (a+1)x + a, defined over F_q ? ellap(E) %8 = -3
If the curve is defined over a more general number field than \(\mathbb{Q}\), the maximal ideal \(p\) must be explicitly given in
idealprimedec
format. There is no assumption of local minimality at \(p\).? K = nfinit(a^2+1); E = ellinit([1+a,0,1,0,0], K); ? fa = idealfactor(K, E.disc) %2 = [ [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]] 1] [[13, [5, 1]~, 1, 1, [-5, -1; 1, -5]] 2] ? ellap(E, fa[1,1]) %3 = -1 \\ nonsplit multiplicative reduction ? ellap(E, fa[2,1]) %4 = 1 \\ split multiplicative reduction ? P17 = idealprimedec(K,17)[1]; ? ellap(E, P17) %6 = 6 \\ good reduction ? E2 = ellchangecurve(E, [17,0,0,0]); ? ellap(E2, P17) %8 = 6 \\ same, starting from a nonmiminal model ? P3 = idealprimedec(K,3)[1]; ? ellap(E, P3) \\ OK: E is minimal at P3 %10 = -2 ? E3 = ellchangecurve(E, [3,0,0,0]); ? ellap(E3, P3) \\ not integral at P3 *** at top-level: ellap(E3,P3) *** ^------------ *** ellap: impossible inverse in Rg_to_ff: Mod(0, 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\) bit operations. 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. Above this range, the
SEA
algorithm becomes available, heuristically in \(~{O}(\log q)^4\), and primes of the order of 200 digits become feasible. In small characteristic we use Mestre’s (p = 2), Kohel’s (p = 3,5,7,13), Satoh-Harley (all in \(~{O}(p^{2} n^2)\)) or Kedlaya’s (in \(~{O}(p n^3)\)) algorithms.
- ellbil(z1, z2, precision)¶
Deprecated alias for
ellheight(E,P,Q)
.
- ellbsd(precision)¶
The object \(E\) being an elliptic curve over a number field, returns a real number \(c\) such that the BSD conjecture predicts that \(L_{E}^{(r)}(1)/r != c R S\) where \(r\) is the rank, \(R\) the regulator and \(S\) the cardinal of the Tate-Shafarevich group.
? e = ellinit([0,-1,1,-10,-20]); \\ rank 0 ? ellbsd(e) %2 = 0.25384186085591068433775892335090946105 ? lfun(e,1) %3 = 0.25384186085591068433775892335090946104 ? e = ellinit([0,0,1,-1,0]); \\ rank 1 ? P = ellheegner(e); ? ellbsd(e)*ellheight(e,P) %6 = 0.30599977383405230182048368332167647445 ? lfun(e,1,1) %7 = 0.30599977383405230182048368332167647445 ? e = ellinit([1+a,0,1,0,0],nfinit(a^2+1)); \\ rank 0 ? ellbsd(e) %9 = 0.42521832235345764503001271536611593310 ? lfun(e,1) %10 = 0.42521832235345764503001271536611593309
- ellcard(p)¶
Let
E
be anell
structure as output byellinit
, attached to an elliptic curve \(E/K\). If \(K = \mathbb{F}_q\) is finite, return the order of the group \(E(\mathbb{F}_q)\).? E = ellinit([-3,1], 5); ellcard(E) %1 = 7 ? t = ffgen(3^5,'t); E = ellinit([t,t^2+1]); ellcard(E) %2 = 217
For other fields of definition and \(p\) defining a finite residue field \(\mathbb{F}_q\), return the order of the reduction of \(E\): the argument \(p\) is best left omitted if \(K = \mathbb{Q}_\ell\) (else we must have \(p = \ell\)) and must be a prime number (\(K = \mathbb{Q}\)) or prime ideal (\(K\) a general number field) with residue field \(\mathbb{F}_q\) otherwise. The equation need not be minimal or even integral at \(p\); of course, a minimal model will be more efficient. The function considers the group of nonsingular points of the reduction of a minimal model of the curve at \(p\), so also makes sense when the curve has bad reduction.
? E = ellinit([-3,1]); ? factor(E.disc) %2 = [2 4] [3 4] ? ellcard(E, 5) \\ as above ! %3 = 7 ? ellcard(E, 2) \\ additive reduction %4 = 2
When the characteristic of the finite field is large, the availability of the
seadata
package will speed the computation. See alsoellap
for the list of implemented algorithms.
- ellchangecurve(v)¶
Changes the data for the elliptic curve \(E\) by changing the coordinates using the vector
v = [u,r,s,t]
, i.e. if \(x'\) and \(y'\) are the new coordinates, then \(x = u^2x'+r\), \(y = u^3y'+su^2x'+t\). \(E\) must be anell
structure as output byellinit
. The special case \(v = 1\) is also used instead of \([1,0,0,0]\) to denote the trivial coordinate change.
- ellchangepoint(v)¶
Changes the coordinates of the point or vector of points \(x\) using the vector
v = [u,r,s,t]
, i.e. if \(x'\) and \(y'\) are the new coordinates, then \(x = u^2x'+r\), \(y = u^3y'+su^2x'+t\) (see alsoellchangecurve
).? E0 = ellinit([1,1]); P0 = [0,1]; v = [1,2,3,4]; ? E = ellchangecurve(E0, v); ? P = ellchangepoint(P0,v) %3 = [-2, 3] ? ellisoncurve(E, P) %4 = 1 ? ellchangepointinv(P,v) %5 = [0, 1]
- ellchangepointinv(v)¶
Changes the coordinates of the point or vector of points \(x\) using the inverse of the isomorphism attached 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 ofellchangepoint
).? E0 = ellinit([1,1]); P0 = [0,1]; v = [1,2,3,4]; ? E = ellchangecurve(E0, v); ? P = ellchangepoint(P0,v) %3 = [-2, 3] ? ellisoncurve(E, P) %4 = 1 ? ellchangepointinv(P,v) %5 = [0, 1] \\ we get back P0
- ellconvertname()¶
Converts an elliptic curve name, as found in the
elldata
database, from a string to a triplet \([conductor, isogeny class, index]\). It will also convert a triplet back to a curve name. Examples:? ellconvertname("123b1") %1 = [123, 1, 1] ? ellconvertname(%) %2 = "123b1"
- elldivpol(n, v)¶
\(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 and any integer \(n >= 0\), we have
\[[n]P = (\phi_n(P)\psi_n(P) : \omega_n(P) : \psi_n(P)^3)\]for some polynomials \(\phi_n,\omega_n,\psi_n\) in \(\mathbb{Z}[a_1,a_2,a_3,a_4,a_6][X,Y]\). We have \(f_n(X) = \psi_n(X)\) for \(n\) odd, and \(f_n(X) = \psi_n(X,Y) (2Y + a_1X+a_3)\) for \(n\) even. We have
\[f_0 = 0, f_1 = 1, f_2 = 4X^3 + b_2X^2 + 2b_4 X + b_6, f_3 = 3 X^4 + b_2 X^3 + 3b_4 X^2 + 3 b_6 X + b8,\]\[f_4 = f_2(2X^6 + b_2 X^5 + 5b_4 X^4 + 10 b_6 X^3 + 10 b_8 X^2 + (b_2b_8-b_4b_6)X + (b_8b_4 - b_6^2)),...\]When \(n\) is odd, the roots of \(f_n\) are the \(X\)-coordinates of the affine points in the \(n\)-torsion subgroup \(E[n]\); when \(n\) is even, the roots of \(f_n\) are the \(X\)-coordinates of the affine points in \(E[n] \ E[2]\) when \(n > 2\), resp. in \(E[2]\) when \(n = 2\). For \(n < 0\), we define \(f_n := - f_{-n}\).
- elleisnum(k, flag, precision)¶
\(k\) being an even positive integer, computes the numerical value of the Eisenstein series of weight \(k\) at the lattice \(w\), as given by
ellperiods
, namely\[(2i \pi/\omega_2)^k (1 + 2/\zeta (1-k) \sum_{n >= 1} n^{k-1}q^n / (1-q^n)),\]where \(q = \exp (2i\pi \tau)\) and \(\tau := \omega_1/\omega_2\) belongs to the complex upper half-plane. It is also possible to directly input \(w = [\omega_1,\omega_2]\), or an elliptic curve \(E\) as given by
ellinit
.? w = ellperiods([1,I]); ? elleisnum(w, 4) %2 = 2268.8726415508062275167367584190557607 ? elleisnum(w, 6) %3 = -3.977978632282564763 E-33 ? E = ellinit([1, 0]); ? elleisnum(E, 4) %5 = -48.000000000000000000000000000000000000
When flag is nonzero and \(k = 4\) or 6, returns the elliptic invariants \(g_2\) or \(g_3\), such that
\[y^2 = 4x^3 - g_2 x - g_3\]is a Weierstrass equation for \(E\).
? g2 = elleisnum(E, 4, 1) %6 = -4.0000000000000000000000000000000000000 ? g3 = elleisnum(E, 6, 1) \\ ~ 0 %7 = 0.E-114 - 3.909948178422242682 E-57*I
- elleta(precision)¶
Returns the quasi-periods \([\eta_1,\eta_2]\) attached 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 attached to the period lattice basis:math:`E
.omega` (namely,:math:`E
.eta`) are returned.? elleta([1, I]) %1 = [3.141592653589793238462643383, 9.424777960769379715387930149*I]
- ellformaldifferential(serprec, n)¶
Let \(\omega := dx / (2y+a_1x+a_3)\) be the invariant differential form attached to the model \(E\) of some elliptic curve (
ellinit
form), and \(\eta := x(t)\omega\). Return \(n\) terms (seriesprecision
by default) of \(f(t),g(t)\) two power series in the formal parameter \(t = -x/y\) such that \(\omega = f(t) dt\), \(\eta = g(t) dt\):\[f(t) = 1+a_1 t + (a_1^2 + a_2) t^2 +..., g(t) = t^{-2} +...\]? E = ellinit([-1,1/4]); [f,g] = ellformaldifferential(E,7,'t); ? f %2 = 1 - 2*t^4 + 3/4*t^6 + O(t^7) ? g %3 = t^-2 - t^2 + 1/2*t^4 + O(t^5)
- ellformalexp(serprec, n)¶
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 (seeellformallog
): \(Exp o L = \mathrm{Id}\). Return \(n\) terms of this power series:? E=ellinit([-1,1/4]); Exp = ellformalexp(E,10,'z) %1 = z + 2/5*z^5 - 3/28*z^7 + 2/15*z^9 + O(z^11) ? L = ellformallog(E,10,'t); ? subst(Exp,z,L) %3 = t + O(t^11)
- ellformallog(serprec, n)¶
The formal elliptic logarithm is a series \(L\) in \(t K[[t]]\) such that \(d L = \omega = dx / (2y + a_1x + a_3)\), the canonical invariant differential attached to the model \(E\). It gives an isomorphism from the formal group of \(E\) to the additive formal group.
? E = ellinit([-1,1/4]); L = ellformallog(E, 9, 't) %1 = t - 2/5*t^5 + 3/28*t^7 + 2/3*t^9 + O(t^10) ? [f,g] = ellformaldifferential(E,8,'t); ? L' - f %3 = O(t^8)
- ellformalpoint(serprec, n)¶
If \(E\) is an elliptic curve, return the coordinates \(x(t), y(t)\) in the formal group of the elliptic curve \(E\) in the formal parameter \(t = -x/y\) at \(oo\):
\[x = t^{-2} -a_1 t^{-1} - a_2 - a_3 t +...\]\[y = - t^{-3} -a_1 t^{-2} - a_2t^{-1} -a_3 +...\]Return \(n\) terms (
seriesprecision
by default) of these two power series, whose coefficients are in \(\mathbb{Z}[a_1,a_2,a_3,a_4,a_6]\).? E = ellinit([0,0,1,-1,0]); [x,y] = ellformalpoint(E,8,'t); ? x %2 = t^-2 - t + t^2 - t^4 + 2*t^5 + O(t^6) ? y %3 = -t^-3 + 1 - t + t^3 - 2*t^4 + O(t^5) ? E = ellinit([0,1/2]); ellformalpoint(E,7) %4 = [x^-2 - 1/2*x^4 + O(x^5), -x^-3 + 1/2*x^3 + O(x^4)]
- ellformalw(serprec, n)¶
Return the formal power series \(w\) attached to the elliptic curve \(E\), in the variable \(t\):
\[w(t) = t^3(1 + a_1 t + (a_2 + a_1^2) t^2 +...+ O(t^{n})),\]which is the formal expansion of \(-1/y\) in the formal parameter \(t := -x/y\) at \(oo\) (take \(n = seriesprecision\) if \(n\) is omitted). The coefficients of \(w\) belong to \(\mathbb{Z}[a_1,a_2,a_3,a_4,a_6]\).
? E=ellinit([3,2,-4,-2,5]); ellformalw(E, 5, 't) %1 = t^3 + 3*t^4 + 11*t^5 + 35*t^6 + 101*t^7 + O(t^8)
- ellfromeqn()¶
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 Edwards 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); ? isprime(ellcard(E) / 8) %3 = 1
The elliptic curve attached 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\).
? En = 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(En, n, 23)) ) %2 = [168100/289, 68053440/4913]
- ellfromj()¶
Returns the coefficients \([a_1,a_2,a_3,a_4,a_6]\) of a fixed elliptic curve with \(j\)-invariant \(j\).
- ellgenerators()¶
If \(E\) is an elliptic curve over the rationals, return a \(\mathbb{Z}\)-basis of the free part of the Mordell-Weil group attached 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 byellinit
, return a minimal set of generators for the group \(E(\mathbb{F}_q)\).Caution. When the group is not cyclic, of shape \(\mathbb{Z}/d_1\mathbb{Z} x \mathbb{Z}/d_2\mathbb{Z}\) with \(d_2 \| d_1\), the points \([P,Q]\) returned by ellgenerators need not have order \(d_1\) and \(d_2\): it is true that \(P\) has order \(d_1\), but we only know that \(Q\) is a generator of \(E(\mathbb{F}_q)/ <P>\) and that the Weil pairing \(w(P,Q)\) has order \(d_2\), see
??ellgroup
. If you need generators \([P,R]\) with \(R\) of order \(d_2\), find \(x\) such that \(R = Q-[x]P\) has order \(d_2\) by solving the discrete logarithm problem \([d_2]Q = [x]([d_2]P)\) in a cyclic group of order \(d_1/d_2\). This will be very expensive if \(d_1/d_2\) has a large prime factor.
- ellglobalred()¶
Let \(E\) be an
ell
structure as output byellinit
attached to an elliptic curve defined over a number field. This function calculates the arithmetic conductor and the global Tamagawa number \(c\). The result \([N,v,c,F,L]\) is slightly different if \(E\) is defined over \(\mathbb{Q}\) (domain \(D = 1\) inellinit
) or over a number field (domain \(D\) is a number field structure, includingnfinit(x)
representing \(\mathbb{Q}\) !):\(N\) is the arithmetic conductor of the curve,
\(v\) is an obsolete field, left in place for backward compatibility. If \(E\) is defined over \(\mathbb{Q}\), \(v\) gives the coordinate change for \(E\) to the standard minimal integral model (
ellminimalmodel
provides it in a cheaper way); if \(E\) is defined over another number field, \(v\) gives a coordinate change to an integral model (ellintegralmodel
provides it in a cheaper way).\(c\) is the product of the local Tamagawa numbers \(c_p\), a quantity which enters in the Birch and Swinnerton-Dyer conjecture,
\(F\) is the factorization of \(N\),
\(L\) is a vector, whose \(i\)-th entry contains the local data at the \(i\)-th prime ideal divisor of \(N\), i.e.
L[i] = elllocalred(E,F[i,1])
. If \(E\) is defined over \(\mathbb{Q}\), the local coordinate change has been deleted and replaced by a 0; if \(E\) is defined over another number field the local coordinate change to a local minimal model is given relative to the integral model afforded by \(v\) (so either start from an integral model so that \(v\) be trivial, or apply \(v\) first).
- ellgroup(p, flag)¶
Let
E
be anell
structure as output byellinit
, attached to an elliptic curve \(E/K\). We first describle the function when the field \(K = \mathbb{F}_q\) is finite, it computes the structure of the finite abelian group \(E(\mathbb{F}_q)\):if \(flag = 0\), return the structure \([]\) (trivial group) or \([d_1]\) (nontrivial cyclic group) or \([d_1,d_2]\) (noncyclic group) of \(E(\mathbb{F}_q) ~ \mathbb{Z}/d_1\mathbb{Z} x \mathbb{Z}/d_2\mathbb{Z}\), with \(d_2 \| d_1\).
if \(flag = 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, d_1)\) has order \(d_2\).
For other fields of definition and \(p\) defining a finite residue field \(\mathbb{F}_q\), return the structure of the reduction of \(E\): the argument \(p\) is best left omitted if \(K = \mathbb{Q}_\ell\) (else we must have \(p = \ell\)) and must be a prime number (\(K = \mathbb{Q}\)) or prime ideal (\(K\) a general number field) with residue field \(\mathbb{F}_q\) otherwise. The curve is allowed to have bad reduction at \(p\) and in this case we consider the (cyclic) group of nonsingular points for the reduction of a minimal model at \(p\).
If \(flag = 0\), the equation not be minimal or even integral at \(p\); of course, a minimal model will be more efficient.
If \(flag = 1\), the requested generators depend on the model, which must then be minimal at \(p\), otherwise an exception is thrown. Use
ellintegralmodel
and/orellocalred
first to reduce to this case.? 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, noncyclic ? 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)]]]
Let us now consider curves of bad reduction, in this case we return the structure of the (cyclic) group of nonsingular 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 \\ nonsplit multiplicative reduction at 7
- ellheegner()¶
Let \(E\) be an elliptic curve over the rationals, assumed to be of (analytic) rank \(1\). This returns a nontorsion rational point on the curve, whose canonical height is equal to the product of the elliptic regulator by the analytic Sha.
This uses the Heegner point method, described in Cohen GTM 239; the complexity is proportional to the product of the square root of the conductor and the height of the point (thus, it is preferable to apply it to strong Weil curves).
? E = ellinit([-157^2,0]); ? u = ellheegner(E); print(u[1], "\n", u[2]) 69648970982596494254458225/166136231668185267540804 538962435089604615078004307258785218335/67716816556077455999228495435742408 ? ellheegner(ellinit([0,1])) \\ E has rank 0 ! *** at top-level: ellheegner(E=ellinit *** ^-------------------- *** ellheegner: The curve has even analytic rank.
- ellheight(P, Q, precision)¶
Let \(E\) be an elliptic curve defined over \(K = \mathbb{Q}\) or a number field, as output by
ellinit
; it needs not be given by a minimal model although the computation will be faster if it is.Without arguments \(P,Q\), returns the Faltings height of the curve \(E\) using Deligne normalization. For a rational curve, the normalization is such that the function returns
-(1/2)*log(ellminimalmodel(E).area)
.If the argument \(P \in E(K)\) is present, returns the global Néron-Tate height \(h(P)\) of the point, using the normalization in Cremona’s Algorithms for modular elliptic curves.
If the argument \(Q \in E(K)\) is also present, computes the value of the bilinear form \((h(P+Q)-h(P-Q)) / 4\).
- ellheightmatrix(x, precision)¶
\(x\) being a vector of points, this function outputs the Gram matrix of \(x\) with respect to the Néron-Tate height, in other words, the \((i,j)\) component of the matrix is equal to
ellbil(:math:`E
,x[\(i\)],x[\(j\)])`. The rank of this matrix, at least in some approximate sense, gives the rank of the set of points, and if \(x\) is a basis of the Mordell-Weil group of \(E\), its determinant is equal to the regulator of \(E\). Note our height normalization follows Cremona’s Algorithms for modular elliptic curves: this matrix should be divided by 2 to be in accordance with, e.g., Silverman’s normalizations.
- ellidentify()¶
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 from \(E\) to \(M\), suitable forellchangecurve
.
- ellinit(D, precision)¶
Initialize an
ell
structure, attached to the elliptic curve \(E\). \(E\) is eithera \(5\)-component vector \([a_1,a_2,a_3,a_4,a_6]\) defining the elliptic curve with Weierstrass equation
\[Y^2 + a_1 XY + a_3 Y = X^3 + a_2 X^2 + a_4 X + a_6,\]a \(2\)-component vector \([a_4,a_6]\) defining the elliptic curve with short Weierstrass equation
\[Y^2 = X^3 + a_4 X + a_6,\]a character string in Cremona’s notation, e.g.
"11a1"
, in which case the curve is retrieved from theelldata
database if available.
The optional argument \(D\) describes the domain over which the curve is defined:
the
t_INT
\(1\) (default): the field of rational numbers \(\mathbb{Q}\).a
t_INT
\(p\), where \(p\) is a prime number: the prime finite field \(\mathbb{F}_p\).an
t_INTMOD
Mod(a, p)
, where \(p\) is a prime number: the prime finite field \(\mathbb{F}_p\).a
t_FFELT
, as returned byffgen
: the corresponding finite field \(\mathbb{F}_q\).a
t_PADIC
, \(O(p^n)\): the field \(\mathbb{Q}_p\), where \(p\)-adic quantities will be computed to a relative accuracy of \(n\) digits. We advise to input a model defined over \(\mathbb{Q}\) for such curves. In any case, if you input an approximate model witht_PADIC
coefficients, it will be replaced by a lift to \(\mathbb{Q}\) (an exact model “close” to the one that was input) and all quantities will then be computed in terms of this lifted model, at the given accuracy.a
t_REAL
\(x\): the field \(\mathbb{C}\) of complex numbers, where floating point quantities are by default computed to a relative accuracy ofprecision
\((x)\). If no such argument is given, the value ofrealprecision
at the timeellinit
is called will be used.a number field \(K\), given by a
nf
orbnf
structure; abnf
is required forellminimalmodel
.a prime ideal \(p\), given by a
prid
structure; valid if \(x\) is a curve defined over a number field \(K\) and the equation is integral and minimal at \(p\).
This argument \(D\) is indicative: the curve coefficients are checked for compatibility, possibly changing \(D\); for instance if \(D = 1\) and an
t_INTMOD
is found. If inconsistencies are detected, an error is raised:? ellinit([1 + O(5), 1], O(7)); *** at top-level: ellinit([1+O(5),1],O *** ^-------------------- *** ellinit: inconsistent moduli in ellinit: 7 != 5
If the curve coefficients are too general to fit any of the above domain categories, only basic operations, such as point addition, will be supported later.
If the curve (seen over the domain \(D\)) is singular, fail and return an empty vector \([]\).
? E = ellinit([0,0,0,0,1]); \\ y^2 = x^3 + 1, over Q ? E = ellinit([0,1]); \\ the same curve, short form ? E = ellinit("36a1"); \\ sill the same curve, Cremona's notations ? E = ellinit([0,1], 2) \\ over F2: singular curve %4 = [] ? E = ellinit(['a4,'a6] * Mod(1,5)); \\ over F_5[a4,a6], basic support !
The result of
ellinit
is an ell structure. It contains at least the following information in its components:\[a_1,a_2,a_3,a_4,a_6,b_2,b_4,b_6,b_8,c_4,c_6,\Delta,j.\]All are accessible via member functions. In particular, the discriminant is
:math:`E
.disc`, and the \(j\)-invariant is:math:`E
.j`.? E = ellinit([a4, a6]); ? E.disc %2 = -64*a4^3 - 432*a6^2 ? E.j %3 = -6912*a4^3/(-4*a4^3 - 27*a6^2)
Further components contain domain-specific data, which are in general dynamic: only computed when needed, and then cached in the structure.
? E = ellinit([2,3], 10^60+7); \\ E over F_p, p large ? ellap(E) time = 4,440 ms. %2 = -1376268269510579884904540406082 ? ellcard(E); \\ now instantaneous ! time = 0 ms. ? ellgenerators(E); time = 5,965 ms. ? ellgenerators(E); \\ second time instantaneous time = 0 ms.
See the description of member functions related to elliptic curves at the beginning of this section.
- ellintegralmodel(v)¶
Let \(E\) be an
ell
structure over a number field \(K\) or \(\mathbb{Q}_p\). This function returns an integral model. If \(v\) is present, sets \(v = [u,0,0,0]\) to the corresponding change of variable: the return value is identical to that ofellchangecurve(E, v)
.? e = ellinit([1/17,1/42]); ? e = ellintegralmodel(e,&v); ? e[1..5] %3 = [0, 0, 0, 15287762448, 3154568630095008] ? v %4 = [1/714, 0, 0, 0]
- ellisdivisible(P, n, Q)¶
Given \(E/K\) a number field and \(P\) in \(E(K)\) return \(1\) if \(P = [n]R\) for some \(R\) in \(E(K)\) and set \(Q\) to one such \(R\); and return \(0\) otherwise. The integer \(n >= 0\) may be given as
ellxn(E,n)
, if many points need to be tested.? K = nfinit(polcyclo(11,t)); ? E = ellinit([0,-1,1,0,0], K); ? P = [0,0]; ? ellorder(E,P) %4 = 5 ? ellisdivisible(E,P,5, &Q) %5 = 1 ? lift(Q) %6 = [-t^7-t^6-t^5-t^4+1, -t^9-2*t^8-2*t^7-3*t^6-3*t^5-2*t^4-2*t^3-t^2-1] ? ellorder(E, Q) %7 = 25
The algebraic complexity of the underlying algorithm is in \(O(n^4)\), so it is advisable to first factor \(n\), then use a chain of checks attached to the prime divisors of \(n\): the function will do it itself unless \(n\) is given in
ellxn
form.
- ellisogeny(G, only_image, x, y)¶
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 nonzero elements of \(G\) (general case and more efficient if available). This function returns the \([a_1,a_2,a_3,a_4,a_6]\) invariants of the quotient elliptic curve \(E/G\) and (if only_image is zero (the default)) a vector of rational functions \([f, g, h]\) such that the isogeny \(E \to E/G\) is given by \((x,y) :---> (f(x)/h(x)^2, g(x,y)/h(x)^3)\).
? E = ellinit([0,1]); ? elltors(E) %2 = [6, [6], [[2, 3]]] ? ellisogeny(E, [2,3], 1) \\ Weierstrass model for E/<P> %3 = [0, 0, 0, -135, -594] ? ellisogeny(E,[-1,0]) %4 = [[0,0,0,-15,22], [x^3+2*x^2+4*x+3, y*x^3+3*y*x^2-2*y, x+1]]
- ellisogenyapply(g)¶
Given an isogeny of elliptic curves \(f:E'\to E\) (being the result of a call to
ellisogeny
), apply \(f\) to \(g\):if \(g\) is a point \(P\) in the domain of \(f\), return the image \(f(P)\);
if \(g:E"\to E'\) is a compatible isogeny, return the composite isogeny \(f o g: E"\to E\).
? one = ffgen(101, 't)^0; ? E = ellinit([6, 53, 85, 32, 34] * one); ? P = [84, 71] * one; ? ellorder(E, P) %4 = 5 ? [F, f] = ellisogeny(E, P); \\ f: E->F = E/<P> ? ellisogenyapply(f, P) %6 = [0] ? F = ellinit(F); ? Q = [89, 44] * one; ? ellorder(F, Q) %9 = 2 ? [G, g] = ellisogeny(F, Q); \\ g: F->G = F/<Q> ? gof = ellisogenyapply(g, f); \\ gof: E -> G
- ellisomat(p, fl)¶
Given an elliptic curve \(E\) defined over a number field \(K\), compute representatives of the isomorphism classes of elliptic curves defined over \(K\) and \(K\)-isogenous to \(E\). We assume that \(E\) does not have CM over \(K\) (otherwise that set would be infinite). For any such curve \(E_i\), let \(f_i: E \to E_i\) be a rational isogeny of minimal degree and let \(g_i: E_i \to E\) be the dual isogeny; and let \(M\) be the matrix such that \(M_{i,j}\) is the minimal degree for an isogeny \(E_i \to E_j\).
The function returns a vector \([L,M]\) where \(L\) is a list of triples \([E_i, f_i, g_i]\) (\(flag = 0\)), or simply the list of \(E_i\) (\(flag = 1\), which saves time). The curves \(E_i\) are given in \([a_4,a_6]\) form and the first curve \(E_1\) is isomorphic to \(E\) by \(f_1\).
If \(p\) is set, it must be a prime number; in this which case only isogenies of degree a power of \(p\) are considered.
Over a number field, the possible isogeny degrees are determined by Billerey algorithm.
? E = ellinit("14a1"); ? [L,M] = ellisomat(E); ? LE = apply(x->x[1], L) \\ list of curves %3 = [[215/48,-5291/864],[-675/16,6831/32],[-8185/48,-742643/864], [-1705/48,-57707/864],[-13635/16,306207/32],[-131065/48,-47449331/864]] ? L[2][2] \\ isogeny f_2 %4 = [x^3+3/4*x^2+19/2*x-311/12, 1/2*x^4+(y+1)*x^3+(y-4)*x^2+(-9*y+23)*x+(55*y+55/2),x+1/3] ? L[2][3] \\ dual isogeny g_2 %5 = [1/9*x^3-1/4*x^2-141/16*x+5613/64, -1/18*x^4+(1/27*y-1/3)*x^3+(-1/12*y+87/16)*x^2+(49/16*y-48)*x +(-3601/64*y+16947/512),x-3/4] ? apply(E->ellidentify(ellinit(E))[1][1], LE) %6 = ["14a1","14a4","14a3","14a2","14a6","14a5"] ? M %7 = [1 3 3 2 6 6] [3 1 9 6 2 18] [3 9 1 6 18 2] [2 6 6 1 3 3] [6 2 18 3 1 9] [6 18 2 3 9 1]
- ellisoncurve(z)¶
Gives 1 (i.e. true) if the point \(z\) is on the elliptic curve \(E\), 0 otherwise. If \(E\) or \(z\) have imprecise coefficients, an attempt is made to take this into account, i.e. an imprecise equality is checked, not a precise one. It is allowed for \(z\) to be a vector of points in which case a vector (of the same type) is returned.
- ellisotree()¶
Given an elliptic curve \(E\) defined over \(\mathbb{Q}\) or a set of \(\mathbb{Q}\)-isogenous curves as given by
ellisomat
, return a pair \([L,M]\) where\(L\) lists the minimal models of the isomorphism classes of elliptic curves \(\mathbb{Q}\)-isogenous to \(E\) (or in the set of isogenous curves),
\(M\) is the adjacency matrix of the prime degree isogenies tree: there is an edge from \(E_i\) to \(E_j\) if there is an isogeny \(E_i \to E_j\) of prime degree such that the Néron differential forms are preserved.
? E = ellinit("14a1"); ? [L,M] = ellisotree(E); ? M %3 = [0 0 3 2 0 0] [3 0 0 0 2 0] [0 0 0 0 0 2] [0 0 0 0 0 3] [0 0 0 3 0 0] [0 0 0 0 0 0] ? [L2,M2] = ellisotree(ellisomat(E,2,1)); %4 = [0 2] [0 0] ? [L3,M3] = ellisotree(ellisomat(E,3,1)); ? M3 %6 = [0 0 3] [3 0 0] [0 0 0]
Compare with the result of
ellisomat
.? [L,M]=ellisomat(E,,1); ? M %7 = [1 3 3 2 6 6] [3 1 9 6 2 18] [3 9 1 6 18 2] [2 6 6 1 3 3] [6 2 18 3 1 9] [6 18 2 3 9 1]
- ellissupersingular(p)¶
Return 1 if the elliptic curve \(E\) defined over a number field, \(\mathbb{Q}_p\) or a finite field is supersingular at \(p\), and \(0\) otherwise. If the curve is defined over a number field, \(p\) must be explicitly given, and must be a prime number, resp. a maximal ideal, if the curve is defined over \(\mathbb{Q}\), resp. a general number field: we return \(1\) if and only if \(E\) has supersingular good reduction at \(p\).
Alternatively, \(E\) can be given by its \(j\)-invariant in a finite field. In this case \(p\) must be omitted.
? setrand(1); \\ make the choice of g deterministic ? g = ffprimroot(ffgen(7^5)) %1 = 4*x^4 + 5*x^3 + 6*x^2 + 5*x + 6 ? [g^n | n <- [1 .. 7^5 - 1], ellissupersingular(g^n)] %2 = [6] ? K = nfinit(y^3-2); P = idealprimedec(K, 2)[1]; ? E = ellinit([y,1], K); ? ellissupersingular(E, P) %5 = 1 ? Q = idealprimedec(K,5)[1]; ? ellissupersingular(E, Q) %6 = 0
- ellj(precision)¶
Elliptic \(j\)-invariant. \(x\) must be a complex number with positive imaginary part, or convertible into a power series or a \(p\)-adic number with positive valuation.
- elllocalred(p)¶
Calculates the Kodaira type of the local fiber of the elliptic curve \(E\) at \(p\). \(E\) must be an
ell
structure as output byellinit
, over \(\mathbb{Q}_\ell\) (\(p\) better left omitted, else equal to \(\ell\)) over \(\mathbb{Q}\) (\(p\) a rational prime) or a number field \(K\) (\(p\) a maximal ideal given by aprid
structure). 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\).
- elllog(P, G, o)¶
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 nonnegative 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\), seeDLfun
(in the PARI manual); the preferred format for this parameter is[N, factor(N)]
, where \(N\) is the order of \(G\).If no \(o\) is given, assume that \(G\) generates the curve. The function also assumes that \(P\) is a multiple of \(G\).
? a = ffgen(ffinit(2,8),'a); ? E = ellinit([a,1,0,0,1]); \\ over F_{2^8} ? x = a^3; y = ellordinate(E,x)[1]; ? P = [x,y]; G = ellmul(E, P, 113); ? ord = [242, factor(242)]; \\ P generates a group of order 242. Initialize. ? ellorder(E, G, ord) %4 = 242 ? e = elllog(E, P, G, ord) %5 = 15 ? ellmul(E,G,e) == P %6 = 1
- elllseries(s, A, precision)¶
This function is deprecated, use
lfun(E,s)
instead.\(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.
- ellminimaldisc()¶
\(E\) being an elliptic curve defined over a number field output by
ellinit
, return the minimal discriminant ideal of E.
- ellminimalmodel(v)¶
Let \(E\) be an
ell
structure over a number field \(K\). This function determines whether \(E\) admits a global minimal integral model. If so, it returns it and sets \(v = [u,r,s,t]\) to the corresponding change of variable: the return value is identical to that ofellchangecurve(E, v)
.Else return the (nonprincipal) Weierstrass class of \(E\), i.e. the class of \(\prod p^{(v_{p}{\Delta} - \delta_{p}) / 12}\) where \(\Delta = E.disc\) is the model’s discriminant and \(p ^ \delta_{p}\) is the local minimal discriminant. This function requires either that \(E\) be defined over the rational field \(\mathbb{Q}\) (with domain \(D = 1\) in
ellinit
), in which case a global minimal model always exists, or over a number field given by a bnf structure. The Weierstrass class is given inbnfisprincipal
format, i.e. in terms of theK.gen
generators.The resulting model has integral coefficients and is everywhere minimal, the coefficients \(a_1\) and \(a_3\) are reduced modulo \(2\) (in terms of the fixed integral basis
K.zk
) and \(a_2\) is reduced modulo \(3\). Over \(\mathbb{Q}\), we further require that \(a_1\) and \(a_3\) be \(0\) or \(1\), that \(a_2\) be \(0\) or \(± 1\) and that \(u > 0\) in the change of variable: both the model and the change of variable \(v\) are then unique.? e = ellinit([6,6,12,55,233]); \\ over Q ? E = ellminimalmodel(e, &v); ? E[1..5] %3 = [0, 0, 0, 1, 1] ? v %4 = [2, -5, -3, 9]
? K = bnfinit(a^2-65); \\ over a nonprincipal number field ? K.cyc %2 = [2] ? u = Mod(8+a, K.pol); ? E = ellinit([1,40*u+1,0,25*u^2,0], K); ? ellminimalmodel(E) \\ no global minimal model exists over Z_K %6 = [1]~
- ellminimaltwist(flag)¶
Let \(E\) be an elliptic curve defined over \(\mathbb{Q}\), return a discriminant \(D\) such that the twist of \(E\) by \(D\) is minimal among all possible quadratic twists, i.e. if \(flag = 0\), its minimal model has minimal discriminant, or if \(flag = 1\), it has minimal conductor.
In the example below, we find a curve with \(j\)-invariant \(3\) and minimal conductor.
? E = ellminimalmodel(ellinit(ellfromj(3))); ? ellglobalred(E)[1] %2 = 357075 ? D = ellminimaltwist(E,1) %3 = -15 ? E2 = ellminimalmodel(ellinit(elltwist(E,D))); ? ellglobalred(E2)[1] %5 = 14283
In the example below, \(flag = 0\) and \(flag = 1\) give different results.
? E = ellinit([1,0]); ? D0 = ellminimaltwist(E,0) %7 = 1 ? D1 = ellminimaltwist(E,1) %8 = 8 ? E0 = ellminimalmodel(ellinit(elltwist(E,D0))); ? [E0.disc, ellglobalred(E0)[1]] %10 = [-64, 64] ? E1 = ellminimalmodel(ellinit(elltwist(E,D1))); ? [E1.disc, ellglobalred(E1)[1]] %12 = [-4096, 32]
- ellmoddegree()¶
\(e\) being an elliptic curve defined over \(\mathbb{Q}\) output by
ellinit
, compute the modular degree of \(e\) divided by the square of the Manin constant \(c\). It is conjectured that \(c = 1\) for the strong Weil curve in the isogeny class (optimal quotient of \(J_0(N)\)) and this can be proven usingellweilcurve
when the conductor \(N\) is moderate.? E = ellinit("11a1"); \\ from Cremona table: strong Weil curve and c = 1 ? [v,smith] = ellweilcurve(E); smith \\ proof of the above %2 = [[1, 1], [5, 1], [1, 1/5]] ? ellmoddegree(E) %3 = 1 ? [ellidentify(e)[1][1] | e<-v] %4 = ["11a1", "11a2", "11a3"] ? ellmoddegree(ellinit("11a2")) %5 = 5 ? ellmoddegree(ellinit("11a3")) %6 = 1/5
The modular degree of
11a1
is \(1\) (becauseellweilcurve
or Cremona’s table prove that the Manin constant is \(1\) for this curve); the output ofellweilcurve
also proves that the Manin constants of11a2
and11a3
are 1 and 5 respectively, so the actual modular degree of both11a2
and11a3
is 5.
- ellmul(z, n)¶
Computes \([n]z\), where \(z\) is a point on the elliptic curve \(E\). The exponent \(n\) is in \(\mathbb{Z}\), or may be a complex quadratic integer if the curve \(E\) has complex multiplication by \(n\) (if not, an error message is issued).
? Ei = ellinit([1,0]); z = [0,0]; ? ellmul(Ei, z, 10) %2 = [0] \\ unsurprising: z has order 2 ? ellmul(Ei, z, I) %3 = [0, 0] \\ Ei has complex multiplication by Z[i] ? ellmul(Ei, z, quadgen(-4)) %4 = [0, 0] \\ an alternative syntax for the same query ? Ej = ellinit([0,1]); z = [-1,0]; ? ellmul(Ej, z, I) *** at top-level: ellmul(Ej,z,I) *** ^-------------- *** ellmul: not a complex multiplication in ellmul. ? ellmul(Ej, z, 1+quadgen(-3)) %6 = [1 - w, 0]
The simple-minded algorithm for the CM case assumes that we are in characteristic \(0\), and that the quadratic order to which \(n\) belongs has small discriminant.
- ellneg(z)¶
Opposite of the point \(z\) on elliptic curve \(E\).
- ellnonsingularmultiple(P)¶
Given an elliptic curve \(E/\mathbb{Q}\) (more precisely, a model defined over \(\mathbb{Q}\) of a curve) and a rational point \(P \in 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 nonsingular.
? e = ellinit("57a1"); P = [2,-2]; ? ellnonsingularmultiple(e, P) %2 = [[1, -1], 2] ? e = ellinit("396b2"); P = [35, -198]; ? [R,n] = ellnonsingularmultiple(e, P); ? n %5 = 12
- ellorder(z, o)¶
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 nonzero multiple of the order of \(z\), see
DLfun
(in the PARI manual); the preferred format for this parameter is[ord, factor(ord)]
, whereord
is the cardinality of the curve. It is no longer needed since PARI is now able to compute it over large finite fields (was restricted to small prime fields at the time this feature was introduced), and caches the result in \(E\) so that it is computed and factored only once. Modifying the last example, we see that including this extra parameter provides no improvement:? o = [N, factor(N)]; ? for(i=1,100, ellorder(E,random(E),o)) time = 260 ms.
- ellordinate(x, precision)¶
Gives a 0, 1 or 2-component vector containing the \(y\)-coordinates of the points of the curve \(E\) having \(x\) as \(x\)-coordinate.
- ellpadicL(p, n, s, r, D)¶
Returns the value (or \(r\)-th derivative) on a character \(\chi^s\) of \(\mathbb{Z}_p^*\) of the \(p\)-adic \(L\)-function of the elliptic curve \(E/\mathbb{Q}\), twisted by \(D\), given modulo \(p^n\).
Characters. The set of continuous characters of \(Gal(\mathbb{Q} (\mu_{p^{ oo }})/ \mathbb{Q})\) is identified to \(\mathbb{Z}_p^*\) via the cyclotomic character \(\chi\) with values in \(\overline{\mathbb{Q}_p}^*\). Denote by \(\tau:\mathbb{Z}_p^*\to\mathbb{Z}_p^*\) the Teichmüller character, with values in the \((p-1)\)-th roots of \(1\) for \(p != 2\), and \({-1,1}\) for \(p = 2\); finally, let \(<\chi>= \chi \tau^{-1}\), with values in \(1 + 2p\mathbb{Z}_p\). In GP, the continuous character of \(Gal(\mathbb{Q} (\mu_{p^{ oo }})/ \mathbb{Q})\) given by \(<\chi>^{s_1} \tau^{s_2}\) is represented by the pair of integers \(s = (s_1,s_2)\), with \(s_1 \in \mathbb{Z}_p\) and \(s_2 mod p-1\) for \(p > 2\), (resp. mod \(2\) for \(p = 2\)); \(s\) may be also an integer, representing \((s,s)\) or \(\chi^s\).
The :math:`p-adic \(L\) function.` The \(p\)-adic \(L\) function \(L_p\) is defined on the set of continuous characters of \(Gal(\mathbb{Q} (\mu_{p^{ oo }})/ \mathbb{Q})\), as \(\int_{\mathbb{Z}_p^*} \chi^s d \mu\) for a certain \(p\)-adic distribution \(\mu\) on \(\mathbb{Z}_p^*\). The derivative is given by
\[L_p^{(r)}(E, \chi^s) = \int_{\mathbb{Z}_p^*} \log_p^r(a) \chi^s(a) d\mu (a).\]More precisely:
When \(E\) has good supersingular reduction, \(L_p\) takes its values in \(D := H^1_{dR}(E/\mathbb{Q})\otimes_\mathbb{Q} \mathbb{Q}_p\) and satisfies
\[ \begin{align}\begin{aligned} (1-p^{-1} F)^{-2} L_p(E, \chi^0) = (L(E,1) / \Omega).\omega\\where :math:`F` is the Frobenius, :math:`L(E,1)` is the value of the complex :math:`L` function at :math:`1`, :math:`\omega` is the Néron differential and :math:`\Omega` the attached period on :math:`E(\mathbb{R})`. Here, :math:`\chi^0` represents the trivial character.\end{aligned}\end{align} \]The function returns the components of \(L_p^{(r)}(E,\chi^s)\) in the basis \((\omega, F \omega)\).
When \(E\) has ordinary good reduction, this method only defines the projection of \(L_p(E,\chi^s)\) on the \(\alpha\)-eigenspace, where \(\alpha\) is the unit eigenvalue for \(F\). This is what the function returns. We have
\[(1- \alpha^{-1})^{-2} L_{p,\alpha}(E,\chi^0) = L(E,1) / \Omega.\]Two supersingular examples:
? cxL(e) = bestappr( ellL1(e) / e.omega[1] ); ? e = ellinit("17a1"); p=3; \\ supersingular, a3 = 0 ? 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) %5 = [1 + O(3^5), O(3^5)]~ \\ [1,0]~ ? e = ellinit("116a1"); p=3; \\ supersingular, a3 != 0~ ? L = ellpadicL(e,p,4); ? F = [0,-p; 1,ellap(e,p)]; ? (1-p^(-1)*F)^-2*L~ / cxL(e) %9 = [1 + O(3^4), O(3^5)]~
Good ordinary reduction:
? e = ellinit("17a1"); p=5; ap = ellap(e,p) %1 = -2 \\ ordinary ? L = ellpadicL(e,p,4) %2 = 4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4) ? al = padicappr(x^2 - ap*x + p, ap + O(p^7))[1]; ? (1-al^(-1))^(-2) * L / cxL(e) %4 = 1 + O(5^4)
Twist and Teichmüller:
? e = ellinit("17a1"); p=5; \\ ordinary \\ 2nd derivative at tau^1, twist by -7 ? ellpadicL(e, p, 4, [0,1], 2, -7) %2 = 2*5^2 + 5^3 + O(5^4)
We give an example of non split multiplicative reduction (see
ellpadicbsd
for more examples).? e=ellinit("15a1"); p=3; n=5; ? L = ellpadicL(e,p,n) %2 = 2 + 3 + 3^2 + 3^3 + 3^4 + O(3^5) ? (1 - ellap(e,p))^(-1) * L / cxL(e) %3 = 1 + O(3^5)
This function is a special case of
mspadicL
and it also appears as the first term ofmspadicseries
:? e = ellinit("17a1"); p=5; ? L = ellpadicL(e,p,4) %2 = 4 + 3*5 + 4*5^2 + 2*5^3 + O(5^4) ? [M,phi] = msfromell(e, 1); ? Mp = mspadicinit(M, p, 4); ? mu = mspadicmoments(Mp, phi); ? mspadicL(mu) %6 = 4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + O(5^6) ? mspadicseries(mu) %7 = (4 + 3*5 + 4*5^2 + 2*5^3 + 2*5^4 + 5^5 + O(5^6)) + (3 + 3*5 + 5^2 + 5^3 + O(5^4))*x + (2 + 3*5 + 5^2 + O(5^3))*x^2 + (3 + 4*5 + 4*5^2 + O(5^3))*x^3 + (3 + 2*5 + O(5^2))*x^4 + O(x^5)
These are more cumbersome than
ellpadicL
but allow to compute at different characters, or successive derivatives, or to twist by a quadratic character essentially for the cost of a single call toellpadicL
due to precomputations.
- ellpadicbsd(p, n, D)¶
Given an elliptic curve \(E\) over \(\mathbb{Q}\), its quadratic twist \(E_D\) and a prime number \(p\), this function is a \(p\)-adic analog of the complex functions
ellanalyticrank
andellbsd
. It callsellpadicL
with initial accuracy \(p^n\) and may increase it internally; it returns a vector \([r, L_p]\) where\(L_p\) is a \(p\)-adic number (resp. a pair of \(p\)-adic numbers if \(E\) has good supersingular reduction) defined modulo \(p^N\), conjecturally equal to \(R_p S\), where \(R_p\) is the \(p\)-adic regulator as given by
ellpadicregulator
(in the basis \((\omega, F \omega)\)) and \(S\) is the cardinal of the Tate-Shafarevich group for the quadratic twist \(E_D\).\(r\) is an upper bound for the analytic rank of the \(p\)-adic \(L\)-function attached to \(E_D\): we know for sure that the \(i\)-th derivative of \(L_p(E_D,.)\) at \(\chi^0\) is \(O(p^N)\) for all \(i < r\) and that its \(r\)-th derivative is nonzero; it is expected that the true analytic rank is equal to the rank of the Mordell-Weil group \(E_D(\mathbb{Q})\), plus \(1\) if the reduction of \(E_D\) at \(p\) is split multiplicative; if \(r = 0\), then both the analytic rank and the Mordell-Weil rank are unconditionnally \(0\).
Recall that the \(p\)-adic BSD conjecture (Mazur, Tate, Teitelbaum, Bernardi, Perrin-Riou) predicts an explicit link between \(R_p S\) and
\[(1-p^{-1} F)^{-2}.L_p^{(r)}(E_D, \chi^0) / r!\]where \(r\) is the analytic rank of the \(p\)-adic \(L\)-function attached to \(E_D\) and \(F\) is the Frobenius on \(H^1_{dR}\); see
ellpadicL
for definitions.? E = ellinit("11a1"); p = 7; n = 5; \\ good ordinary ? ellpadicbsd(E, 7, 5) \\ rank 0, %2 = [0, 1 + O(7^5)] ? E = ellinit("91a1"); p = 7; n = 5; \\ non split multiplicative ? [r,Lp] = ellpadicbsd(E, p, n) %5 = [1, 2*7 + 6*7^2 + 3*7^3 + 7^4 + O(7^5)] ? R = ellpadicregulator(E, p, n, E.gen) %6 = 2*7 + 6*7^2 + 3*7^3 + 7^4 + 5*7^5 + O(7^6) ? sha = Lp/R %7 = 1 + O(7^4) ? E = ellinit("91b1"); p = 7; n = 5; \\ split multiplicative ? [r,Lp] = ellpadicbsd(E, p, n) %9 = [2, 2*7 + 7^2 + 5*7^3 + O(7^4)] ? ellpadicregulator(E, p, n, E.gen) %10 = 2*7 + 7^2 + 5*7^3 + 6*7^4 + 2*7^5 + O(7^6) ? [rC, LC] = ellanalyticrank(E); ? [r, rC] %12 = [2, 1] \\ r = rC+1 because of split multiplicative reduction ? E = ellinit("53a1"); p = 5; n = 5; \\ supersingular ? [r, Lp] = ellpadicbsd(E, p, n); ? r %15 = 1 ? Lp %16 = [3*5 + 2*5^2 + 2*5^5 + O(5^6), \ 5 + 3*5^2 + 4*5^3 + 2*5^4 + 5^5 + O(5^6)] ? R = ellpadicregulator(E, p, n, E.gen) %17 = [3*5 + 2*5^2 + 2*5^5 + O(5^6), 5 + 3*5^2 + 4*5^3 + 2*5^4 + O(5^5)] \\ expect Lp = R*#Sha, hence (conjecturally) #Sha = 1 ? E = ellinit("84a1"); p = 11; n = 6; D = -443; ? [r,Lp] = ellpadicbsd(E, 11, 6, D) \\ Mordell-Weil rank 0, no regulator %19 = [0, 3 + 2*11 + O(11^6)] ? lift(Lp) \\ expected cardinal for Sha is 5^2 %20 = 25 ? ellpadicbsd(E, 3, 12, D) \\ at 3 %21 = [1, 1 + 2*3 + 2*3^2 + O(3^8)] ? ellpadicbsd(E, 7, 8, D) \\ and at 7 %22 = [0, 4 + 3*7 + O(7^8)]
- ellpadicfrobenius(p, n)¶
If \(p > 2\) is a prime and \(E\) is an elliptic curve on \(\mathbb{Q}\) with good reduction at \(p\), return the matrix of the Frobenius endomorphism \(\varphi\) on the crystalline module \(D_p(E) = \mathbb{Q}_p \otimes H^1_{dR}(E/\mathbb{Q})\) with respect to the basis of the given model \((\omega, \eta = x \omega)\), where \(\omega = dx/(2 y+a_1 x+a_3)\) is the invariant differential. The characteristic polynomial of \(\varphi\) is \(x^2 - a_p x + p\). The matrix is computed to absolute \(p\)-adic precision \(p^n\).
? E = ellinit([1,-1,1,0,0]); ? F = ellpadicfrobenius(E,5,3); ? lift(F) %3 = [120 29] [ 55 5] ? charpoly(F) %4 = x^2 + O(5^3)*x + (5 + O(5^3)) ? ellap(E, 5) %5 = 0
- ellpadicheight(p, n, P, Q)¶
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 := 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 \(h_E\) associates to \(P\in E(\mathbb{Q})\) an element \(f \omega + g \eta\) in \(D\). This routine returns the vector \([f, g]\) to \(n\) \(p\)-adic digits. If \(P\in E(\mathbb{Q})\) is in the kernel of reduction mod \(p\) and if its reduction at all finite places is non singular, then \(g = -(\log_E P)^2\), where \(\log_E\) is the logarithm for the formal group of \(E\) at \(p\).
If furthermore the model is of the form \(Y^2 = X^3 + a X + b\) and \(P = (x,y)\), then
\[f = \log_p(denominator (x)) - 2 \log_p(\sigma (P))\]where \(\sigma (P)\) is given by
ellsigma
\((E,P)\).Recall (Advanced topics in the arithmetic of elliptic curves, Theorem 3.2) that the local height function over the complex numbers is of the form
\[\lambda (z) = -\log (\|E.disc\|) / 6 + \Re (z \eta (z)) - 2 \log ( \sigma (z)).\](N.B. our normalization for local and global heights is twice that of Silverman’s).
? E = ellinit([1,-1,1,0,0]); P = [0,0]; ? ellpadicheight(E,5,3, P) %2 = [3*5 + 5^2 + 2*5^3 + O(5^4), 5^2 + 4*5^4 + O(5^5)] ? E = ellinit("11a1"); P = [5,5]; \\ torsion point ? ellpadicheight(E,19,6, P) %4 = [0, 0] ? E = ellinit([0,0,1,-4,2]); P = [-2,1]; ? ellpadicheight(E,3,3, P) %6 = [2*3^2 + 2*3^3 + 3^4 + O(3^5), 2*3^2 + 3^4 + O(3^5)] ? ellpadicheight(E,3,5, P, elladd(E,P,P)) %7 = [3^2 + 2*3^3 + O(3^7), 3^2 + 3^3 + 2*3^4 + 3^5 + O(3^7)]
When \(E\) has good ordinary reduction at \(p\) or non split multiplicative reduction, the “canonical” \(p\)-adic height is given by
s2 = ellpadics2(E,p,n); ellpadicheight(E, p, n, P) * [1,-s2]~
Since \(s_2\) does not depend on \(P\), it is preferable to compute it only once:
? E = ellinit("5077a1"); p = 5; n = 7; \\ rank 3 ? s2 = ellpadics2(E,p,n); ? M = ellpadicheightmatrix(E,p, n, E.gen) * [1,-s2]~; ? matdet(M) \\ p-adic regulator on the points in E.gen %4 = 5 + 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7)
When \(E\) has split multiplicative reduction at \(p\) (Tate curve), the “canonical” \(p\)-adic height is given by
Ep = ellinit(E[1..5], O(p^(n))); \\ E seen as a Tate curve over Qp [u2,u,q] = Ep.tate; ellpadicheight(E, p, n, P) * [1,-s2 + 1/log(q)/u2]]~
where \(s_2\) is as above. For example,
? E = ellinit("91b1"); P =[-1, 3]; p = 7; n = 5; ? Ep = ellinit(E[1..5], O(p^(n))); ? s2 = ellpadics2(E,p,n); ? [u2,u,q] = Ep.tate; ? H = ellpadicheight(E,p, n, P) * [1,-s2 + 1/log(q)/u2]~ %5 = 2*7 + 7^2 + 5*7^3 + 6*7^4 + 2*7^5 + O(7^6)
These normalizations are chosen so that \(p\)-adic BSD conjectures are easy to state, see
ellpadicbsd
.
- ellpadicheightmatrix(p, n, Q)¶
\(Q\) being a vector of points, this function returns the “Gram matrix” \([F,G]\) of the cyclotomic \(p\)-adic height \(h_E\) with respect to the basis \((\omega, \eta)\) of \(D = H^1_{dR}(E) \otimes_\mathbb{Q} \mathbb{Q}_p\) given to \(n\) \(p\)-adic digits. In other words, if
ellpadicheight
\((E,p,n, Q[i],Q[j]) = [f,g]\), corresponding to \(f \omega + g \eta\) in \(D\), then \(F[i,j] = f\) and \(G[i,j] = g\).? E = ellinit([0,0,1,-7,6]); Q = [[-2,3],[-1,3]]; p = 5; n = 5; ? [F,G] = ellpadicheightmatrix(E,p,n,Q); ? lift(F) \\ p-adic entries, integral approximation for readability %3 = [2364 3100] [3100 3119] ? G %4 = [25225 46975] [46975 61850] ? [F,G] * [1,-ellpadics2(E,p,n)]~ %5 = [4 + 2*5 + 4*5^2 + 3*5^3 + O(5^5) 4*5^2 + 4*5^3 + 5^4 + O(5^5)] [ 4*5^2 + 4*5^3 + 5^4 + O(5^5) 4 + 3*5 + 4*5^2 + 4*5^3 + 5^4 + O(5^5)]
- ellpadiclambdamu(p, D, i)¶
Let \(p\) be a prime number and let \(E/\mathbb{Q}\) be a rational elliptic curve with good or bad multiplicative reduction at \(p\). Return the Iwasawa invariants \(\lambda\) and \(\mu\) for the \(p\)-adic \(L\) function \(L_p(E)\), twisted by \((D/.)\) and the \(i\)-th power of the Teichmüller character \(\tau\), see
ellpadicL
for details about \(L_p(E)\).Let \(\chi\) be the cyclotomic character and choose \(\gamma\) in \(Gal(\mathbb{Q}_p(\mu_{p^ oo })/\mathbb{Q}_p)\) such that \(\chi (\gamma) = 1+2p\). Let \(^{L}^{(i), D} \in \mathbb{Q}_p[[X]]\otimes D_{cris}\) such that
\[( < \chi > ^s \tau^i) (^{L}^{(i), D}(\gamma-1)) = L_p(E, < \chi > ^s\tau^i (D/.)).\]When \(E\) has good ordinary or bad multiplicative reduction at \(p\). By Weierstrass’s preparation theorem the series \(^{L}^{(i), D}\) can be written \(p^\mu (X^\lambda + p G(X))\) up to a \(p\)-adic unit, where \(G(X)\in \mathbb{Z}_p[X]\). The function returns \([\lambda,\mu]\).
When \(E\) has good supersingular reduction, we define a sequence of polynomials \(P_n\) in \(\mathbb{Q}_p[X]\) of degree \(< p^n\) (and bounded denominators), such that
\[ \begin{align}\begin{aligned} ^{L}^{(i), D} = P_n \varphi^{n+1}\omega_E - \xi_n P_{n-1}\varphi^{n+2}\omega_E mod ((1+X)^{p^n}-1) \mathbb{Q}_p[X]\otimes D_{cris},\\where :math:`\xi_n = polcyclo (p^n, 1+X)`. Let :math:`\lambda_n,\mu_n` be the invariants of :math:`P_n`. We find that\end{aligned}\end{align} \]\(\mu_n\) is nonnegative and decreasing for \(n\) of given parity hence \(\mu_{2n}\) tends to a limit \(\mu^+\) and \(\mu_{2n+1}\) tends to a limit \(\mu^-\) (both conjecturally \(0\)).
there exists integers \(\lambda^+\), \(\lambda^-\) in \(\mathbb{Z}\) (denoted with a \(~\) in the reference below) such that
\[ \begin{align}\begin{aligned} \lim_{n\to oo } \lambda_{2n} + 1/(p+1) = \lambda^+ and \lim_{n\to oo } \lambda_{2n+1} + p/(p+1) = \lambda^-.\\The function returns :math:`[[\lambda^+, \lambda^-], [\mu^+,\mu^-]]`.\end{aligned}\end{align} \]Reference: B. Perrin-Riou, Arithmétique des courbes elliptiques à réduction supersinguli\`ere en \(p\), Experimental Mathematics, 12, 2003, pp. 155-186.
- ellpadiclog(p, n, P)¶
Given \(E\) defined over \(K = \mathbb{Q}\) or \(\mathbb{Q}_p\) and \(P = [x,y]\) on \(E(K)\) in the kernel of reduction mod \(p\), let \(t(P) = -x/y\) be the formal group parameter; this function returns \(L(t)\), where \(L\) denotes the formal logarithm (mapping the formal group of \(E\) to the additive formal group) attached to the canonical invariant differential: \(dL = dx/(2y + a_1x + a_3)\).
? E = ellinit([0,0,1,-4,2]); P = [-2,1]; ? ellpadiclog(E,2,10,P) %2 = 2 + 2^3 + 2^8 + 2^9 + 2^10 + O(2^11) ? E = ellinit([17,42]); ? p=3; Ep = ellinit(E,p); \\ E mod p ? P=[114,1218]; ellorder(Ep,P) \\ the order of P on (E mod p) is 2 %5 = 2 ? Q = ellmul(E,P,2) \\ we need a point of the form 2*P %6 = [200257/7056, 90637343/592704] ? ellpadiclog(E,3,10,Q) %7 = 3 + 2*3^2 + 3^3 + 3^4 + 3^5 + 3^6 + 2*3^8 + 3^9 + 2*3^10 + O(3^11)
- ellpadicregulator(p, n, S)¶
Let \(E/\mathbb{Q}\) be an elliptic curve. Return the determinant of the Gram matrix of the vector of points \(S = (S_1,..., S_r)\) with respect to the “canonical” cyclotomic \(p\)-adic height on \(E\), given to \(n\) (\(p\)-adic) digits.
When \(E\) has ordinary reduction at \(p\), this is the expected Gram deteterminant in \(\mathbb{Q}_p\).
In the case of supersingular reduction of \(E\) at \(p\), the definition requires care: the regulator \(R\) is an element of \(D := H^1_{dR}(E) \otimes_\mathbb{Q} \mathbb{Q}_p\), which is a two-dimensional \(\mathbb{Q}_p\)-vector space spanned by \(\omega\) and \(\eta = x \omega\) (which are defined over \(\mathbb{Q}\)) or equivalently but now over \(\mathbb{Q}_p\) by \(\omega\) and \(F\omega\) where \(F\) is the Frobenius endomorphism on \(D\) as defined in
ellpadicfrobenius
. On \(D\) we define the cyclotomic height \(h_E = f \omega + g \eta\) (seeellpadicheight
) and a canonical alternating bilinear form \([.,.]_D\) such that \([\omega, \eta]_D = 1\).For any \(\nu \in D\), we can define a height \(h_\nu := [ h_E, \nu ]_D\) from \(E(\mathbb{Q})\) to \(\mathbb{Q}_p\) and \(<.,.>_\nu\) the attached bilinear form. In particular, if \(h_E = f \omega + g\eta\), then \(h_\eta = [ h_E, \eta ]_D\) = f and \(h_\omega = [ h_E, \omega ]_D = - g\) hence \(h_E = h_\eta \omega - h_\omega \eta\). Then, \(R\) is the unique element of \(D\) such that
\[[\omega,\nu]_D^{r-1} [R, \nu]_D = \det (< S_i, S_j >_{\nu})\]for all \(\nu \in D\) not in \(\mathbb{Q}_p \omega\). The
ellpadicregulator
function returns \(R\) in the basis \((\omega, F\omega)\), which was chosen so that \(p\)-adic BSD conjectures are easy to state, seeellpadicbsd
.Note that by definition
\[[R, \eta]_D = \det (< S_i, S_j >_{\eta})\]and
\[[R, \omega+\eta]_D = \det (< S_i, S_j >_{\omega+\eta}).\]
- ellpadics2(p, n)¶
If \(p > 2\) is a prime and \(E/\mathbb{Q}\) is an 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\).? e=ellinit([17,42]); ? ellpadics2(e,13,4) %2 = 10 + 2*13 + 6*13^3 + O(13^4)
This slope is the unique \(c \in 3^{-1}\mathbb{Z}_p\) such that the odd solution \(\sigma (t) = t + O(t^2)\) of
\[- d((1)/(\sigma) (d \sigma)/(\omega)) = (x(t) + c) \omega\]is in \(t\mathbb{Z}_p[[t]]\).
It is equal to \(b_2/12 - E_2/12\) where \(E_2\) is the value of the Katz \(p\)-adic Eisenstein series of weight 2 on \((E,\omega)\). This is used to construct a canonical \(p\)-adic height when \(E\) has good ordinary reduction at \(p\) as follows
s2 = ellpadics2(E,p,n); h(E,p,n, P, s2) = ellpadicheight(E, [p,[1,-s2]],n, P);
Since \(s_2\) does not depend on the point \(P\), we compute it only once.
- ellperiods(flag, precision)¶
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 attached to \([W_1,W_2]\), satisfying \(\eta_2 W_1 - \eta_1 W_2 = 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.
? L = ellperiods([1,I],1); ? [w1,w2] = L[1]; [e1,e2] = L[2]; ? e2*w1 - e1*w2 %3 = 6.2831853071795864769252867665590057684*I ? ellzeta(L, 1/2 + 2*I) %4 = 1.5707963... - 6.283185307...*I ? ellzeta([1,I], 1/2 + 2*I) \\ same but less efficient %4 = 1.5707963... - 6.283185307...*I
- ellpointtoz(P, precision)¶
If \(E/\mathbb{C} ~ \mathbb{C}/\Lambda\) is a complex elliptic curve (\(\Lambda = E.omega\)), computes a complex number \(z\), well-defined modulo the lattice \(\Lambda\), corresponding to the point \(P\); i.e. such that \(P = [\wp_\Lambda (z),\wp'_\Lambda (z)]\) satisfies the equation
\[y^2 = 4x^3 - g_2 x - g_3,\]where \(g_2\), \(g_3\) are the elliptic invariants.
If \(E\) is defined over \(\mathbb{R}\) and \(P\in 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 = [2.548947057811923643 E-57, 7.646841173435770930 E-57] ? ellpointtoz(E, [0]) \\ the point at infinity %5 = 0
If \(E\) is defined over a general number field, the function returns the values corresponding to the various complex embeddings of the curve and of the point, in the same order as
E.nf.roots
:? E=ellinit([-22032-15552*x,0], nfinit(x^2-2)); ? P=[-72*x-108,0]; ? ellisoncurve(E,P) %3 = 1 ? ellpointtoz(E,P) %4 = [-0.52751724240790530394437835702346995884*I, -0.090507650025885335533571758708283389896*I] ? E.nf.roots %5 = [-1.4142135623730950488016887242096980786, \\ x-> -sqrt(2) 1.4142135623730950488016887242096980786] \\ x-> sqrt(2)
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 behavior is then as follows:
If the reduction is split (\(E.tate[2]\) is a
t_PADIC
), we have an isomorphism \(\phi: E(\mathbb{Q}_p) ~ \mathbb{Q}_p^*/q^\mathbb{Z}\) and the function returns \(\phi (P)\in \mathbb{Q}_p\).If the reduction is not split (\(E.tate[2]\) is a
t_POLMOD
), we only have an isomorphism \(\phi: E(K) ~ K^*/q^\mathbb{Z}\) over the unramified quadratic extension \(K/\mathbb{Q}_p\). In this case, the output \(\phi (P)\in K\) is at_POLMOD
.
? E = ellinit([0,-1,1,0,0], O(11^5)); P = [0,0]; ? [u2,u,q] = E.tate; type(u) \\ split multiplicative reduction %2 = "t_PADIC" ? ellmul(E, P, 5) \\ P has order 5 %3 = [0] ? z = ellpointtoz(E, [0,0]) %4 = 3 + 11^2 + 2*11^3 + 3*11^4 + 6*11^5 + 10*11^6 + 8*11^7 + O(11^8) ? z^5 %5 = 1 + O(11^9) ? E = ellinit(ellfromj(1/4), O(2^6)); x=1/2; y=ellordinate(E,x)[1]; ? z = ellpointtoz(E,[x,y]); \\ t_POLMOD of t_POL with t_PADIC coeffs ? liftint(z) \\ lift all p-adics %8 = Mod(8*u + 7, u^2 + 437)
- ellpow(z, n)¶
Deprecated alias for
ellmul
.
- ellratpoints(h, flag)¶
\(E\) being an integral model of elliptic curve , return a vector containing the affine rational points on the curve of naive height less than \(h\). If \(flag = 1\), stop as soon as a point is found; return either an empty vector or a vector containing a single point. See
hyperellratpoints
for how \(h\) can be specified.? E=ellinit([-25,1]); ? ellratpoints(E,10) %2 = [[-5,1],[-5,-1],[-3,7],[-3,-7],[-1,5],[-1,-5], [0,1],[0,-1],[5,1],[5,-1],[7,13],[7,-13]] ? ellratpoints(E,10,1) %3 = [[-5,1]]
- ellrootno(p)¶
\(E\) being an
ell
structure over \(\mathbb{Q}\) as output byellinit
, 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 and in this case the curve can also be defined over a number field.Note that the global root number is the sign of the functional equation and conjecturally is the parity of the rank of the 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.
- ellsea(tors)¶
Let \(E\) be an ell structure as output by
ellinit
, defined over a finite field \(\mathbb{F}_q\). This low-level function computes the order of the group \(E(\mathbb{F}_q)\) using the SEA algorithm; compared to the high-level functionellcard
, which includes SEA among its choice of algorithms, thetors
argument allows to speed up a search for curves having almost prime order and whose quadratic twist may also have almost prime order. Whentors
is set to a nonzero value, the function returns \(0\) as soon as it detects that the order has a small prime factor not dividingtors
; SEA considers modular polynomials of increasing prime degree \(\ell\) and we return \(0\) as soon as we hit an \(\ell\) (coprime totors
) dividing \(\#E(\mathbb{F}_q)\):? ellsea(ellinit([1,1], 2^56+3477), 1) %1 = 72057594135613381 ? forprime(p=2^128,oo, q = ellcard(ellinit([1,1],p)); if(isprime(q),break)) time = 6,571 ms. ? forprime(p=2^128,oo, q = ellsea(ellinit([1,1],p),1);if(isprime(q),break)) time = 522 ms.
In particular, set
tors
to \(1\) if you want a curve with prime order, to \(2\) if you want to allow a cofactor which is a power of two (e.g. for Edwards’s curves), etc. The early exit on bad curves yields a massive speedup compared to running the cardinal algorithm to completion.When
tors
is negative, similar checks are performed for the quadratic twist of the curve.The following function returns a curve of prime order over \(\mathbb{F}_p\).
cryptocurve(p) = { while(1, my(E, N, j = Mod(random(p), p)); E = ellinit(ellfromj(j)); N = ellsea(E, 1); if (!N, continue); if (isprime(N), return(E)); \\ try the quadratic twist for free if (isprime(2*p+2 - N), return(ellinit(elltwist(E)))); ); } ? p = randomprime([2^255, 2^256]); ? E = cryptocurve(p); \\ insist on prime order %2 = 47,447ms
The same example without early abort (using
ellcard(E)
instead ofellsea(E, 1)
) runs for about 5 minutes before finding a suitable curve.The availability of the
seadata
package will speed up the computation, and is strongly recommended. The generic functionellcard
should be preferred when you only want to compute the cardinal of a given curve without caring about it having almost prime order:If the characteristic is too small (\(p <= 7\)) or the field cardinality is tiny (\(q <= 523\)) the generic algorithm
ellcard
is used instead and thetors
argument is ignored. (The reason for this is that SEA is not implemented for \(p <= 7\) and that if \(q <= 523\) it is likely to run into an infinite loop.)If the field cardinality is smaller than about \(2^{50}\), the generic algorithm will be faster.
Contrary to
ellcard
,ellsea
does not store the computed cardinality in \(E\).
- ellsearch()¶
This function finds all curves in the
elldata
database satisfying the constraint defined by the argument \(N\):if \(N\) is a character string, it selects a given curve, e.g.
"11a1"
, or curves in the given isogeny class, e.g."11a"
, or curves with given conductor, e.g."11"
;if \(N\) is a vector of integers, it encodes the same constraints as the character string above, according to the
ellconvertname
correspondance, e.g.[11,0,1]
for"11a1"
,[11,0]
for"11a"
and[11]
for"11"
;if \(N\) is an integer, curves with conductor \(N\) are selected.
If \(N\) codes a full curve name, for instance
"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 Mordell-Weil group attached to the curve.? ellsearch("11a3") %1 = ["11a3", [0, -1, 1, 0, 0], []] ? ellsearch([11,0,3]) %2 = ["11a3", [0, -1, 1, 0, 0], []]
If \(N\) is not a full curve name, then the output is a vector of all matching curves in the above format:
? ellsearch("11a") %1 = [["11a1", [0, -1, 1, -10, -20], []], ["11a2", [0, -1, 1, -7820, -263580], []], ["11a3", [0, -1, 1, 0, 0], []]] ? ellsearch("11b") %2 = []
- ellsigma(z, flag, precision)¶
Computes the value at \(z\) of the Weierstrass \(\sigma\) function attached to the lattice \(L\) as given by
ellperiods
\((,1)\): including quasi-periods is useful, otherwise there are recomputed from scratch for each new \(z\).\[\sigma (z, L) = z \prod_{\omega\in L^*} (1 - (z)/(\omega))e^{(z)/(\omega) + (z^2)/(2\omega^2)}.\]It is also possible to directly input \(L = [\omega_1,\omega_2]\), or an elliptic curve \(E\) as given by
ellinit
(\(L = E.omega\)).? w = ellperiods([1,I], 1); ? ellsigma(w, 1/2) %2 = 0.47494937998792065033250463632798296855 ? E = ellinit([1,0]); ? ellsigma(E) \\ at 'x, implicitly at default seriesprecision %4 = x + 1/60*x^5 - 1/10080*x^9 - 23/259459200*x^13 + O(x^17)
If \(flag = 1\), computes an arbitrary determination of \(\log (\sigma (z))\).
- ellsub(z1, z2)¶
Difference of the points \(z1\) and \(z2\) on the elliptic curve corresponding to \(E\).
- elltamagawa()¶
The object \(E\) being an elliptic curve over a number field, returns the global Tamagawa number of the curve (including the factor at infinite places).
? e = ellinit([1, -1, 1, -3002, 63929]); \\ curve "90c6" from elldata ? elltamagawa(e) %2 = 288 ? [elllocalred(e,p)[4] | p<-[2,3,5]] %3 = [6, 4, 6] ? vecprod(%) \\ since e.disc > 0 the factor at infinity is 2 %4 = 144
- elltaniyama(serprec)¶
Computes the modular parametrization of the elliptic curve \(E/\mathbb{Q}\), where \(E\) is an
ell
structure as output byellinit
. This returns a two-component vector \([u,v]\) of power series, given to \(n\) 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} ellak (E, n) x^n\).
- elltatepairing(P, Q, m)¶
Let \(E\) be an elliptic curve defined over a finite field \(k\) and \(m >= 1\) be an integer. This function computes the (nonreduced) Tate pairing of the points \(P\) and \(Q\) on \(E\), where \(P\) is an \(m\)-torsion point. More precisely, let \(f_{m,P}\) denote a Miller function with divisor \(m[P] - m[O_E]\); the algorithm returns \(f_{m,P}(Q) \in k^*/(k^*)^m\).
- elltors()¶
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]
, wheret
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), andv2
gives generators for these cyclic groups. \(E\) must be anell
structure as output byellinit
.? 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]\).
- elltwist(P)¶
Returns the coefficients \([a_1,a_2,a_3,a_4,a_6]\) of the twist of the elliptic curve \(E\) by the quadratic extension of the coefficient ring defined by \(P\) (when \(P\) is a polynomial) or
quadpoly(P)
when \(P\) is an integer. If \(E\) is defined over a finite field, then \(P\) can be omitted, in which case a random model of the unique nontrivial twist is returned. If \(E\) is defined over a number field, the model should be replaced by a minimal model (if one exists).Example: Twist by discriminant \(-3\):
? elltwist(ellinit([0,a2,0,a4,a6]),-3) %1 = [0,-3*a2,0,9*a4,-27*a6]
Twist by the Artin-Schreier extension given by \(x^2+x+T\) in characteristic \(2\):
? lift(elltwist(ellinit([a1,a2,a3,a4,a6]*Mod(1,2)),x^2+x+T)) %1 = [a1,a2+a1^2*T,a3,a4,a6+a3^2*T]
Twist of an elliptic curve defined over a finite field:
? E=ellinit([1,7]*Mod(1,19));lift(elltwist(E)) %1 = [0,0,0,11,12]
- ellweilcurve(ms)¶
If \(E'\) is an elliptic curve over \(\mathbb{Q}\), let \(L_{E'}\) be the sub-\(\mathbb{Z}\)-module of \(\text{Hom}_{\Gamma_0(N)}(\Delta_0,\mathbb{Q})\) attached to \(E'\) (It is given by \(x[3]\) if \([M,x] = msfromell (E')\).)
On the other hand, if \(N\) is the conductor of \(E\) and \(f\) is the modular form for \(\Gamma_0(N)\) attached to \(E\), let \(L_f\) be the lattice of the \(f\)-component of \(\text{Hom}_{\Gamma_0(N)}(\Delta_0,\mathbb{Q})\) given by the elements \(\phi\) such that \(\phi ({0,\gamma^{-1} 0}) \in \mathbb{Z}\) for all \(\gamma \in \Gamma_0(N)\) (see
mslattice
).Let \(E'\) run through the isomorphism classes of elliptic curves isogenous to \(E\) as given by
ellisomat
(and in the same order). This function returns a pair[vE,vS]
wherevE
contains minimal models for the \(E'\) andvS
contains the list of Smith invariants for the lattices \(L_{E'}\) in \(L_f\). The function also accepts the output ofellisomat
, i.e. the isogeny class. If the optional argumentms
is present, it contains the output ofmsfromell(vE, 0)
, i.e. the new modular symbol space \(M\) of level \(N\) and a vector of triples \([x^+,x^-, L]\) attached to each curve \(E'\).In particular, the strong Weil curve amongst the curves isogenous to \(E\) is the one whose Smith invariants are \([c,c]\), where \(c\) is the Manin constant, conjecturally equal to \(1\).
? E = ellinit("11a3"); ? [vE, vS] = ellweilcurve(E); ? [n] = [ i | i<-[1..#vS], vS[i]==[1,1] ] \\ lattice with invariant [1,1] %3 = [2] ? ellidentify(vE[n]) \\ ... corresponds to strong Weil curve %4 = [["11a1", [0, -1, 1, -10, -20], []], [1, 0, 0, 0]] ? [vE, vS] = ellweilcurve(E, &ms); \\ vE,vS are as above ? [M, vx] = ms; msdim(M) \\ ... but ms contains more information %6 = 3 ? #vx %7 = 3 ? vx[1] %8 = [[1/25, -1/10, -1/10]~, [0, 1/2, -1/2]~, [1/25,0; -3/5,1; 2/5,-1]] ? forell(E, 11,11, print(msfromell(ellinit(E[1]), 1)[2])) [1/5, -1/2, -1/2]~ [1, -5/2, -5/2]~ [1/25, -1/10, -1/10]~
The last example prints the modular symbols \(x^+\) in \(M^+\) attached to the curves
11a1
,11a2
and11a3
.
- ellweilpairing(P, Q, m)¶
Let \(E\) be an elliptic curve defined over a finite field and \(m >= 1\) be an integer. This function computes the Weil pairing of the two \(m\)-torsion points \(P\) and \(Q\) on \(E\), which is an alternating bilinear map. More precisely, let \(f_{m,R}\) denote a Miller function with divisor \(m[R] - m[O_E]\); the algorithm returns the \(m\)-th root of unity
\[\varepsilon (P,Q)^m.f_{m,P}(Q) / f_{m,Q}(P),\]where \(f(R)\) is the extended evaluation of \(f\) at the divisor \([R] - [O_E]\) and \(\varepsilon (P,Q)\in {±1}\) is given by Weil reciprocity: \(\varepsilon (P,Q) = 1\) if and only if \(P, Q, O_E\) are not pairwise distinct.
- ellwp(z, flag, precision)¶
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 byellinit
(\(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)]\).
For instance, the Dickson elliptic functions sm and sn can be implemented as follows
smcm(z) = { my(a, b, E = ellinit([0,-1/(4*27)])); \\ ell. invariants (g2,g3)=(0,1/27) [a,b] = ellwp(E, z, 1); [6*a / (1-3*b), (3*b+1)/(3*b-1)]; } ? [s,c] = smcm(0.5); ? s %2 = 0.4898258757782682170733218609 ? c %3 = 0.9591820206453842491187464098 ? s^3+c^3 %4 = 1.000000000000000000000000000 ? smcm('x + O('x^11)) %5 = [x - 1/6*x^4 + 2/63*x^7 - 13/2268*x^10 + O(x^11), 1 - 1/3*x^3 + 1/18*x^6 - 23/2268*x^9 + O(x^10)]
- ellxn(n, v)¶
For any affine point \(P = (t,u)\) on the curve \(E\), we have
\[[n]P = (\phi_n(P)\psi_n(P) : \omega_n(P) : \psi_n(P)^3)\]for some \(\phi_n,\omega_n,\psi_n\) in \(\mathbb{Z}[a_1,a_2,a_3,a_4,a_6][t,u]\) modulo the curve equation. This function returns a pair \([A,B]\) of polynomials in \(\mathbb{Z}[a_1,a_2,a_3,a_4,a_6][v]\) such that \([A(t),B(t)] = [\phi_n(P),\psi_n(P)^2]\) in the function field of \(E\), whose quotient give the abscissa of \([n]P\). If \(P\) is an \(n\)-torsion point, then \(B(t) = 0\).
? E = ellinit([17,42]); [t,u] = [114,1218]; ? T = ellxn(E, 2, 'X) %2 = [X^4 - 34*X^2 - 336*X + 289, 4*X^3 + 68*X + 168] ? [a,b] = subst(T,'X,t); %3 = [168416137, 5934096] ? a / b == ellmul(E, [t,u], 2)[1] %4 = 1
- ellzeta(z, precision)¶
Computes the value at \(z\) of the Weierstrass \(\zeta\) function attached to the lattice \(w\) as given by
ellperiods
\((,1)\): including quasi-periods is useful, otherwise there are recomputed from scratch for each new \(z\).\[\zeta (z, L) = (1)/(z) + z^2\sum_{\omega\in L^*} (1)/(\omega^2(z-\omega)).\]It is also possible to directly input \(w = [\omega_1,\omega_2]\), or an elliptic curve \(E\) as given by
ellinit
(\(w = E.omega\)). The quasi-periods of \(\zeta\), such that\[\zeta (z + a\omega_1 + b\omega_2) = \zeta (z) + a\eta_1 + b\eta_2\]for integers \(a\) and \(b\) are obtained as \(\eta_i = 2\zeta (\omega_i/2)\). Or using directly
elleta
.? w = ellperiods([1,I],1); ? ellzeta(w, 1/2) %2 = 1.5707963267948966192313216916397514421 ? E = ellinit([1,0]); ? ellzeta(E, E.omega[1]/2) %4 = 0.84721308479397908660649912348219163647
One can also compute the series expansion around \(z = 0\) (the quasi-periods are useless in this case):
? E = ellinit([0,1]); ? ellzeta(E) \\ at 'x, implicitly at default seriesprecision %4 = x^-1 + 1/35*x^5 - 1/7007*x^11 + O(x^15) ? ellzeta(E, x + O(x^20)) \\ explicit precision %5 = x^-1 + 1/35*x^5 - 1/7007*x^11 + 1/1440257*x^17 + O(x^18)
- ellztopoint(z, precision)¶
\(E\) being an ell as output by
ellinit
, computes the coordinates \([x,y]\) on the curve \(E\) corresponding to the complex or \(p\)-adic parameter \(z\). Hence this is the inverse function ofellpointtoz
.If \(E\) is defined over a \(p\)-adic field and has multiplicative reduction, then \(z\) is understood as an element on the Tate curve \(\bar{Q}_p^* / q^\mathbb{Z}\).
? E = ellinit([0,-1,1,0,0], O(11^5)); ? [u2,u,q] = E.tate; type(u) %2 = "t_PADIC" \\ split multiplicative reduction ? z = ellpointtoz(E, [0,0]) %3 = 3 + 11^2 + 2*11^3 + 3*11^4 + 6*11^5 + 10*11^6 + 8*11^7 + O(11^8) ? ellztopoint(E,z) %4 = [O(11^9), O(11^9)] ? E = ellinit(ellfromj(1/4), O(2^6)); x=1/2; y=ellordinate(E,x)[1]; ? z = ellpointtoz(E,[x,y]); \\ nonsplit: t_POLMOD with t_PADIC coefficients ? P = ellztopoint(E, z); ? P[1] \\ y coordinate is analogous, more complicated %8 = Mod(O(2^4)*x + (2^-1 + O(2^5)), x^2 + (1 + 2^2 + 2^4 + 2^5 + O(2^7)))
If \(E\) is defined over the complex numbers (for instance over \(\mathbb{Q}\)), \(z\) is understood as a complex number in \(\mathbb{C}/\Lambda_E\). If the short Weierstrass equation is \(y^2 = 4x^3 - g_2x - g_3\), then \([x,y]\) represents the Weierstrass \(\wp\)-function and its derivative. For a general Weierstrass equation we have
\[ \begin{align}\begin{aligned} x = \wp (z) - b_2/12, y = \wp'(z)/2 - (a_1 x + a_3)/2.\\If :math:`z` is in the lattice defining :math:`E` over :math:`\mathbb{C}`, the result is the point at infinity :math:`[0]`.\end{aligned}\end{align} \]? 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 = [2.548947057811923643 E-57, 7.646841173435770930 E-57] ? ellztopoint(E, 0) %5 = [0] \\ point at infinity
- erfc(precision)¶
Complementary error function, analytic continuation of \((2/\sqrt\pi)\int_x^ oo e^{-t^2}dt = {sign(x)}incgam (1/2,x^2)/\sqrt\pi\) for real \(x != 0\). The latter expression extends the function definition from real \(x\) to complex \(x\) with positive real part (or zero real part and positive imaginary part). This is extended to the whole complex plane by the functional equation \(erfc (-x) = 2 - erfc (x)\).
? erfc(0) %1 = 1.0000000000000000000000000000000000000 ? erfc(1) %2 = 0.15729920705028513065877936491739074071 ? erfc(1+I) %3 = -0.31615128169794764488027108024367036903 - 0.19045346923783468628410886196916244244*I
- errname()¶
Returns the type of the error message
E
as a string.? iferr(1 / 0, E, print(errname(E))) e_INV ? ?? e_INV [...] * "e_INV". Tried to invert a noninvertible object x in function s. [...]
- eta(flag, precision)¶
Variants of Dedekind’s \(\eta\) function. If \(flag = 0\), return \(\prod_{n = 1}^ oo (1-q^n)\), where \(q\) depends on \(x\) in the following way:
\(q = e^{2i\pi x}\) if \(x\) is a complex number (which must then have positive imaginary part); notice that the factor \(q^{1/24}\) is missing!
\(q = x\) if \(x\) is a
t_PADIC
, or can be converted to a power series (which must then have positive valuation).
If \(flag\) is nonzero, \(x\) is converted to a complex number and we return the true \(\eta\) function, \(q^{1/24}\prod_{n = 1}^ oo (1-q^n)\), where \(q = e^{2i\pi x}\).
- eulerphi()¶
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 haveznstar:math:`(n)
.no = eulerphi(n)` for all \(n\in\mathbb{Z}\).
- exp(precision)¶
Exponential of \(x\). \(p\)-adic arguments with positive valuation are accepted.
- expm1(precision)¶
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 = 4 ms. ? default(realprecision, 10040); x = 1e-100; ? c = expm1(x); \\ reference point ? abs(a-c)/c \\ relative error in expm1(x) %7 = 1.4027986153764843997 E-10019 ? 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 more accurate thanexp(x)-1
.
- exponent()¶
When \(x\) is a
t_REAL
, the result is the binary exponent \(e\) of \(x\). For a nonzero \(x\), this is the unique integer \(e\) such that \(2^e <= \|x\| < 2^{e+1}\). For a real \(0\), this returns the PARI exponent \(e\) attached to \(x\) (which may represent any floating-point number less than \(2^e\) in absolute value).? exponent(Pi) %1 = 1 ? exponent(4.0) %2 = 2 ? exponent(0.0) %3 = -128 ? default(realbitprecision) %4 = 128
This definition extends naturally to nonzero integers, and the exponent of an exact \(0\) is \(-oo\) by convention.
For convenience, we define the exponent of a
t_FRAC
\(a/b\) as the difference ofexponent
\((a)\) andexponent
\((b)\); note that, if \(e'\) denotes the exponent of:math:`a/b
* 1.0`, then the exponent \(e\) we return is either \(e'\) or \(e'+1\), thus \(2^{e+1}\) is an upper bound for \(\|a/b\|\).? [ exponent(9), exponent(10), exponent(9/10), exponent(9/10*1.) ] %5 = [3, 3, 0, -1]
For a PARI object of type
t_COMPLEX
,t_POL
,t_SER
,t_VEC
,t_COL
,t_MAT
this returns the largest exponent found among the components of \(x\). Hence \(2^{e+1}\) is a quick upper bound for the sup norm of real matrices or polynomials; and \(2^{e+(3/2)}\) for complex ones.? exponent(3*x^2 + 15*x - 100) %5 = 6 ? exponent(0) %6 = -oo
- factor(D)¶
Factor \(x\) over domain \(D\); if \(D\) is omitted, it is determined from \(x\). For instance, if \(x\) is an integer, it is factored in \(\mathbb{Z}\), if it is a polynomial with rational coefficients, it is factored in \(\mathbb{Q}[x]\), etc., see below for details. 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:`x in mathbb{Q}.` See
factorint
for the algorithms used. The factorization includes the unit \(-1\) when \(x < 0\) and all other factors are positive; a denominator is factored with negative exponents. The factors are sorted in increasing order.? factor(-7/106) %1 = [-1 1] [ 2 -1] [ 7 1] [53 -1]
By convention, \(1\) is factored as
matrix(0,2)
(the empty factorization, printed as[;]
).Large rational “primes” \(> 2^{64}\) in the factorization are in fact pseudoprimes (see
ispseudoprime
), a priori not rigorously proven primes. Useisprime
to prove primality of these factors, as in? fa = factor(2^2^7 + 1) %2 = [59649589127497217 1] [5704689200685129054721 1] ? isprime( fa[,1] ) %3 = [1, 1]~ \\ both entries are proven primes
Another possibility is to globally set the default
factor_proven
, which will perform a rigorous primality proof for each pseudoprime factor but will slow down PARI.A
t_INT
argument \(D\) can be added, meaning that we only trial divide by all primes \(p < D\) and theaddprimes
entries, then skip all expensive factorization methods. The limit \(D\) must be nonnegative. In this case, one entry in the factorization may be a composite number: all factors less than \(D^2\) and primes from theaddprimes
table are actual primes. But (at most) one entry may not verify this criterion, and it may be prime or composite: it is only known to be coprime to all other entries and not a pure power..? factor(2^2^7 +1, 10^5) %4 = [340282366920938463463374607431768211457 1]
Deprecated feature. Setting \(D = 0\) is the same as setting it to \(primelimit + 1\).
This routine uses trial division and perfect power tests, and should not be used for huge values of \(D\) (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 more efficient way.? F = (2^2^7 + 1) * 1009 * (10^5+3); factor(F, 10^5) \\ fast, incomplete time = 0 ms. %5 = [1009 1] [34029257539194609161727850866999116450334371 1] ? factor(F, 10^9) \\ slow time = 3,260 ms. %6 = [1009 1] [100003 1] [340282366920938463463374607431768211457 1] ? factorint(F, 1+8) \\ much faster and all small primes were found time = 8 ms. %7 = [1009 1] [100003 1] [340282366920938463463374607431768211457 1] ? factor(F) \\ complete factorization time = 60 ms. %8 = [1009 1] [100003 1] [59649589127497217 1] [5704689200685129054721 1]
Setting \(D = I\) will factor in the Gaussian integers \(\mathbb{Z}[i]\):
:math:`x in mathbb{Q} (i).` The factorization is performed with Gaussian primes in \(\mathbb{Z}[i]\) and includes Gaussian units in \({±1, ± i}\); factors are sorted by increasing norm. Except for a possible leading unit, the Gaussian factors are normalized: rational factors are positive and irrational factors have positive imaginary part (a canonical represneta.
Unless
factor_proven
is set, large factors are actually pseudoprimes, not proven primes; a rational factor is prime if less than \(2^{64}\) and an irrational one if its norm is less than \(2^{64}\).? factor(5*I) %9 = [ 2 + I 1] [1 + 2*I 1]
One can force the factorization of a rational number by setting the domain \(D = I\):
? factor(-5, I) %10 = [ I 1] [ 2 + I 1] [1 + 2*I 1] ? factorback(%) %11 = -5
Univariate polynomials and rational functions. PARI can factor univariate polynomials in \(K[t]\). The following base fields \(K\) are currently supported: \(\mathbb{Q}\), \(\mathbb{R}\), \(\mathbb{C}\), \(\mathbb{Q}_p\), finite fields and number fields. See
factormod
andfactorff
for the algorithms used over finite fields andnffactor
for the algorithms over number fields. The irreducible factors are sorted by increasing degree and normalized: they are monic except when \(K = \mathbb{Q}\) where they are primitive in \(\mathbb{Z}[t]\).The content is not included in the factorization, in particular
factorback
will in general recover the original \(x\) only up to multiplication by an element of \(K^*\): when \(K != \mathbb{Q}\), this scalar ispollead
\((x)\) (since irreducible factors are monic); and when \(K = \mathbb{Q}\) you can either ask for the \(\mathbb{Q}\)-content explicitly of use factorback:? P = t^2 + 5*t/2 + 1; F = factor(P) %12 = [t + 2 1] [2*t + 1 1] ? content(P, 1) \\ Q-content %13 = 1/2 ? pollead(factorback(F)) / pollead(P) %14 = 2
You can specify \(K\) using the optional “domain” argument \(D\) as follows
\(K = \mathbb{Q}\) : \(D\) a rational number (
t_INT
ort_FRAC
),\(K = \mathbb{Z}/p\mathbb{Z}\) with \(p\) prime : \(D\) a
t_INTMOD
modulo \(p\); factoring modulo a composite number is not supported.\(K = \mathbb{F}_q\) : \(D\) a
t_FFELT
encoding the finite field; you can also use at_POLMOD
oft_INTMOD
modulo a prime \(p\) but this is usualy less convenient;\(K = \mathbb{Q}[X]/(T)\) a number field : \(D\) a
t_POLMOD
modulo \(T\),\(K = \mathbb{Q} (i)\) (alternate syntax for special case): \(D = I\),
\(K = \mathbb{Q} (w)\) a quadratic number field (alternate syntax for special case): \(D\) a
t_QUAD
,\(K = \mathbb{R}\) : \(D\) a real number (
t_REAL
); truncate the factorization at accuracyprecision
\((D)\). If \(x\) is inexact andprecision
\((x)\) is less thanprecision
\((D)\), then the precision of \(x\) is used instead.\(K = \mathbb{C}\) : \(D\) a complex number with a
t_REAL
component, e.g.I * 1.
; truncate the factorization as for \(K = \mathbb{R}\),\(K = \mathbb{Q}_p\) : \(D\) a
t_PADIC
; truncate the factorization at \(p\)-adic accuracypadicprec
\((D)\), possibly less if \(x\) is inexact with insufficient \(p\)-adic accuracy;
? T = x^2+1; ? factor(T, 1); \\ 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, O(3^6)) \\ over Q_3, precision 6 ? factor(T, 1.) \\ over R, current precision ? factor(T, I*1.) \\ over C ? factor(T, Mod(1, y^3-2)) \\ over Q(2^{1/3})
In most cases, it is possible and simpler to call a specialized variant rather than use the above scheme:
? factormod(T, 3) \\ over F_3 ? factormod(T, [t^2+t+2, 3]) \\ over F_{3^2} ? factormod(T, ffgen(3^2, 't)) \\ 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 ? polrootsreal(T) \\ over R (real polynomial)
It is also possible to let the routine use the smallest field containing all coefficients, taking into account quotient structures induced by
t_INTMOD
s andt_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):? 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})
Multiplying by a suitable field element equal to \(1 \in K\) in this way is error-prone and is not recommanded. Factoring existing polynomials with obvious fields of coefficients is fine, the domain argument \(D\) should be used instead ad hoc conversions.
Note on inexact polynomials. Polynomials with inexact coefficients (e.g. floating point or \(p\)-adic numbers) are first rounded to an exact representation, then factored to (potentially) infinite accuracy and we return a truncated approximation of that virtual factorization. To avoid pitfalls, we advise to only factor exact polynomials:
? factor(x^2-1+O(2^2)) \\ rounded to x^2 + 3, irreducible in Q_2 %1 = [(1 + O(2^2))*x^2 + O(2^2)*x + (1 + 2 + O(2^2)) 1] ? factor(x^2-1+O(2^3)) \\ rounded to x^2 + 7, reducible ! %2 = [ (1 + O(2^3))*x + (1 + 2 + O(2^3)) 1] [(1 + O(2^3))*x + (1 + 2^2 + O(2^3)) 1] ? factor(x^2-1, O(2^2)) \\ no ambiguity now %3 = [ (1 + O(2^2))*x + (1 + O(2^2)) 1] [(1 + O(2^2))*x + (1 + 2 + O(2^2)) 1]
Note about inseparable polynomials. Polynomials with inexact coefficients are considered to be squarefree: indeed, there exist a squarefree polynomial arbitrarily close to the input, and they cannot be distinguished at the input accuracy. This means that irreducible factors are repeated according to their apparent multiplicity. On the contrary, using a specialized function such as
factorpadic
with an exact rational input yields the correct multiplicity when the (now exact) input is not separable. Compare:? factor(z^2 + O(5^2))) %1 = [(1 + O(5^2))*z + O(5^2) 1] [(1 + O(5^2))*z + O(5^2) 1] ? factor(z^2, O(5^2)) %2 = [1 + O(5^2))*z + O(5^2) 2]
Multivariate polynomials and rational functions. PARI recursively factors multivariate polynomials in \(K[t_1,..., t_d]\) for the same fields \(K\) as above and the argument \(D\) is used in the same way to specify \(K\). The irreducible factors are sorted by their main variable (least priority first) then by increasing degree.
? factor(x^2 + y^2, Mod(1,5)) %1 = [ x + Mod(2, 5)*y 1] [Mod(1, 5)*x + Mod(3, 5)*y 1] ? factor(x^2 + y^2, O(5^2)) %2 = [ (1 + O(5^2))*x + (O(5^2)*y^2 + (2 + 5 + O(5^2))*y + O(5^2)) 1] [(1 + O(5^2))*x + (O(5^2)*y^2 + (3 + 3*5 + O(5^2))*y + O(5^2)) 1] ? lift(%) %3 = [ x + 7*y 1] [x + 18*y 1]
Note that the implementation does not really support inexact real fields (\(\mathbb{R}\) or \(\mathbb{C}\)) and usually misses factors even if the input is exact:
? factor(x^2 + y^2, I) \\ over Q(i) %4 = [x - I*y 1] [x + I*y 1] ? factor(x^2 + y^2, I*1.) \\ over C %5 = [x^2 + y^2 1]
- factorback(e)¶
Gives back the factored object corresponding to a factorization. The integer \(1\) corresponds to the empty factorization.
If \(e\) is present, \(e\) and \(f\) must be vectors of the same length (\(e\) being integral), and the corresponding factorization is the product of the \(f[i]^{e[i]}\).
If not, and \(f\) is vector, it is understood as in the preceding case with \(e\) a vector of 1s: we return the product of the \(f[i]\). Finally, \(f\) can be a regular factorization, as produced with any
factor
command. A few examples:? factor(12) %1 = [2 2] [3 1] ? factorback(%) %2 = 12 ? factorback([2,3], [2,1]) \\ 2^3 * 3^1 %3 = 12 ? factorback([5,2,3]) %4 = 30
- factorcantor(p)¶
This function is obsolete, use factormod.
- factorff(p, a)¶
Obsolete, kept for backward compatibility: use factormod.
- factorint(flag)¶
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 forfactor
: 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 if they are larger than \(2^{64}\), they only failed the BPSW compositeness test (see
ispseudoprime
). Useisprime
on the result if you want to guarantee primality or set thefactor_proven
default to \(1\). Entries of the private prime tables (seeaddprimes
) 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
’sdebug
default parameter (level 3 shows just the outline, 4 turns on time keeping, 5 and above show an increasing amount of internal details).
- factormod(D, flag)¶
Factors the polynomial \(f\) over the finite field defined by the domain \(D\) as follows:
\(D = p\) a prime: factor over \(\mathbb{F}_p\);
\(D = [T,p]\) for a prime \(p\) and \(T(y)\) an irreducible polynomial over \(\mathbb{F}_p\): factor over \(\mathbb{F}_p[y]/(T)\) (as usual the main variable of \(T\) must have lower priority than the main variable of \(f\));
\(D\) a
t_FFELT
: factor over the attached field;\(D\) omitted: factor over the field of definition of \(f\), which must be a finite field.
The coefficients of \(f\) must be operation-compatible with the corresponding finite field. The result is a two-column matrix, the first column being the irreducible polynomials dividing \(f\), and the second the exponents. By convention, the \(0\) polynomial factors as \(0^1\); a nonzero constant polynomial has empty factorization, a \(0 x 2\) matrix. The irreducible factors are ordered by increasing degree and the result is canonical: it will not change across multiple calls or sessions.
? factormod(x^2 + 1, 3) \\ over F_3 %1 = [Mod(1, 3)*x^2 + Mod(1, 3) 1] ? liftall( factormod(x^2 + 1, [t^2+1, 3]) ) \\ over F_9 %2 = [ x + t 1] [x + 2*t 1] \\ same, now letting GP choose a model ? T = ffinit(3,2,'t) %3 = Mod(1, 3)*t^2 + Mod(1, 3)*t + Mod(2, 3) ? liftall( factormod(x^2 + 1, [T, 3]) ) %4 = \\ t is a root of T ! [ x + (t + 2) 1] [x + (2*t + 1) 1] ? t = ffgen(t^2+Mod(1,3)); factormod(x^2 + t^0) \\ same using t_FFELT %5 = [ x + t 1] [x + 2*t 1] ? factormod(x^2+Mod(1,3)) %6 = [Mod(1, 3)*x^2 + Mod(1, 3) 1] ? liftall( factormod(x^2 + Mod(Mod(1,3), y^2+1)) ) %7 = [ x + y 1] [x + 2*y 1]
If \(flag\) is nonzero, outputs only the degrees of the irreducible polynomials (for example to compute an \(L\)-function). By convention, a constant polynomial (including the \(0\) polynomial) has empty factorization. The degrees appear in increasing order but need not correspond to the ordering with \(flag = 0\) when multiplicities are present.
? f = x^3 + 2*x^2 + x + 2; ? factormod(f, 5) \\ (x+2)^2 * (x+3) %1 = [Mod(1, 5)*x + Mod(2, 5) 2] [Mod(1, 5)*x + Mod(3, 5) 1] ? factormod(f, 5, 1) \\ (deg 1) * (deg 1)^2 %2 = [1 1] [1 2]
- factormodDDF(D)¶
Distinct-degree factorization of the squarefree polynomial \(f\) over the finite field defined by the domain \(D\) as follows:
\(D = p\) a prime: factor over \(\mathbb{F}_p\);
\(D = [T,p]\) for a prime \(p\) and \(T\) an irreducible polynomial over \(\mathbb{F}_p\): factor over \(\mathbb{F}_p[x]/(T)\);
\(D\) a
t_FFELT
: factor over the attached field;\(D\) omitted: factor over the field of definition of \(f\), which must be a finite field.
This is somewhat faster than full factorization. The coefficients of \(f\) must be operation-compatible with the corresponding finite field. The result is a two-column matrix:
the first column contains monic (squarefree) pairwise coprime polynomials dividing \(f\), all of whose irreducible factors have degree \(d\);
the second column contains the degrees of the irreducible factors.
The factors are ordered by increasing degree and the result is canonical: it will not change across multiple calls or sessions.
? f = (x^2 + 1) * (x^2-1); ? factormodSQF(f,3) \\ squarefree over F_3 %2 = [Mod(1, 3)*x^4 + Mod(2, 3) 1] ? factormodDDF(f, 3) %3 = [Mod(1, 3)*x^2 + Mod(2, 3) 1] \\ two degree 1 factors [Mod(1, 3)*x^2 + Mod(1, 3) 2] \\ irred of degree 2 ? for(i=1,10^5,factormodDDF(f,3)) time = 424 ms. ? for(i=1,10^5,factormod(f,3)) \\ full factorization is slower time = 464 ms. ? liftall( factormodDDF(x^2 + 1, [3, t^2+1]) ) \\ over F_9 %6 = [x^2 + 1 1] \\ product of two degree 1 factors ? t = ffgen(t^2+Mod(1,3)); factormodDDF(x^2 + t^0) \\ same using t_FFELT %7 = [x^2 + 1 1] ? factormodDDF(x^2-Mod(1,3)) %8 = [Mod(1, 3)*x^2 + Mod(2, 3) 1]
- factormodSQF(D)¶
Squarefree factorization of the polynomial \(f\) over the finite field defined by the domain \(D\) as follows:
\(D = p\) a prime: factor over \(\mathbb{F}_p\);
\(D = [T,p]\) for a prime \(p\) and \(T\) an irreducible polynomial over \(\mathbb{F}_p\): factor over \(\mathbb{F}_p[x]/(T)\);
\(D\) a
t_FFELT
: factor over the attached field;\(D\) omitted: factor over the field of definition of \(f\), which must be a finite field.
This is somewhat faster than full factorization. The coefficients of \(f\) must be operation-compatible with the corresponding finite field. The result is a two-column matrix:
the first column contains monic squarefree pairwise coprime polynomials dividing \(f\);
the second column contains the power to which the polynomial in column \(1\) divides \(f\);
The factors are ordered by increasing degree and the result is canonical: it will not change across multiple calls or sessions.
? f = (x^2 + 1)^3 * (x^2-1)^2; ? factormodSQF(f, 3) \\ over F_3 %1 = [Mod(1, 3)*x^2 + Mod(2, 3) 2] [Mod(1, 3)*x^2 + Mod(1, 3) 3] ? for(i=1,10^5,factormodSQF(f,3)) time = 192 ms. ? for(i=1,10^5,factormod(f,3)) \\ full factorization is slower time = 409 ms. ? liftall( factormodSQF((x^2 + 1)^3, [3, t^2+1]) ) \\ over F_9 %4 = [x^2 + 1 3] ? t = ffgen(t^2+Mod(1,3)); factormodSQF((x^2 + t^0)^3) \\ same using t_FFELT %5 = [x^2 + 1 3] ? factormodSQF(x^8 + x^7 + x^6 + x^2 + x + Mod(1,2)) %6 = [ Mod(1, 2)*x + Mod(1, 2) 2] [Mod(1, 2)*x^2 + Mod(1, 2)*x + Mod(1, 2) 3]
- factornf(t)¶
This function is obsolete, use
nffactor
.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 nonrational number field elements occur (as polmods or polynomials) as coefficients of \(x\), the variable of these polmods must be the same as the main variable of \(t\). For example? factornf(x^2 + Mod(y, y^2+1), y^2+1); ? factornf(x^2 + y, y^2+1); \\ these two are OK ? factornf(x^2 + Mod(z,z^2+1), y^2+1) *** at top-level: factornf(x^2+Mod(z,z *** ^-------------------- *** factornf: inconsistent data in rnf function. ? factornf(x^2 + z, y^2+1) *** at top-level: factornf(x^2+z,y^2+1 *** ^-------------------- *** factornf: incorrect variable in rnf function.
- factorpadic(p, r)¶
\(p\)-adic factorization of the polynomial pol to precision \(r\), the result being a two-column matrix as in
factor
. Note that this is not the same as a factorization over \(\mathbb{Z}/p^r\mathbb{Z}\) (polynomials over that ring do not form a unique factorization domain, anyway), but approximations in \(\mathbb{Q}/p^r\mathbb{Z}\) of the true factorization in \(\mathbb{Q}_p[X]\).? factorpadic(x^2 + 9, 3,5) %1 = [(1 + O(3^5))*x^2 + O(3^5)*x + (3^2 + O(3^5)) 1] ? factorpadic(x^2 + 1, 5,3) %2 = [ (1 + O(5^3))*x + (2 + 5 + 2*5^2 + O(5^3)) 1] [(1 + O(5^3))*x + (3 + 3*5 + 2*5^2 + O(5^3)) 1]
The factors are normalized so that their leading coefficient is a power of \(p\). The method used is a modified version of the round 4 algorithm of Zassenhaus.
If pol has inexact
t_PADIC
coefficients, this is not always well-defined; in this case, the polynomial is first made integral by dividing out the \(p\)-adic content, then lifted to \(\mathbb{Z}\) usingtruncate
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.
- ffcompomap(g)¶
Let \(k\), \(l\), \(m\) be three finite fields and \(f\) a (partial) map from \(l\) to \(m\) and \(g\) a (partial) map from \(k\) to \(l\), return the (partial) map \(f o g\) from \(k\) to \(m\).
a = ffgen([3,5],'a); b = ffgen([3,10],'b); c = ffgen([3,20],'c); m = ffembed(a, b); n = ffembed(b, c); rm = ffinvmap(m); rn = ffinvmap(n); nm = ffcompomap(n,m); ffmap(n,ffmap(m,a)) == ffmap(nm, a) %5 = 1 ffcompomap(rm, rn) == ffinvmap(nm) %6 = 1
- ffembed(b)¶
Given two finite fields elements \(a\) and \(b\), return a map embedding the definition field of \(a\) to the definition field of \(b\). Assume that the latter contains the former.
? a = ffgen([3,5],'a); ? b = ffgen([3,10],'b); ? m = ffembed(a, b); ? A = ffmap(m, a); ? minpoly(A) == minpoly(a) %5 = 1
- ffextend(P, v)¶
Extend the field \(K\) of definition of \(a\) by a root of the polynomial \(P\in K[X]\) assumed to be irreducible over \(K\). Return \([r, m]\) where \(r\) is a root of \(P\) in the extension field \(L\) and \(m\) is a map from \(K\) to \(L\), see
ffmap
. If \(v\) is given, the variable name is used to display the generator of \(L\), else the name of the variable of \(P\) is used. A generator of \(L\) can be recovered using \(b = ffgen(r)\). The image of \(P\) in \(L[X]\) can be recovered using \(PL = ffmap(m,P)\).? a = ffgen([3,5],'a); ? P = x^2-a; polisirreducible(P) %2 = 1 ? [r,m] = ffextend(a, P, 'b); ? r %3 = b^9+2*b^8+b^7+2*b^6+b^4+1 ? subst(ffmap(m, P), x, r) %4 = 0 ? ffgen(r) %5 = b
- fffrobenius(n)¶
Return the \(n\)-th power of the Frobenius map over the field of definition of \(m\).
? a = ffgen([3,5],'a); ? f = fffrobenius(a); ? ffmap(f,a) == a^3 %3 = 1 ? g = fffrobenius(a, 5); ? ffmap(g,a) == a %5 = 1 ? h = fffrobenius(a, 2); ? h == ffcompomap(f,f) %7 = 1
- ffgen(v)¶
Return a generator for the finite field \(k\) as a
t_FFELT
. The field \(k\) can be given byits order \(q\)
the pair \([p,f]\) where \(q = p^f\)
a monic irreducible polynomial with
t_INTMOD
coefficients modulo a prime.a
t_FFELT
belonging to \(k\).
If
v
is given, the variable name is used to display \(g\), else the variable of the polynomial or thet_FFELT
is used, else \(x\) is used.When only the order is specified, the function uses the polynomial generated by
ffinit
and is deterministic: two calls to the function with the same parameters will always give the same generator.For efficiency, the characteristic is not checked to be prime; similarly if a polynomial is given, we do not check whether it is irreducible.
To obtain a multiplicative generator, call
ffprimroot
on the result.? g = ffgen(16, 't); ? g.mod \\ recover the underlying polynomial. %2 = t^4+t^3+t^2+t+1 ? g.pol \\ lift g as a t_POL %3 = t ? g.p \\ recover the characteristic %4 = 2 ? fforder(g) \\ g is not a multiplicative generator %5 = 5 ? a = ffprimroot(g) \\ recover a multiplicative generator %6 = t^3+t^2+t ? fforder(a) %7 = 15
- ffinit(n, v)¶
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 ifP = ffinit(3,2)
, you can represent elements in \(\mathbb{F}_{3^2}\) in term ofg = ffgen(P,'t)
. This can be abbreviated asg = ffgen(3^2, 't)
, where the defining polynomial \(P\) can be later recovered asg.mod
.
- ffinvmap()¶
\(m\) being a map from \(K\) to \(L\) two finite fields, return the partial map \(p\) from \(L\) to \(K\) such that for all \(k\in K\), \(p(m(k)) = k\).
? a = ffgen([3,5],'a); ? b = ffgen([3,10],'b); ? m = ffembed(a, b); ? p = ffinvmap(m); ? u = random(a); ? v = ffmap(m, u); ? ffmap(p, v^2+v+2) == u^2+u+2 %7 = 1 ? ffmap(p, b) %8 = []
- fflog(g, o)¶
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)]
, whereord
is the order of \(g\). It may be set as a side effect of callingffprimroot
. The result is undefined if \(e\) does not exist. This function usesa combination of generic discrete log algorithms (see
znlog
)a cubic sieve index calculus algorithm for large fields of degree at least \(5\).
Coppersmith’s algorithm for fields of characteristic at most \(5\).
? t = ffgen(ffinit(7,5)); ? o = fforder(t) %2 = 5602 \\ not a primitive root. ? fflog(t^10,t) %3 = 10 ? fflog(t^10,t, o) %4 = 10 ? g = ffprimroot(t, &o); ? o \\ order is 16806, bundled with its factorization matrix %6 = [16806, [2, 1; 3, 1; 2801, 1]] ? fforder(g, o) %7 = 16806 ? fflog(g^10000, g, o) %8 = 10000
- ffmap(x)¶
Given a (partial) map \(m\) between two finite fields, return the image of \(x\) by \(m\). The function is applied recursively to the component of vectors, matrices and polynomials. If \(m\) is a partial map that is not defined at \(x\), return \([]\).
? a = ffgen([3,5],'a); ? b = ffgen([3,10],'b); ? m = ffembed(a, b); ? P = x^2+a*x+1; ? Q = ffmap(m,P); ? ffmap(m,poldisc(P)) == poldisc(Q) %6 = 1
- ffmaprel(x)¶
Given a (partial) map \(m\) between two finite fields, express \(x\) as an algebraic element over the codomain of \(m\) in a way which is compatible with \(m\). The function is applied recursively to the component of vectors, matrices and polynomials.
? a = ffgen([3,5],'a); ? b = ffgen([3,10],'b); ? m = ffembed(a, b); ? mi= ffinvmap(m); ? R = ffmaprel(mi,b) %5 = Mod(b,b^2+(a+1)*b+(a^2+2*a+2))
In particular, this function can be used to compute the relative minimal polynomial, norm and trace:
? minpoly(R) %6 = x^2+(a+1)*x+(a^2+2*a+2) ? trace(R) %7 = 2*a+2 ? norm(R) %8 = a^2+2*a+2
- ffnbirred(n, fl)¶
Computes the number of monic irreducible polynomials over \(\mathbb{F}_q\) of degree exactly \(n\), (\(flag = 0\) or omitted) or at most \(n\) (\(flag = 1\)).
- fforder(o)¶
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)]
, whereN
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
- ffprimroot(o)¶
Return a primitive root of the multiplicative group of the definition field of the finite field element \(x\) (not necessarily the same as the field generated by \(x\)). If present, \(o\) is set to a vector
[ord, fa]
, whereord
is the order of the group andfa
its factorizationfactor(ord)
. This last parameter is useful infflog
andfforder
, seeDLfun
(in the PARI manual).? t = ffgen(ffinit(nextprime(10^7), 5)); ? g = ffprimroot(t, &o); ? o[1] %3 = 100000950003610006859006516052476098 ? o[2] %4 = [2 1] [7 2] [31 1] [41 1] [67 1] [1523 1] [10498781 1] [15992881 1] [46858913131 1] ? fflog(g^1000000, g, o) time = 1,312 ms. %5 = 1000000
- fft(P)¶
Let \(w = [1,z,...,z^{N-1}]\) from some primitive \(N\)-roots of unity \(z\) where \(N\) is a power of \(2\), and \(P\) be a polynomial \(< N\), return the unnormalized discrete Fourier transform of \(P\), \({ P(w[i]), 1 <= i <= N}\). Also allow \(P\) to be a vector \([p_0,...,p_n]\) representing the polynomial \(\sum p_i X^i\). Composing
fft
andfftinv
returns \(N\) times the original input coefficients.? w = rootsof1(4); fft(w, x^3+x+1) %1 = [3, 1, -1, 1] ? fftinv(w, %) %2 = [4, 4, 0, 4] ? Polrev(%) / 4 %3 = x^3 + x + 1 ? w = powers(znprimroot(5),3); fft(w, x^3+x+1) %4 = [Mod(3,5),Mod(1,5),Mod(4,5),Mod(1,5)] ? fftinv(w, %) %5 = [Mod(4,5),Mod(4,5),Mod(0,5),Mod(4,5)]
- fftinv(P)¶
Let \(w = [1,z,...,z^{N-1}]\) from some primitive \(N\)-roots of unity \(z\) where \(N\) is a power of \(2\), and \(P\) be a polynomial \(< N\), return the unnormalized discrete Fourier transform of \(P\), \({ P(1 / w[i]), 1 <= i <= N}\). Also allow \(P\) to be a vector \([p_0,...,p_n]\) representing the polynomial \(\sum p_i X^i\). Composing
fft
andfftinv
returns \(N\) times the original input coefficients.? w = rootsof1(4); fft(w, x^3+x+1) %1 = [3, 1, -1, 1] ? fftinv(w, %) %2 = [4, 4, 0, 4] ? Polrev(%) / 4 %3 = x^3 + x + 1 ? N = 512; w = rootsof1(N); T = random(1000 * x^(N-1)); ? U = fft(w, T); time = 3 ms. ? V = vector(N, i, subst(T, 'x, w[i])); time = 65 ms. ? exponent(V - U) %7 = -97 ? round(Polrev(fftinv(w,U) / N)) == T %8 = 1
- fileflush()¶
Flushes the file descriptor \(n\), created via
fileopen
orfileextern
. On files opened for writing, this function forces a write of all buffered data to the file system and completes all pending write operations. This function is implicitly called byfileclose
but you may want to call it explicitly at synchronization points, for instance after writing a large result to file and before printing diagnostics on screen. (In order to be sure that the file contains the expected content on inspection.)If \(n\) is omitted, flush all descriptors to output streams.
? n = fileopen("./here", "w"); ? for (i = 1, 10^5, \ filewrite(n, i^2+1); \ if (i % 10000 == 0, fileflush(n)))
Until a
fileflush
orfileclose
, there is no guarantee that the file contains all the expected data from previousfilewrite
s.
- floor()¶
Floor of \(x\). When \(x\) is in \(\mathbb{R}\), the result is the largest integer smaller than or equal to \(x\). Applied to a rational function, \(floor (x)\) returns the Euclidean quotient of the numerator by the denominator.
- fold(A)¶
Apply the
t_CLOSURE
f
of arity \(2\) to the entries ofA
, in order to returnf(...f(f(A[1],A[2]),A[3])...,A[#A])
.? fold((x,y)->x*y, [1,2,3,4]) %1 = 24 ? fold((x,y)->[x,y], [1,2,3,4]) %2 = [[[1, 2], 3], 4] ? fold((x,f)->f(x), [2,sqr,sqr,sqr]) %3 = 256 ? fold((x,y)->(x+y)/(1-x*y),[1..5]) %4 = -9/19 ? bestappr(tan(sum(i=1,5,atan(i)))) %5 = -9/19
- frac()¶
Fractional part of \(x\). Identical to \(x-floor(x)\). If \(x\) is real, the result is in \([0,1[\).
- fromdigits(b)¶
Gives the integer formed by the elements of \(x\) seen as the digits of a number in base \(b\) (\(b = 10\) by default). This is the reverse of
digits
:? digits(1234,5) %1 = [1,4,4,1,4] ? fromdigits([1,4,4,1,4],5) %2 = 1234
By convention, \(0\) has no digits:
? fromdigits([]) %3 = 0
- galoischardet(chi, o)¶
Let \(G\) be the group attached to the
galoisinit
structure gal, and let \(\chi\) be the character of some representation \(\rho\) of the group \(G\), where a polynomial variable is to be interpreted as an \(o\)-th root of 1. For instance, if[T,o] = galoischartable(gal)
the characters \(\chi\) are input as the columns ofT
.Return the degree-\(1\) character \(\det\rho\) as the list of \(\det \rho (g)\), where \(g\) runs through representatives of the conjugacy classes in
galoisconjclasses(gal)
, with the same ordering.? P = x^5 - x^4 - 5*x^3 + 4*x^2 + 3*x - 1; ? polgalois(P) %2 = [10, 1, 1, "D(5) = 5:2"] ? K = nfsplitting(P); ? gal = galoisinit(K); \\ dihedral of order 10 ? [T,o] = galoischartable(gal); ? chi = T[,1]; \\ trivial character ? galoischardet(gal, chi, o) %7 = [1, 1, 1, 1]~ ? [galoischardet(gal, T[,i], o) | i <- [1..#T]] \\ all characters %8 = [[1, 1, 1, 1]~, [1, 1, -1, 1]~, [1, 1, -1, 1]~, [1, 1, -1, 1]~]
- galoischarpoly(chi, o)¶
Let \(G\) be the group attached to the
galoisinit
structure gal, and let \(\chi\) be the character of some representation \(\rho\) of the group \(G\), where a polynomial variable is to be interpreted as an \(o\)-th root of 1, e.g., if[T,o] = galoischartable(gal)
and \(\chi\) is a column ofT
. Return the list of characteristic polynomials \(\det (1 - \rho (g)T)\), where \(g\) runs through representatives of the conjugacy classes ingaloisconjclasses(gal)
, with the same ordering.? T = x^5 - x^4 - 5*x^3 + 4*x^2 + 3*x - 1; ? polgalois(T) %2 = [10, 1, 1, "D(5) = 5:2"] ? K = nfsplitting(T); ? gal = galoisinit(K); \\ dihedral of order 10 ? [T,o] = galoischartable(gal); ? o %5 = 5 ? galoischarpoly(gal, T[,1], o) \\ T[,1] is the trivial character %6 = [-x + 1, -x + 1, -x + 1, -x + 1]~ ? galoischarpoly(gal, T[,3], o) %7 = [x^2 - 2*x + 1, x^2 + (y^3 + y^2 + 1)*x + 1, -x^2 + 1, x^2 + (-y^3 - y^2)*x + 1]~
- galoischartable()¶
Compute the character table of \(G\), where \(G\) is the underlying group of the
galoisinit
structure gal. The input gal is also allowed to be at_VEC
of permutations that is closed under products. Let \(N\) be the number of conjugacy classes of \(G\). Return at_VEC
\([M,e]\) where \(e >= 1\) is an integer and \(M\) is a squaret_MAT
of size \(N\) giving the character table of \(G\).Each column corresponds to an irreducible character; the characters are ordered by increasing dimension and the first column is the trivial character (hence contains only \(1\)’s).
Each row corresponds to a conjugacy class; the conjugacy classes are ordered as specified by
galoisconjclasses(gal)
, in particular the first row corresponds to the identity and gives the dimension \(\chi (1)\) of the irreducible representation attached to the successive characters \(\chi\).
The value \(M[i,j]\) of the character \(j\) at the conjugacy class \(i\) is represented by a polynomial in
y
whose variable should be interpreted as an \(e\)-th root of unity, i.e. as the lift ofMod(y, polcyclo(e,'y))
(Note that \(M\) is the transpose of the usual orientation for character tables.)
The integer \(e\) divides the exponent of the group \(G\) and is chosen as small as posible; for instance \(e = 1\) when the characters are all defined over \(\mathbb{Q}\), as is the case for \(S_n\). Examples:
? K = nfsplitting(x^4+x+1); ? gal = galoisinit(K); ? [M,e] = galoischartable(gal); ? M~ \\ take the transpose to get the usual orientation %4 = [1 1 1 1 1] [1 -1 -1 1 1] [2 0 0 -1 2] [3 -1 1 0 -1] [3 1 -1 0 -1] ? e %5 = 1 ? {G = [Vecsmall([1, 2, 3, 4, 5]), Vecsmall([1, 5, 4, 3, 2]), Vecsmall([2, 1, 5, 4, 3]), Vecsmall([2, 3, 4, 5, 1]), Vecsmall([3, 2, 1, 5, 4]), Vecsmall([3, 4, 5, 1, 2]), Vecsmall([4, 3, 2, 1, 5]), Vecsmall([4, 5, 1, 2, 3]), Vecsmall([5, 1, 2, 3, 4]), Vecsmall([5, 4, 3, 2, 1])];} \\G = D10 ? [M,e] = galoischartable(G); ? M~ %8 = [1 1 1 1] [1 -1 1 1] [2 0 -y^3 - y^2 - 1 y^3 + y^2] [2 0 y^3 + y^2 -y^3 - y^2 - 1] ? e %9 = 5
- galoisconjclasses()¶
gal being output by
galoisinit
, return the list of conjugacy classes of the underlying group. The ordering of the classes is consistent withgaloischartable
and the trivial class comes first.? G = galoisinit(x^6+108); ? galoisidentify(G) %2 = [6, 1] \\ S_3 ? S = galoisconjclasses(G) %3 = [[Vecsmall([1,2,3,4,5,6])], [Vecsmall([3,1,2,6,4,5]),Vecsmall([2,3,1,5,6,4])], [Vecsmall([6,5,4,3,2,1]),Vecsmall([5,4,6,2,1,3]), Vecsmall([4,6,5,1,3,2])]] ? [[permorder(c[1]),#c] | c <- S ] %4 = [[1,1], [3,2], [2,3]]
This command also accepts subgroups returned by
galoissubgroups
:? subs = galoissubgroups(G); H = subs[5]; ? galoisidentify(H) %2 = [2, 1] \\ Z/2 ? S = galoisconjclasses(subgroups_of_G[5]); ? [[permorder(c[1]),#c] | c <- S ] %4 = [[1,1], [2,1]]
- galoisexport(flag)¶
gal being be a Galois group as output by
galoisinit
, export the underlying permutation group as a string suitable for (no flags or \(flag = 0\)) GAP or (\(flag = 1\)) Magma. The following example compute the index of the underlying abstract group in the GAP library:? G = galoisinit(x^6+108); ? s = galoisexport(G) %2 = "Group((1, 2, 3)(4, 5, 6), (1, 4)(2, 6)(3, 5))" ? extern("echo \"IdGroup("s");\" | gap -q") %3 = [6, 1] ? galoisidentify(G) %4 = [6, 1]
This command also accepts subgroups returned by
galoissubgroups
.To import a GAP permutation into gp (for
galoissubfields
for instance), the following GAP function may be useful:PermToGP := function(p, n) return Permuted([1..n],p); end; gap> p:= (1,26)(2,5)(3,17)(4,32)(6,9)(7,11)(8,24)(10,13)(12,15)(14,27) (16,22)(18,28)(19,20)(21,29)(23,31)(25,30) gap> PermToGP(p,32); [ 26, 5, 17, 32, 2, 9, 11, 24, 6, 13, 7, 15, 10, 27, 12, 22, 3, 28, 20, 19, 29, 16, 31, 8, 30, 1, 14, 18, 21, 25, 23, 4 ]
- galoisfixedfield(perm, flag, v)¶
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)). In this case, \(P\) is also expressed in the variable \(v\) for compatibility with \(F\). Example:? G = galoisinit(x^4+1); ? galoisfixedfield(G,G.group[2],2) %2 = [y^2 - 2, Mod(- x^3 + x, x^4 + 1), [x^2 - y*x + 1, x^2 + y*x + 1]]
computes the factorization \(x^4+1 = (x^2-\sqrt{2}x+1)(x^2+\sqrt{2}x+1)\)
- galoisidentify()¶
gal 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 GAP4IdGroup
handles all groups of order less than \(2000\) except \(1024\), so you can usegaloisexport
and GAP4 to identify large Galois groups.
- galoisinit(den)¶
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 \(48\) 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\), \(S_4\) or the group \((3 x 3):4\) (
GAP4(36,9)
) then \([o_1,...,o_g]\) ends by \([3,3,4]\).In practice, almost all small groups are WKSS, the exceptions having order 48(2), 56(1), 60(1), 72(3), 75(1), 80(1), 96(10), 112(1), 120(3) and \(>= 144\).
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]\).
* if \(G/H_n ~ (3 x 3):4\) (
GAP4(36,9)
) then \([o_1,...,o_g]\) ends by \([3,3,4]\).* for \(1 <= i <= g\) the subgroup of \(G\) generated by \([s_1,...,s_i]\) is normal, with the exception of \(i = g-2\) in the \(A_4\) case and of \(i = g-3\) in the \(S_4\) 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\in G\) there exists a unique family \([e_1,...,e_g]\) such that (no exceptions):
– for \(1 <= i <= g\) we have \(0 <= e_i < o_i\)
– \(x = g_1^{e_1}g_2^{e_2}...g_n^{e_n}\)
If present \(den\) must be a suitable value for \(gal[5]\).
- galoisisabelian(flag)¶
gal being as output by
galoisinit
, return \(0\) if gal is not an abelian group, and the HNF matrix of gal overgal.gen
if \(flag = 0\), \(1\) if \(flag = 1\), and the SNF matrix of gal if \(flag = 2\).This command also accepts subgroups returned by
galoissubgroups
.
- galoisisnormal(subgrp)