Interface to the PARI library¶
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): split off this file from gen.pyx (Sage ticket #15185)
Jeroen Demeyer (2014-02-09): upgrade to PARI 2.7 (Sage ticket #15767)
Jeroen Demeyer (2014-09-19): 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)Luca De Feo (2016-09-06): Separate Sage-specific components from generic C-interface in
Pari
(Sage ticket #20241)
Examples:
>>> import cypari2
>>> pari = cypari2.Pari()
>>> pari('5! + 10/x')
(120*x + 10)/x
>>> pari('intnum(x=0,13,sin(x)+sin(x^2) + x)')
85.6215190762676
>>> f = pari('x^3 - 1')
>>> v = f.factor(); v
[x - 1, 1; x^2 + x + 1, 1]
>>> v[0] # indexing is 0-based unlike in GP.
[x - 1, x^2 + x + 1]~
>>> v[1]
[1, 1]~
For most functions, you can call the function as method of pari
or you can first create a Gen
object and then call the
function as method of that. In other words, the following two commands
do the same:
>>> pari('x^3 - 1').factor()
[x - 1, 1; x^2 + x + 1, 1]
>>> pari.factor('x^3 - 1')
[x - 1, 1; x^2 + x + 1, 1]
Arithmetic operations cause all arguments to be converted to PARI:
>>> type(pari(1) + 1)
<... 'cypari2.gen.Gen'>
>>> type(1 + pari(1))
<... 'cypari2.gen.Gen'>
Guide to real precision in the PARI interface¶
In the PARI interface, “real precision” refers to the precision of real numbers, so it is the floating-point precision. This is a non-trivial issue, since there are various interfaces for different things.
Internal representation of floating-point numbers in PARI¶
Real numbers in PARI have a precision associated to them, which is
always a multiple of the CPU wordsize. So, it is a multiple of 32
of 64 bits. When converting a float
from Python to PARI, the
float
has 53 bits of precision which is rounded up to 64 bits
in PARI:
>>> x = 1.0
>>> pari(x)
1.00000000000000
>>> pari(x).bitprecision()
64
It is possible to change the precision of a PARI object with the
Gen.bitprecision()
method:
>>> p = pari(1.0)
>>> p.bitprecision()
64
>>> p = p.bitprecision(100)
>>> p.bitprecision() # Rounded up to a multiple of the wordsize
128
Beware that these extra bits are just bogus. For example, this will not
magically give a more precise approximation of math.pi
:
>>> import math
>>> p = pari(math.pi)
>>> pari("Pi") - p
1.225148... E-16
>>> p = p.bitprecision(1000)
>>> pari("Pi") - p
1.225148... E-16
Another way to create numbers with many bits is to use a string with many digits:
>>> p = pari("3.1415926535897932384626433832795028842")
>>> p.bitprecision()
128
Output precision for printing¶
Even though PARI reals have a precision, not all significant bits are
printed by default. The maximum number of digits when printing a PARI
real can be set using the methods
Pari.set_real_precision_bits()
or
Pari.set_real_precision()
.
Note that this will also change the input precision for strings,
see Input precision for function calls.
We create a very precise approximation of pi and see how it is printed in PARI:
>>> pi = pari.pi(precision=1024)
The default precision is 15 digits:
>>> pi
3.14159265358979
With a different precision, we see more digits. Note that this does not
affect the object pi
at all, it only affects how it is printed:
>>> _ = pari.set_real_precision(50)
>>> pi
3.1415926535897932384626433832795028841971693993751
Back to the default:
>>> _ = pari.set_real_precision(15)
>>> pi
3.14159265358979
Input precision for function calls¶
When we talk about precision for PARI functions, we need to distinguish three kinds of calls:
Using the string interface, for example
pari("sin(1)")
.Using the library interface with exact inputs, for example
pari.sin(1)
.Using the library interface with inexact inputs, for example
pari.sin(1.0)
.
In the first case, the relevant precision is the one set by the methods
Pari.set_real_precision_bits()
or
Pari.set_real_precision()
:
>>> pari.set_real_precision_bits(150)
>>> pari("sin(1)")
0.841470984807896506652502321630298999622563061
>>> pari.set_real_precision_bits(53)
>>> pari("sin(1)")
0.841470984807897
In the second case, the precision can be given as the argument
precision
in the function call, with a default of 53 bits.
The real precision set by
Pari.set_real_precision_bits()
or
Pari.set_real_precision()
does not affect the call
(but it still affects printing).
As explained before, the precision increases to a multiple of the wordsize (and you should not assume that the extra bits are meaningful):
>>> a = pari.sin(1, precision=180); a
0.841470984807897
>>> a.bitprecision()
192
>>> b = pari.sin(1, precision=40); b
0.841470984807897
>>> b.bitprecision()
64
>>> c = pari.sin(1); c
0.841470984807897
>>> c.bitprecision()
64
>>> pari.set_real_precision_bits(90)
>>> print(a); print(b); print(c)
0.841470984807896506652502322
0.8414709848078965067
0.8414709848078965067
In the third case, the precision is determined only by the inexact
inputs and the precision
argument is ignored:
>>> pari.sin(1.0, precision=180).bitprecision()
64
>>> pari.sin(1.0, precision=40).bitprecision()
64
>>> pari.sin("1.0000000000000000000000000000000000000").bitprecision()
128
Tests:
Check that the documentation is generated correctly:
>>> from inspect import getdoc
>>> getdoc(pari.Pi)
'The constant :math:`\\pi` ...'
Check that output from PARI’s print command is actually seen by Python (Sage ticket #9636):
>>> pari('print("test")')
test
Verify that nfroots()
(which has an unusual signature with a
non-default argument following a default argument) works:
>>> pari.nfroots(x='x^4 - 1')
[-1, 1]
>>> pari.nfroots(pari.nfinit('t^2 + 1'), "x^4 - 1")
[-1, 1, Mod(-t, t^2 + 1), Mod(t, t^2 + 1)]
Reset default precision for the following tests:
>>> pari.set_real_precision_bits(53)
Test that interrupts work properly:
>>> pari.allocatemem(8000000, 2**29)
PARI stack size set to 8000000 bytes, maximum size set to ...
>>> from cysignals.alarm import alarm, AlarmInterrupt
>>> for i in range(1, 11):
... try:
... alarm(i/11.0)
... pari.binomial(2**100, 2**22)
... except AlarmInterrupt:
... pass
Test that changing the stack size using default
works properly:
>>> pari.default("parisizemax", 2**23)
>>> pari = cypari2.Pari() # clear stack
>>> a = pari(1)
>>> pari.default("parisizemax", 2**29)
>>> a + a
2
>>> pari.default("parisizemax")
536870912
- class cypari2.pari_instance.Pari¶
- List(x)¶
Create an empty list or convert x to a list.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.List(range(5)) List([0, 1, 2, 3, 4]) >>> L = pari.List() >>> L List([]) >>> L.listput(42, 1) 42 >>> L List([42]) >>> L.listinsert(24, 1) 24 >>> L List([24, 42])
- allocatemem(s, sizemax, *, silent)¶
Change the PARI stack space to the given size
s
(or double the current size ifs
is 0) and change the maximum stack size tosizemax
.PARI tries to use only its current stack (the size which is set by
s
), but it will increase its stack if needed up to the maximum size which is set bysizemax
.The PARI stack is never automatically shrunk. You can use the command
pari.allocatemem(10^6)
to reset the size to 10^6, which is the default size at startup. Note that the results of computations using cypari are copied to the Python heap, so they take up no space in the PARI stack. The PARI stack is cleared after every computation.It does no real harm to set this to a small value as the PARI stack will be automatically enlarged when we run out of memory.
INPUT:
s
- an integer (default: 0). A non-zero argument is the size in bytes of the new PARI stack. If s is zero, double the current stack size.sizemax
- an integer (default: 0). A non-zero argument is the maximum size in bytes of the PARI stack. Ifsizemax
is 0, the maximum of the current maximum ands
is taken.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.allocatemem(10**7, 10**7) PARI stack size set to 10000000 bytes, maximum size set to 100... >>> pari.allocatemem() # Double the current size PARI stack size set to 20000000 bytes, maximum size set to 200... >>> pari.stacksize() 20000000 >>> pari.allocatemem(10**6) PARI stack size set to 1000000 bytes, maximum size set to 200...
The following computation will automatically increase the PARI stack size:
>>> a = pari('2^100000000')
a
is now a Python variable on the Python heap and does not take up any space on the PARI stack. The PARI stack is still large because of the computation ofa
:>>> pari.stacksize() > 10**6 True
Setting a small maximum size makes this fail:
>>> pari.allocatemem(10**6, 2**22) PARI stack size set to 1000000 bytes, maximum size set to 4194304 >>> a = pari('2^100000000') Traceback (most recent call last): ... PariError: _^s: the PARI stack overflows (current size: 1000000; maximum size: 4194304) You can use pari.allocatemem() to change the stack size and try again
Tests:
Do the same without using the string interface and starting from a very small stack size:
>>> pari.allocatemem(1, 2**26) PARI stack size set to 1024 bytes, maximum size set to 67108864 >>> a = pari(2)**100000000 >>> pari.stacksize() > 10**6 True
We do not allow
sizemax
less thans
:>>> pari.allocatemem(10**7, 10**6) Traceback (most recent call last): ... ValueError: the maximum size (10000000) should be at least the stack size (1000000)
- complex(re, im)¶
Create a new complex number, initialized from re and im.
- debugstack()¶
Print the internal PARI variables
top
(top of stack),avma
(available memory address, think of this as the stack pointer),bot
(bottom of stack).
- euler(precision)¶
Euler’s constant \(\gamma = 0.57721...\). Note that
Euler
is one of the few reserved names which cannot be used for user variables.
- factorial_int(n)¶
Return the factorial of the integer n as a PARI gen. Give result as an integer.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.factorial_int(0) 1 >>> pari.factorial_int(1) 1 >>> pari.factorial_int(5) 120 >>> pari.factorial_int(25) 15511210043330985984000000
- genus2red(P, p)¶
Let P be a polynomial with integer coefficients. Determines the reduction of the (proper, smooth) genus 2 curve C/QQ, defined by the hyperelliptic equation y^2 = P. The special syntax
genus2red([P,Q])
is also allowed, where the polynomials P and Q have integer coefficients, to represent the model y^2 + Q(x)y = P(x).If the second argument p is specified, it must be a prime. Then only the local information at p is computed and returned.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> x = pari('x') >>> pari.genus2red([-5*x**5, x**3 - 2*x**2 - 2*x + 1]) [1416875, [2, -1; 5, 4; 2267, 1], ..., [[2, [2, [Mod(1, 2)]], []], [5, [1, []], ["[V] page 156", [3]]], [2267, [2, [Mod(432, 2267)]], ["[I{1-0-0}] page 170", []]]]] >>> pari.genus2red([-5*x**5, x**3 - 2*x**2 - 2*x + 1],2267) [2267, Mat([2267, 1]), ..., [2267, [2, [Mod(432, 2267)]], ["[I{1-0-0}] page 170", []]]]
- get_debug_level()¶
Set the debug PARI C library variable.
- get_real_precision()¶
Returns the current PARI default real precision.
This is used both for creation of new objects from strings and for printing. It is the number of digits IN DECIMAL in which real numbers are printed. It also determines the precision of objects created by parsing strings (e.g. pari(‘1.2’)), which is not the normal way of creating new PARI objects in CyPari2. It has no effect on the precision of computations within the pari library.
See also
get_real_precision_bits()
to get the precision in bits.Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.get_real_precision() 15
- get_real_precision_bits()¶
Return the current PARI default real precision in bits.
This is used both for creation of new objects from strings and for printing. It determines the number of digits in which real numbers numbers are printed. It also determines the precision of objects created by parsing strings (e.g. pari(‘1.2’)), which is not the normal way of creating new PARI objects using cypari. It has no effect on the precision of computations within the PARI library.
See also
get_real_precision()
to get the precision in decimal digits.Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.get_real_precision_bits() 53
- init_primes(M)¶
Recompute the primes table including at least all primes up to M (but possibly more).
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.init_primes(200000)
We make sure that ticket Sage ticket #11741 has been fixed:
>>> pari.init_primes(2**30) Traceback (most recent call last): ... ValueError: Cannot compute primes beyond 436273290
- matrix(m, n, entries)¶
matrix(long m, long n, entries=None): Create and return the m x n PARI matrix with given list of entries.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.matrix(3, 3, range(9)) [0, 1, 2; 3, 4, 5; 6, 7, 8]
- new_with_bits_prec(s, precision)¶
pari.new_with_bits_prec(self, s, precision) creates s as a PARI Gen with (at most) precision bits of precision.
- one()¶
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.one() 1
- static pari_version()¶
Return a string describing the version of PARI/GP.
>>> from cypari2 import Pari >>> Pari.pari_version() 'GP/PARI CALCULATOR Version ...'
- pi(precision)¶
The constant \(\pi\) (\(3.14159...\)). Note that
Pi
is one of the few reserved names which cannot be used for user variables.
- polchebyshev(n, v)¶
Chebyshev polynomial of the first kind of degree n, in the variable v.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.polchebyshev(7) 64*x^7 - 112*x^5 + 56*x^3 - 7*x >>> pari.polchebyshev(7, 'z') 64*z^7 - 112*z^5 + 56*z^3 - 7*z >>> pari.polchebyshev(0) 1
- polsubcyclo(n, d, v=x): return the pari list of polynomial(s)¶
defining the sub-abelian extensions of degree d of the cyclotomic field QQ(zeta_n), where d divides phi(n).
Examples:
>>> import cypari2 >>> pari = cypari2.Pari()
>>> pari.polsubcyclo(8, 4) [x^4 + 1] >>> pari.polsubcyclo(8, 2, 'z') [z^2 + 2, z^2 - 2, z^2 + 1] >>> pari.polsubcyclo(8, 1) [x - 1] >>> pari.polsubcyclo(8, 3) []
- primes(n, end)¶
Return a pari vector containing the first n primes, the primes in the interval [n, end], or the primes up to end.
INPUT:
Either
n
– integer
or
n
– list or tuple [a, b] defining an interval of primes
or
n, end
– start and end point of an interval of primes
or
end
– end point for the list of primes
OUTPUT: a PARI list of prime numbers
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.primes(3) [2, 3, 5] >>> pari.primes(10) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] >>> pari.primes(20) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] >>> len(pari.primes(1000)) 1000 >>> pari.primes(11,29) [11, 13, 17, 19, 23, 29] >>> pari.primes((11,29)) [11, 13, 17, 19, 23, 29] >>> pari.primes(end=29) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] >>> pari.primes(10**30, 10**30 + 100) [1000000000000000000000000000057, 1000000000000000000000000000099]
Tests:
>>> pari.primes(0) [] >>> pari.primes(-1) [] >>> pari.primes(end=1) [] >>> pari.primes(end=-1) [] >>> pari.primes(3,2) []
- set_debug_level(level)¶
Set the debug PARI C library variable.
- set_real_precision(n)¶
Sets the PARI default real precision in decimal digits.
This is used both for creation of new objects from strings and for printing. It is the number of digits IN DECIMAL in which real numbers are printed. It also determines the precision of objects created by parsing strings (e.g. pari(‘1.2’)), which is not the normal way of creating new PARI objects in CyPari2. It has no effect on the precision of computations within the pari library.
Returns the previous PARI real precision.
See also
set_real_precision_bits()
to set the precision in bits.Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.set_real_precision(60) 15 >>> pari('1.2') 1.20000000000000000000000000000000000000000000000000000000000 >>> pari.set_real_precision(15) 60
- set_real_precision_bits(n)¶
Sets the PARI default real precision in bits.
This is used both for creation of new objects from strings and for printing. It determines the number of digits in which real numbers numbers are printed. It also determines the precision of objects created by parsing strings (e.g. pari(‘1.2’)), which is not the normal way of creating new PARI objects using cypari. It has no effect on the precision of computations within the PARI library.
See also
set_real_precision()
to set the precision in decimal digits.Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.set_real_precision_bits(200) >>> pari('1.2') 1.20000000000000000000000000000000000000000000000000000000000 >>> pari.set_real_precision_bits(53)
- setrand(seed)¶
Sets PARI’s current random number seed.
INPUT:
seed
– either a strictly positive integer or a GEN of typet_VECSMALL
as output bygetrand()
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.setrand(50) >>> a = pari.getrand() >>> pari.setrand(a) >>> a == pari.getrand() True
Tests:
Check that invalid inputs are handled properly:
>>> pari.setrand("foobar") Traceback (most recent call last): ... PariError: incorrect type in setrand (t_POL)
- stacksize()¶
Return the current size of the PARI stack, which is 10^6 by default. However, the stack size is automatically increased when needed up to the given maximum stack size.
See also
stacksizemax()
to get the maximum stack sizeallocatemem()
to change the current or maximum stack size
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.stacksize() 8000000 >>> pari.allocatemem(2**18, silent=True) >>> pari.stacksize() 262144
- stacksizemax()¶
Return the maximum size of the PARI stack, which is determined at startup in terms of available memory. Usually, the PARI stack size is (much) smaller than this maximum but the stack will be increased up to this maximum if needed.
See also
stacksize()
to get the current stack sizeallocatemem()
to change the current or maximum stack size
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.allocatemem(2**18, 2**26, silent=True) >>> pari.stacksizemax() 67108864
- vector(n, entries)¶
vector(long n, entries=None): Create and return the length n PARI vector with given list of entries.
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.vector(5, [1, 2, 5, 4, 3]) [1, 2, 5, 4, 3] >>> pari.vector(2, ['x', 1]) [x, 1] >>> pari.vector(2, ['x', 1, 5]) Traceback (most recent call last): ... IndexError: length of entries (=3) must equal n (=2)
- version()¶
Return the PARI version as tuple with 3 or 4 components: (major, minor, patch) or (major, minor, patch, VCSversion).
Examples:
>>> from cypari2 import Pari >>> Pari().version() >= (2, 9, 0) True
- zero()¶
Examples:
>>> import cypari2 >>> pari = cypari2.Pari() >>> pari.zero() 0
- class cypari2.pari_instance.Pari_auto¶
Part of the
Pari
class containing auto-generated functions.You must never use this class directly (in fact, Python may crash if you do), use the derived class
Pari
instead.- Catalan(precision)¶
Catalan’s constant \(G = \sum_{n >= 0}((-1)^n)/((2n+1)^2) = 0.91596...\). Note that
Catalan
is one of the few reserved names which cannot be used for user variables.
- Col(x, 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(x, 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.
- Euler(precision)¶
Euler’s constant \(\gamma = 0.57721...\). Note that
Euler
is one of the few reserved names which cannot be used for user variables.
- I()¶
The complex number \(\sqrt{-1}\).
- List(x)¶
Transforms a (row or column) vector \(x\) into a list, whose components are the entries of \(x\). Similarly for a list, but rather useless in this case. For other types, creates a list with the single element \(x\).
- Map(x)¶
A “Map” is an associative array, or dictionary: a data type composed of a collection of (key, value) pairs, such that each key appears just once in the collection. This function converts the matrix \([a_1,b_1;a_2,b_2;...;a_n,b_n]\) to the map \(a_i:---> b_i\).
? M = Map(factor(13!)); ? mapget(M,3) %2 = 5
If the argument \(x\) is omitted, creates an empty map, which may be filled later via
mapput
.
- Mat(x)¶
Transforms the object \(x\) into a matrix. If \(x\) is already a matrix, a copy of \(x\) is created. If \(x\) is a row (resp. column) vector, this creates a 1-row (resp. 1-column) matrix, unless all elements are column (resp. row) vectors of the same length, in which case the vectors are concatenated sideways and the 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(a, 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`.
- Pi(precision)¶
The constant \(\pi\) (\(3.14159...\)). Note that
Pi
is one of the few reserved names which cannot be used for user variables.
- Pol(t, 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(t, 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(a, 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(s, 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(x)¶
Converts \(x\) into a set, i.e. into a row vector, with strictly increasing entries with respect to the (somewhat arbitrary) universal comparison function
cmp
. Standard container 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(x)¶
Deprecated alias for strchr.
- Vec(x, 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(x, 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(x, 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(x, 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(x, 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(x, 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.
- addhelp(sym, str)¶
Changes the help message for the symbol
sym
. The string str is expanded on the spot and stored as the online help forsym
. It is recommended to document global variables and user functions in this way, althoughgp
will not protest if you don’t.You can attach a help text to an alias, but it will never be shown: aliases are expanded by the
?
help operator and we get the help of the symbol the alias points to. Nothing prevents you from modifying the help of built-in PARI functions. But if you do, we would like to hear why you needed it!Without
addhelp
, the standard help for user functions consists of its name and definition.gp> f(x) = x^2; gp> ?f f = (x)->x^2
Once addhelp is applied to \(f\), the function code is no longer included. It can still be consulted by typing the function name:
gp> addhelp(f, "Square") gp> ?f Square gp> f %2 = (x)->x^2
- addprimes(x)¶
Adds the integers contained in the vector \(x\) (or the single integer \(x\)) to a special table of “user-defined primes”, and returns that table. Whenever
factor
is subsequently called, it will trial divide by the elements in this table. If \(x\) is empty or omitted, just returns the current list of extra primes.? 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(x, 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(z, precision)¶
Airy \([Ai,Bi]\) functions of argument \(z\).
? [A,B] = airy(1); ? A %2 = 0.13529241631288141552414742351546630617 ? B %3 = 1.2074235949528712594363788170282869954
- algadd(al, x, y)¶
Given two elements \(x\) and \(y\) in al, computes their sum \(x+y\) in the algebra al.
? A = alginit(nfinit(y),[-1,1]); ? algadd(A,[1,0]~,[1,2]~) %2 = [2, 2]~
Also accepts matrices with coefficients in al.
- algalgtobasis(al, x)¶
Given an element x in the central simple algebra al output by
alginit
, transforms it to a column vector on the integral basis of al. This is the inverse function 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(al)¶
Given a cyclic algebra \(al = (L/K,\sigma,b)\) output by
alginit
, returns the automorphism \(\sigma\).? nf = nfinit(y); ? p = idealprimedec(nf,7)[1]; ? p2 = idealprimedec(nf,11)[1]; ? A = alginit(nf,[3,[[p,p2],[1/3,2/3]],[0]]); ? algaut(A) %5 = -1/3*x^2 + 1/3*x + 26/3
- algb(al)¶
Given a cyclic algebra \(al = (L/K,\sigma,b)\) output by
alginit
, returns the element \(b\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(al)¶
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(al, x)¶
Given an element x in the central simple algebra al output by
alginit
, transforms it to its algebraic representation in al. This is the inverse function 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(al)¶
If al is a table algebra output by
algtableinit
, returns a basis of the center of the algebra al over its prime field (\(\mathbb{Q}\) or \(\mathbb{F}_p\)). If al is a central simple algebra output 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(al, 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(al)¶
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(al, 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(al)¶
Given a central simple algebra al output by
alginit
, returns the degree of al.? nf = nfinit(y^3-y+1); ? A = alginit(nf, [-1,-1]); ? algdegree(A) %3 = 2
- algdep(z, 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(al, 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(al)¶
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(al, 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(al, x, y)¶
Given two elements \(x\) and \(y\) in al, returns \(xy^{-1}\). Also accepts matrices with coefficients in al.
- alggroup(gal, 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(gal, 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(al, pl)¶
Given a central simple algebra al output by
alginit
and a prime ideal or an integer between \(1\) and \(r_1+r_2\), returns 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(al)¶
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(al)¶
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(al, 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(B, 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(al, x)¶
Given an element \(x\) in al, computes its inverse \(x^{-1}\) in the algebra al. Assumes that \(x\) is invertible.
? A = alginit(nfinit(y), [-1,-1]); ? alginv(A,[1,1,0,0]~) %2 = [1/2, 1/2, 0, 0]~
Also accepts matrices with coefficients in al.
- alginvbasis(al)¶
Given an central simple algebra al output by
alginit
, returns a \(\mathbb{Z}\)-basis of the natural order in al with respect to the order \(O_0\) stored in al.A = alginit(nfinit(y), [-1,-1]); ? alginvbasis(A) %2 = [1 0 0 -1] [0 1 0 -1] [0 0 1 -1] [0 0 0 2]
- algisassociative(mt, p)¶
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)¶
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(al, 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(al, 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(al, 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(al, 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)¶
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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(al, 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(mt, 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(al, 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(al)¶
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(al, x)¶
Given an element \(x\) in al, computes its opposite \(-x\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algneg(A,[1,1,0,0]~) %2 = [-1, -1, 0, 0]~
Also accepts matrices with coefficients in al.
- algnorm(al, x, 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(al, 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(al, x, n)¶
Given an element \(x\) in al and an integer \(n\), computes the power \(x^n\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algpow(A,[1,1,0,0]~,7) %2 = [8, -8, 0, 0]~
Also accepts a square matrix with coefficients in al.
- algprimesubalg(al)¶
al being the output of
algtableinit
representing a semisimple algebra of positive characteristic, returns a basis of the prime subalgebra of al. The prime subalgebra of al is the subalgebra fixed by the Frobenius automorphism of the center of al. It is abstractly isomorphic to a product of copies of \(\mathbb{F}_p\).? mt = [matid(3), [0,0,0; 1,1,0; 0,0,0], [0,0,1; 0,0,0; 1,0,1]]; ? A = algtableinit(mt,2); ? algprimesubalg(A) %3 = [1 0] [0 1] [0 0]
- algquotient(al, I, 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)¶
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(al)¶
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(al, b)¶
Given an algebra al and an integer b, returns a random element in al with coefficients in \([-b,b]\).
- algrelmultable(al)¶
Given a central simple algebra al output by
alginit
defined by a multiplication table over its center (a number field), returns this multiplication table.? nf = nfinit(y^3-5); a = y; b = y^2; ? {m_i = [0,a,0,0; 1,0,0,0; 0,0,0,a; 0,0,1,0];} ? {m_j = [0, 0,b, 0; 0, 0,0,-b; 1, 0,0, 0; 0,-1,0, 0];} ? {m_k = [0, 0,0,-a*b; 0, 0,b, 0; 0,-a,0, 0; 1, 0,0, 0];} ? mt = [matid(4), m_i, m_j, m_k]; ? A = alginit(nf,mt,'x); ? M = algrelmultable(A); ? M[2] == m_i %8 = 1 ? M[3] == m_j %9 = 1 ? M[4] == m_k %10 = 1
- algsimpledec(al, 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(al, 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(al)¶
Given a central simple algebra al output by
alginit
defined by a multiplication table over its center \(K\) (a number field), returns data stored to compute a splitting of al over an extension. This data is 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(al)¶
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(al, x)¶
Given an element \(x\) in al, computes its square \(x^2\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algsqr(A,[1,0,2,0]~) %2 = [-3, 0, 4, 0]~
Also accepts a square matrix with coefficients in al.
- algsub(al, x, y)¶
Given two elements \(x\) and \(y\) in al, computes their difference \(x-y\) in the algebra al.
? A = alginit(nfinit(y), [-1,-1]); ? algsub(A,[1,1,0,0]~,[1,0,1,0]~) %2 = [0, 1, -1, 0]~
Also accepts matrices with coefficients in al.
- algsubalg(al, B)¶
al being a table algebra output by
algtableinit
and B being a basis of a subalgebra of al represented by a matrix, 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(mt, 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(al1, 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(al, 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(al, 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(al)¶
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(f, 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(x, precision)¶
Argument of the complex number \(x\), such that \(-\pi < \arg (x) <= \pi\).
- arity(C)¶
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(x, 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(x, 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(expr, 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(expr, 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(x, 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(x, 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.
- bernfrac(n)¶
Bernoulli number \(B_n\), where \(B_0 = 1\), \(B_1 = -1/2\), \(B_2 = 1/6\),…, expressed as a rational number. The argument \(n\) should be a nonnegative integer. The function
bervec
creates a cache of successive Bernoulli numbers which greatly speeds up later calls tobernfrac
:? bernfrac(20000); time = 107 ms. ? bernvec(10000); \\ cache B_0, B_2, ..., B_20000 time = 35,957 ms. ? bernfrac(20000); \\ now instantaneous ?
- bernpol(n, v)¶
Bernoulli polynomial \(B_n\) in variable \(v\).
? bernpol(1) %1 = x - 1/2 ? bernpol(3) %2 = x^3 - 3/2*x^2 + 1/2*x
- bernreal(n, precision)¶
Bernoulli number \(B_n\), as
bernfrac
, but \(B_n\) is returned as a real number (with the current precision). The argument \(n\) should be a nonnegative integer. The function slows down as the precision increases:? \p1000 ? bernreal(200000); time = 5 ms. ? \p10000 ? bernreal(200000); time = 18 ms. ? \p100000 ? bernreal(200000); time = 84 ms.
- bernvec(n)¶
Returns a vector containing, as rational numbers, the Bernoulli numbers \(B_0\), \(B_2\),…, \(B_{2n}\):
? bernvec(5) \\ B_0, B_2..., B_10 %1 = [1, 1/6, -1/30, 1/42, -1/30, 5/66] ? bernfrac(10) %2 = 5/66
This routine uses a lot of memory but is much faster than repeated calls to
bernfrac
:? forstep(n = 2, 10000, 2, bernfrac(n)) time = 18,245 ms. ? bernvec(5000); time = 1,338 ms.
The computed Bernoulli numbers are stored in an incremental cache which makes later calls to
bernfrac
andbernreal
instantaneous in the cache range: re-running the same previousbernfrac
s after thebernvec
call gives:? forstep(n = 2, 10000, 2, bernfrac(n)) time = 1 ms.
The time and space complexity of this function are \(~{O}(n^2)\); in the feasible range \(n <= 10^5\) (requires about two hours), the practical time complexity is closer to \(~{O}(n^{\log_2 6})\).
- besselh1(nu, x, precision)¶
\(H^1\)-Bessel function of index nu and argument \(x\).
- besselh2(nu, x, precision)¶
\(H^2\)-Bessel function of index nu and argument \(x\).
- besseli(nu, 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(nu, 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(n, 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(nu, x, precision)¶
\(K\)-Bessel function of index nu and argument \(x\).
- besseln(nu, x, precision)¶
Deprecated alias for
bessely
.
- bessely(nu, x, precision)¶
\(Y\)-Bessel function of index nu and argument \(x\).
- bestappr(x, 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(x, 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(V, 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(x, y)¶
Deprecated alias for
gcdext
- bezoutres(A, B, v)¶
Deprecated alias for
polresultantext
- bigomega(x)¶
Number of prime divisors of the integer \(\|x\|\) counted with multiplicity:
? factor(392) %1 = [2 3] [7 2] ? bigomega(392) %2 = 5; \\ = 3+2 ? omega(392) %3 = 2; \\ without multiplicity
- binary(x)¶
Outputs the vector of the binary digits of \(\|x\|\). Here \(x\) can be an integer, a real number (in which case the result has two components, one for the integer part, one for the fractional part) or a vector/matrix.
? 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(x, 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(x, y)¶
Bitwise
and
of two integers \(x\) and \(y\), that is the integer\[\sum_i (x_i and y_i) 2^i\]Negative numbers behave \(2\)-adically, i.e. the result is the \(2\)-adic limit of
bitand
\((x_n,y_n)\), where \(x_n\) and \(y_n\) are 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(x, 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(x, y)¶
Bitwise negated imply of two integers \(x\) and \(y\) (or
not
\((x ==> y)\)), that is the integer\[\sum (x_i and not (y_i)) 2^i\]See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bitor(x, y)¶
bitwise (inclusive)
or
of two integers \(x\) and \(y\), that is the integer\[\sum (x_i or y_i) 2^i\]See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bitprecision(x, 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(x, n)¶
Outputs the \(n-th\) bit of \(x\) starting from the right (i.e. the coefficient of \(2^n\) in the binary expansion of \(x\)). The result is 0 or 1. 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(x, y)¶
Bitwise (exclusive)
or
of two integers \(x\) and \(y\), that is the integer\[\sum (x_i xor y_i) 2^i\]See
bitand
(in the PARI manual) for the behavior for negative arguments.
- bnfcertify(bnf, flag)¶
\(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(nf, m)¶
If \(m\) is a module as output in the first component of an extension given by
bnrdisclist
, outputs the true module.? K = bnfinit(x^2+23); L = bnrdisclist(K, 10); s = L[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(P, 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(bnf, x)¶
Computes a complete system of solutions (modulo units of positive norm) of the absolute norm equation \(\mathrm{Norm} (a) = x\), where \(a\) is an integer in \(bnf\). If \(bnf\) has not been certified, the correctness of the result depends on the validity of GRH.
See also
bnfisnorm
.
- bnfisnorm(bnf, x, flag)¶
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(bnf, 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(bnf, sfu, x)¶
This function is obsolete, use
bnfisunit
.
- bnfisunit(bnf, 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(bnf, 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(nf, 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(nf, 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)¶
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)¶
\(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(bnf, 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(bnf, 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(bnr, 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(bnr, 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(bnr, 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(A, 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(bnf, 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(A, 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(bnr, chi)¶
This function is obsolete, use bnrconductor.
- bnrdisc(A, 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(bnf, 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(bnr, mat, H)¶
Apply the automorphism given by its matrix mat to the congruence subgroup \(H\) given as a HNF matrix. The matrix mat can be computed with
bnrgaloismatrix
.
- bnrgaloismatrix(bnr, aut)¶
Return the matrix of the action of the automorphism aut of the base field
bnf.nf
on the generators of the ray class 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(bnf, 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(A, 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(bnr, 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(bnr, 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(A, 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(bnr, 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(bnr, 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(f, 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(x)¶
Ceiling of \(x\). When \(x\) is in \(\mathbb{R}\), the result is the smallest integer greater than or equal to \(x\). Applied to a rational function, \(ceil (x)\) returns the Euclidean quotient of the numerator by the denominator.
- centerlift(x, v)¶
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(x)¶
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(cyc, 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(cyc, 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(G, 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(cyc, 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(cyc, 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(cyc, 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(cyc, 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(A, 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(cyc, 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(x, 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(x, y)¶
Gives the result of a comparison between arbitrary objects \(x\) and \(y\) (as \(-1\), \(0\) or \(1\)). The underlying order relation is transitive, the function returns \(0\) if and only if \(x === y\). 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(x, n)¶
Extracts the \(n-th\)-component of \(x\). This is to be understood as follows: every PARI type has one or two initial code words. The components are counted, starting at 1, after these code words. In particular if \(x\) is a vector, this is indeed the \(n-th\)-component of \(x\), if \(x\) is a matrix, the \(n-th\) column, if \(x\) is a polynomial, the \(n-th\) coefficient (i.e. of degree \(n-1\)), and for power series, the \(n-th\) significant coefficient.
For polynomials and power series, one should rather use
polcoeff
, and for vectors and matrices, the[]
operator. Namely, if \(x\) is a vector, 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(x, 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(x)¶
Conjugate of \(x\). The meaning of this is clear, except that for real quadratic numbers, it means conjugation in the real quadratic field. This function has no effect on integers, reals, intmods, fractions or \(p\)-adics. The only forbidden type is polmod (see
conjvec
for this).
- conjvec(z, precision)¶
Conjugate vector representation of \(z\). If \(z\) is a polmod, equal to
Mod
\((a,T)\), this gives a vector of length \(degree(T)\) containing:the complex embeddings of \(z\) if \(T\) has rational coefficients, i.e. the \(a(r[i])\) where \(r = polroots (T)\);
the conjugates of \(z\) if \(T\) has some intmod coefficients;
if \(z\) is a finite field element, the result is the vector of conjugates \([z,z^p,z^{p^2},...,z^{p^{n-1}}]\) where \(n = degree(T)\).
If \(z\) is an integer or a rational number, the result is \(z\). If \(z\) is a (row or column) vector, the result is a matrix whose columns are the conjugate vectors of the individual elements of \(z\).
- content(x, 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(x, 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(CF, 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(M, 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(x, 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(n, 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(n, 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(x, 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(x, precision)¶
Hyperbolic cosine of \(x\).
- cotan(x, precision)¶
Cotangent of \(x\).
- cotanh(x, precision)¶
Hyperbolic cotangent of \(x\).
- default(key, val)¶
Returns the default corresponding to keyword key. If val is present, sets the default to val first (which is subject to string expansion first). Typing
default()
(or\d
) yields the complete default list as well as their current values. Seedefaults
(in the PARI manual) for an introduction to GP defaults,gp_defaults
(in the PARI manual) for a list of available defaults, andmeta
(in the PARI manual) for some shortcut alternatives. Note that the shortcuts are meant for interactive use and usually display more information thandefault
.
- denominator(f, 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(x, v)¶
Derivative of \(x\) with respect to the main variable if \(v\) is omitted, and with respect to \(v\) otherwise. The derivative of a scalar type is zero, and the derivative of a vector or matrix is done componentwise. One can use \(x'\) as a shortcut if the derivative is with respect to the main variable of \(x\); 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(x, 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(x, 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(x, 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(x, 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(x, y)¶
\(x\) and \(y\) being vectors of perhaps different lengths but with \(y[1] != 0\) considered as Dirichlet series, computes the quotient of \(x\) by \(y\), again as a vector.
- dirmul(x, y)¶
\(x\) and \(y\) being vectors of perhaps different lengths representing the Dirichlet series \(\sum_n x_n n^{-s}\) and \(\sum_n y_n n^{-s}\), computes the product of \(x\) by \(y\), again as a vector.
? dirmul(vector(10,n,1), vector(10,n,moebius(n))) %1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
The product length is the minimum of \(\# x* v(y)\) and \(\# y* v(x)\), where \(v(x)\) is the index of the first nonzero coefficient.
? dirmul([0,1], [0,1]); %2 = [0, 0, 0, 1]
- dirpowers(n, x, precision)¶
For nonnegative \(n\) and complex number \(x\), return the vector with \(n\) components \([1^x,2^x,...,n^x]\).
? dirpowers(5, 2) %1 = [1, 4, 9, 16, 25] ? dirpowers(5, 1/2) %2 = [1, 1.414..., 1.732..., 2.000..., 2.236...]
When \(n <= 0\), the function returns the empty vector
[]
.
- dirpowerssum(n, 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(nf, b)¶
Gives as a vector the first \(b\) coefficients of the Dedekind zeta function of the number field \(nf\) considered as a Dirichlet series.
- divisors(x, 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(N, 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(x, 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(x, 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(k, 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(k, 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(E, 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(E, z1, z2)¶
Sum of the points \(z1\) and \(z2\) on the elliptic curve corresponding to \(E\).
- ellak(E, n)¶
Computes the coefficient \(a_n\) of the \(L\)-function of the elliptic curve \(E/\mathbb{Q}\), i.e. coefficients of a newform of weight 2 by the modularity theorem (Taniyama-Shimura-Weil conjecture). \(E\) must be an
ell
structure over \(\mathbb{Q}\) as output 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(E, 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(E, 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(E, 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(E, z1, z2, precision)¶
Deprecated alias for
ellheight(E,P,Q)
.
- ellbsd(E, 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(E, 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(E, v)¶
Changes the data for the elliptic curve \(E\) by changing the coordinates using the vector
v = [u,r,s,t]
, i.e. if \(x'\) and \(y'\) are the new coordinates, then \(x = u^2x'+r\), \(y = u^3y'+su^2x'+t\). \(E\) must be 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(x, v)¶
Changes the coordinates of the point or vector of points \(x\) using the vector
v = [u,r,s,t]
, i.e. if \(x'\) and \(y'\) are the new coordinates, then \(x = u^2x'+r\), \(y = u^3y'+su^2x'+t\) (see 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(x, 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(name)¶
Converts an elliptic curve name, as found in the
elldata
database, from a string to a triplet \([conductor, isogeny class, index]\). It will also convert a triplet back to a curve name. Examples:? ellconvertname("123b1") %1 = [123, 1, 1] ? ellconvertname(%) %2 = "123b1"
- elldivpol(E, n, v)¶
\(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(w, 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(w, 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(E, 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(E, 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(E, 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(E, 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(E, 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(P)¶
Given a genus \(1\) plane curve, defined by the affine equation \(f(x,y) = 0\), return the coefficients \([a_1,a_2,a_3,a_4,a_6]\) of a Weierstrass equation for its Jacobian. This allows to recover a Weierstrass model for an elliptic curve given by a general plane cubic or by a binary quartic or biquadratic model. The function implements the \(f :---> f^*\) formulae of Artin, Tate and Villegas (Advances in Math. 198 (2005), pp. 366–382).
In the example below, the function is used to convert between twisted 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(j)¶
Returns the coefficients \([a_1,a_2,a_3,a_4,a_6]\) of a fixed elliptic curve with \(j\)-invariant \(j\).
- ellgenerators(E)¶
If \(E\) is an elliptic curve over the rationals, return a \(\mathbb{Z}\)-basis of the free part of the Mordell-Weil group 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(E)¶
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(E, 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(E)¶
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(E, 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(E, 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(E)¶
Look up the elliptic curve \(E\), defined by an arbitrary model over \(\mathbb{Q}\), in the
elldata
database. Return[[N, M, G], C]
where \(N\) is the curve name in Cremona’s elliptic curve database, \(M\) is the minimal model, \(G\) is a \(\mathbb{Z}\)-basis of the free part of the Mordell-Weil group \(E(\mathbb{Q})\) and \(C\) is the change of coordinates from \(E\) to \(M\), suitable forellchangecurve
.
- ellinit(x, 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(E, 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(E, 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(E, 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(f, 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(E, 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(E, z)¶
Gives 1 (i.e. true) if the point \(z\) is on the elliptic curve \(E\), 0 otherwise. If \(E\) or \(z\) have imprecise coefficients, an attempt is made to take this into account, i.e. an imprecise equality is checked, not a precise one. It is allowed for \(z\) to be a vector of points in which case a vector (of the same type) is returned.
- ellisotree(E)¶
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(E, 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(x, 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(E, p)¶
Calculates the Kodaira type of the local fiber of the elliptic curve \(E\) at \(p\). \(E\) must be an
ell
structure as output 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(E, 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(E, 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)¶
\(E\) being an elliptic curve defined over a number field output by
ellinit
, return the minimal discriminant ideal of E.
- ellminimalmodel(E, 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(E, 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)¶
\(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.
- ellmodulareqn(N, x, y)¶
Given a prime \(N < 500\), return a vector \([P,t]\) where \(P(x,y)\) is a modular equation of level \(N\), i.e. a bivariate polynomial with integer coefficients; \(t\) indicates the type of this equation: either canonical (\(t = 0\)) or Atkin (\(t = 1\)). This function requires the
seadata
package and its only use is to give access to the package contents. Seepolmodular
for a more general and more flexible function.Let \(j\) be the \(j\)-invariant function. The polynomial \(P\) satisfies the functional equation,
\[P(f,j) = P(f \| W_N, j \| W_N) = 0\]for some modular function \(f = f_N\) (hand-picked for each fixed \(N\) to minimize its size, see below), where \(W_N(\tau) = -1 / (N \tau)\) is the Atkin-Lehner involution. These two equations allow to compute the values of the classical modular polynomial \(\Phi_N\), such that \(\Phi_N(j(\tau), j(N\tau)) = 0\), while being much smaller than the latter. More precisely, we have \(j(W_N(\tau)) = j(N \tau)\); the function \(f\) is invariant under \(\Gamma_0(N)\) and also satisfies
for Atkin type: \(f \| W_N = f\);
for canonical type: let \(s = 12/\mathrm{gcd} (12,N-1)\), then \(f \| W_N = N^s / f\). In this case, \(f\) has a simple definition: \(f(\tau) = N^s (\eta (N \tau) / \eta (\tau) )^{2 s}\), where \(\eta\) is Dedekind’s eta function.
The following GP function returns values of the classical modular polynomial by eliminating \(f_N(\tau)\) in the above functional equation, for \(N <= 31\) or \(N\in{41,47,59,71}\).
classicaleqn(N, X='X, Y='Y)= { my([P,t] = ellmodulareqn(N), Q, d); if (poldegree(P,'y) > 2, error("level unavailable in classicaleqn")); if (t == 0, \\ Canonical my(s = 12/gcd(12,N-1)); Q = 'x^(N+1) * substvec(P,['x,'y],[N^s/'x,Y]); d = N^(s*(2*N+1)) * (-1)^(N+1); , \\ Atkin Q = subst(P,'y,Y); d = (X-Y)^(N+1)); polresultant(subst(P,'y,X), Q) / d; }
- ellmul(E, z, n)¶
Computes \([n]z\), where \(z\) is a point on the elliptic curve \(E\). The exponent \(n\) is in \(\mathbb{Z}\), or may be a complex quadratic integer if the curve \(E\) has complex multiplication by \(n\) (if not, an error message is issued).
? Ei = ellinit([1,0]); z = [0,0]; ? ellmul(Ei, z, 10) %2 = [0] \\ unsurprising: z has order 2 ? ellmul(Ei, z, I) %3 = [0, 0] \\ Ei has complex multiplication by Z[i] ? ellmul(Ei, z, quadgen(-4)) %4 = [0, 0] \\ an alternative syntax for the same query ? Ej = ellinit([0,1]); z = [-1,0]; ? ellmul(Ej, z, I) *** at top-level: ellmul(Ej,z,I) *** ^-------------- *** ellmul: not a complex multiplication in ellmul. ? ellmul(Ej, z, 1+quadgen(-3)) %6 = [1 - w, 0]
The simple-minded algorithm for the CM case assumes that we are in characteristic \(0\), and that the quadratic order to which \(n\) belongs has small discriminant.
- ellneg(E, z)¶
Opposite of the point \(z\) on elliptic curve \(E\).
- ellnonsingularmultiple(E, P)¶
Given an elliptic curve \(E/\mathbb{Q}\) (more precisely, a model defined over \(\mathbb{Q}\) of a curve) and a rational point \(P \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(E, 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(E, 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(E, 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(E, 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(E, 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(E, 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(E, 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(E, 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(E, p, n, P)¶
Given \(E\) defined over \(K = \mathbb{Q}\) or \(\mathbb{Q}_p\) and \(P = [x,y]\) on \(E(K)\) in the kernel of reduction mod \(p\), let \(t(P) = -x/y\) be the formal group parameter; this function returns \(L(t)\), where \(L\) denotes the formal logarithm (mapping the formal group of \(E\) to the additive formal group) attached to the canonical invariant differential: \(dL = dx/(2y + a_1x + a_3)\).
? 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(E, 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(E, 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(w, 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(E, 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(E, z, n)¶
Deprecated alias for
ellmul
.
- ellratpoints(E, 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(E, 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(E, 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(N)¶
This function finds all curves in the
elldata
database satisfying the constraint defined by the argument \(N\):if \(N\) is a character string, it selects a given curve, e.g.
"11a1"
, or curves in the given isogeny class, e.g."11a"
, or curves with given conductor, e.g."11"
;if \(N\) is a vector of integers, it encodes the same constraints as the character string above, according to the
ellconvertname
correspondance, e.g.[11,0,1]
for"11a1"
,[11,0]
for"11a"
and[11]
for"11"
;if \(N\) is an integer, curves with conductor \(N\) are selected.
If \(N\) 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(L, 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(E, z1, z2)¶
Difference of the points \(z1\) and \(z2\) on the elliptic curve corresponding to \(E\).
- elltamagawa(E)¶
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(E, 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(E, 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(E)¶
If \(E\) is an elliptic curve defined over a number field or a finite field, outputs the torsion subgroup of \(E\) as a 3-component vector
[t,v1,v2]
, 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(E, 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(E, 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(E, 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(w, 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(E, 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(w, 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(E, 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(x, 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(E)¶
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(z, 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}\).
- eulerfrac(n)¶
Euler number \(E_n\), where \(E_0 = 1\), \(E_1 = 0\), \(E_2 = -1\),…, are integers such that
\[(1)/(\cosh t) = \sum_{n >= 0} (E_n)/(n!) t^n.\]The argument \(n\) should be a nonnegative integer.
? vector(10,i,eulerfrac(i)) %1 = [0, -1, 0, 5, 0, -61, 0, 1385, 0, -50521] ? eulerfrac(20000); ? sizedigit(%)) %3 = 73416
- eulerianpol(n, v)¶
Eulerian polynomial \(A_n\) in variable \(v\).
? eulerianpol(2) %1 = x + 1 ? eulerianpol(5, 't) %2 = t^4 + 26*t^3 + 66*t^2 + 26*t + 1
- eulerphi(x)¶
Euler’s \(\phi\) (totient) function of the integer \(\|x\|\), in other words \(\|(\mathbb{Z}/x\mathbb{Z})^*\|\).
? eulerphi(40) %1 = 16
According to this definition we let \(\phi (0) := 2\), since \(\mathbb{Z}^ *= {-1,1}\); this is consistent with
znstar(0)
: we haveznstar:math:`(n)
.no = eulerphi(n)` for all \(n\in\mathbb{Z}\).
- eulerpol(n, v)¶
Euler polynomial \(E_n\) in variable \(v\).
? eulerpol(1) %1 = x - 1/2 ? eulerpol(3) %2 = x^3 - 3/2*x^2 + 1/4
- eulervec(n)¶
Returns a vector containing, as rational numbers, the nonzero Euler numbers \(E_0\), \(E_2\),…, \(E_{2n}\):
? eulervec(5) \\ E_0, E_2..., E_10 %1 = [1, -1, 5, -61, 1385, -50521] ? eulerfrac(10) %2 = -50521
This routine uses more memory but is a little faster than repeated calls to
eulerfrac
:? forstep(n = 2, 8000, 2, eulerfrac(n)) time = 46,851 ms. ? eulervec(4000); time = 30,588 ms.
- exp(x, precision)¶
Exponential of \(x\). \(p\)-adic arguments with positive valuation are accepted.
- expm1(x, 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(x)¶
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
- exportall()¶
Declare all current dynamic variables as exported variables. Such variables are visible inside parallel sections in place of global variables.
? fun(x)=x^2+1; ? parvector(10,i,fun(i)) *** mt: please use export(fun). ? exportall() ? parvector(10,i,fun(i)) %4 = [2,5,10,17,26,37,50,65,82,101]
- extern(str)¶
The string str is the name of an external command (i.e. one you would type from your UNIX shell prompt). This command is immediately run and its output fed into
gp
, just as if read from a file.
- externstr(str)¶
The string str is the name of an external command (i.e. one you would type from your UNIX shell prompt). This command is immediately run and its output is returned as a vector of GP strings, one component per output line.
- factor(x, 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(f, 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(x, p)¶
This function is obsolete, use factormod.
- factorff(x, p, a)¶
Obsolete, kept for backward compatibility: use factormod.
- factorial(x, precision)¶
Factorial of \(x\). The expression \(x!\) gives a result which is an integer, while \(factorial (x)\) gives a real number.
- factorint(x, 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(f, 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(f, 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(f, 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(x, 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(pol, p, r)¶
\(p\)-adic factorization of the polynomial pol to precision \(r\), the result being a two-column matrix as in
factor
. Note that this is not the same as a factorization over \(\mathbb{Z}/p^r\mathbb{Z}\) (polynomials over that ring do not form a unique factorization domain, anyway), but approximations in \(\mathbb{Q}/p^r\mathbb{Z}\) of the true factorization in \(\mathbb{Q}_p[X]\).? factorpadic(x^2 + 9, 3,5) %1 = [(1 + O(3^5))*x^2 + O(3^5)*x + (3^2 + O(3^5)) 1] ? factorpadic(x^2 + 1, 5,3) %2 = [ (1 + O(5^3))*x + (2 + 5 + 2*5^2 + O(5^3)) 1] [(1 + O(5^3))*x + (3 + 3*5 + 2*5^2 + O(5^3)) 1]
The factors are normalized so that their leading coefficient is a power of \(p\). The method used is a modified version of the round 4 algorithm of Zassenhaus.
If pol has inexact
t_PADIC
coefficients, this is not always well-defined; in this case, the polynomial is first made integral by dividing out the \(p\)-adic content, then lifted to \(\mathbb{Z}\) 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(f, 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(a, 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(a, 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(m, 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(k, 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(p, 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)¶
\(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(x, 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(m, 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(m, 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(q, 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(x, 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(x, 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(w, 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(w, 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
- fibonacci(x)¶
\(x-th\) Fibonacci number.
- fileclose(n)¶
Close the file descriptor \(n\), created via
fileopen
orfileextern
. Finitely many files can be opened at a given time, closing them recycles file descriptors and avoids running out of them:? n = 0; while(n++, fileopen("/tmp/test", "w")) *** at top-level: n=0;while(n++,fileopen("/tmp/test","w")) *** ^-------------------------- *** fileopen: error opening requested file: `/tmp/test'. *** Break loop: type 'break' to go back to GP prompt break> n 65533
This is a limitation of the operating system and does not depend on PARI: if you open too many files in
gp
without closing them, the operating system will also prevent unrelated applications from opening files. Independently, your operating system (e.g. Windows) may prevent other applications from accessing or deleting your file while it is opened bygp
. Quittinggp
implicitly calls this function on all opened file descriptors.On files opened for writing, this function also forces a write of all buffered data to the file system and completes all pending write operations. This function is implicitly called for all open file descriptors when exiting
gp
but it is cleaner and safer to call it explicitly, for instance in case of agp
crash or general system failure, which could cause data loss.? n = fileopen("./here"); ? while(l = fileread(n), print(l)); ? fileclose(n); ? n = fileopen("./there", "w"); ? for (i = 1, 100, filewrite(n, i^2+1)) ? fileclose(n)
Until a
fileclose
, there is no guarantee that the file on disk contains all the expected data from previousfilewrite
s. (And even then the operating system may delay the actual write to hardware.)Closing a file twice raises an exception:
? n = fileopen("/tmp/test"); ? fileclose(n) ? fileclose(n) *** at top-level: fileclose(n) *** ^------------ *** fileclose: invalid file descriptor 0
- fileextern(str)¶
The string str is the name of an external command, i.e. one you would type from your UNIX shell prompt. This command is immediately run and the function returns a file descriptor attached to the command output as if it were read from a file.
? n = fileextern("ls -l"); ? while(l = filereadstr(n), print(l)) ? fileclose(n)
If the
secure
default is set, this function will raise en exception.
- fileflush(n)¶
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.
- fileopen(path, mode)¶
Open the file pointed to by ‘path’ and return a file descriptor which can be used with other file functions.
The mode can be
"r"
(default): open for reading; allowfileread
andfilereadstr
."w"
: open for writing, discarding existing content; allowfilewrite
,filewrite1
."a"
: open for writing, appending to existing content; same operations allowed as"w"
.
Eventually, the file should be closed and the descriptor recycled using
fileclose
.? n = fileopen("./here"); \\ "r" by default ? while (l = filereadstr(n), print(l)) \\ print successive lines ? fileclose(n) \\ done
In read mode, raise an exception if the file does not exist or the user does not have read permission. In write mode, raise an exception if the file cannot be written to. Trying to read or write to a file that was not opend with the right mode raises an exception.
? n = fileopen("./read", "r"); ? filewrite(n, "test") \\ not open for writing *** at top-level: filewrite(n,"test") *** ^------------------- *** filewrite: invalid file descriptor 0
- fileread(n)¶
Read a logical line from the file attached to the descriptor \(n\), opened for reading with
fileopen
. Return 0 at end of file.A logical line is a full command as it is prepared by gp’s preprocessor (skipping blanks and comments or assembling multiline commands between braces) before being fed to the interpreter. The function
filereadstr
would read a raw line exactly as input, up to the next carriage return\n
.Compare raw lines
? n = fileopen("examples/bench.gp"); ? while(l = filereadstr(n), print(l)); { u=v=p=q=1; for (k=1, 2000, [u,v] = [v,u+v]; p *= v; q = lcm(q,v); if (k%50 == 0, print(k, " ", log(p)/log(q)) ) ) }
and logical lines
? n = fileopen("examples/bench.gp"); ? while(l = fileread(n), print(l)); u=v=p=q=1;for(k=1,2000,[u,v]=[v,u+v];p*=v;q=lcm(q,v);[...]
- filereadstr(n)¶
Read a raw line from the file attached to the descriptor \(n\), opened for reading with
fileopen
, discarding the terminating newline. In other words the line is read exactly as input, up to the next carriage return\n
. By comparison,fileread
would read a logical line, as assembled by gp’s preprocessor (skipping blanks and comments for instance).
- filewrite(n, s)¶
Write the string \(s\) to the file attached to descriptor \(n\), ending with a newline. The file must have been opened with
fileopen
in"w"
or"a"
mode. There is no guarantee that \(s\) is completely written to disk untilfileclose:math:`(n)`
is executed, which is automatic when quittinggp
.If the newline is not desired, use
filewrite1
.Variant. The high-level function
write
is expensive when many consecutive writes are expected because it cannot use buffering. The low-level interfacefileopen
/filewrite
/fileclose
is more efficient:? f = "/tmp/bigfile"; ? for (i = 1, 10^5, write(f, i^2+1)) time = 240 ms. ? v = vector(10^5, i, i^2+1); time = 10 ms. \\ computing the values is fast ? write("/tmp/bigfile2",v) time = 12 ms. \\ writing them in one operation is fast ? n = fileopen("/tmp/bigfile", "w"); ? for (i = 1, 10^5, filewrite(n, i^2+1)) time = 24 ms. \\ low-level write is ten times faster ? fileclose(n);
In the final example, the file needs not be in a consistent state until the ending
fileclose
is evaluated, e.g. some lines might be half-written or not present at all even though the correspondingfilewrite
was executed already. Both a single high-levelwrite
and a succession of low-levelfilewrite
s achieve the same efficiency, but the latter is often more natural. In fact, concatenating naively the entries to be written is quadratic in the number of entries, hence much more expensive than the original write operations:? v = []; for (i = 1, 10^5, v = concat(v,i)) time = 1min, 41,456 ms.
- filewrite1(n, s)¶
Write the string \(s\) to the file attached to descriptor \(n\). The file must have been opened with
fileopen
in"w"
or"a"
mode.If you want to append a newline at the end of \(s\), you can use
Str(s,"\n")
orfilewrite
.
- floor(x)¶
Floor of \(x\). When \(x\) is in \(\mathbb{R}\), the result is the largest integer smaller than or equal to \(x\). Applied to a rational function, \(floor (x)\) returns the Euclidean quotient of the numerator by the denominator.
- fold(f, A)¶
Apply the
t_CLOSURE
f
of arity \(2\) to the entries 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(x)¶
Fractional part of \(x\). Identical to \(x-floor(x)\). If \(x\) is real, the result is in \([0,1[\).
- fromdigits(x, 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(gal, 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(gal, 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(gal)¶
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)¶
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(gal, 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(gal, 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)\)
- galoisgetgroup(a, b)¶
Query the
galpol
package for a group of order \(a\) with index \(b\) in the GAP4 Small Group library, by Hans Ulrich Besche, Bettina Eick and Eamonn O’Brien.The current version of
galpol
supports groups of order \(a <= 143\). If \(b\) is omitted, return the number of isomorphism classes of groups of order \(a\).
- galoisgetname(a, b)¶
Query the
galpol
package for a string describing the group of order \(a\) with index \(b\) in the GAP4 Small Group library, by Hans Ulrich Besche, Bettina Eick and Eamonn O’Brien. The strings were generated using the GAP4 functionStructureDescription
. The command below outputs the names of all abstract groups of order 12:? o = 12; N = galoisgetgroup(o); \\ # of abstract groups of order 12 ? for(i=1, N, print(i, ". ", galoisgetname(o,i))) 1. C3 : C4 2. C12 3. A4 4. D12 5. C6 x C2
The current version of
galpol
supports groups of order \(a <= 143\). For \(a >= 16\), it is possible for different groups to have the same name:? o = 20; N = galoisgetgroup(o); ? for(i=1, N, print(i, ". ", galoisgetname(o,i))) 1. C5 : C4 2. C20 3. C5 : C4 4. D20 5. C10 x C2
- galoisgetpol(a, b, s)¶
Query the
galpol
package for a polynomial with Galois group isomorphic to GAP4(a,b), totally real if \(s = 1\) (default) and totally complex if \(s = 2\). The current version ofgalpol
supports groups of order \(a <= 143\). The output is a vector [pol
,den
] wherepol
is the polynomial of degree \(a\)den
is the denominator ofnfgaloisconj(pol)
. Pass it as an optional argument togaloisinit
ornfgaloisconj
to speed them up:
? [pol,den] = galoisgetpol(64,4,1); ? G = galoisinit(pol); time = 352ms ? galoisinit(pol, den); \\ passing 'den' speeds up the computation time = 264ms ? % == %` %4 = 1 \\ same answer
If \(b\) and \(s\) are omitted, return the number of isomorphism classes of groups of order \(a\).
- galoisidentify(gal)¶
gal being be a Galois group as output by
galoisinit
, output the isomorphism class of the underlying abstract group as a two-components vector \([o,i]\), where \(o\) is the group order, and \(i\) is the group index in the GAP4 Small Group library, by Hans Ulrich Besche, Bettina Eick and Eamonn O’Brien.This command also accepts subgroups returned by
galoissubgroups
.The current implementation is limited to degree less or equal to \(127\). Some larger “easy” orders are also supported.
The output is similar to the output of the function
IdGroup
in GAP4. Note that GAP4IdGroup
handles all groups of order less than \(2000\) except \(1024\), so you can usegaloisexport
and GAP4 to identify large Galois groups.
- galoisinit(pol, 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(gal, 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(gal, subgrp)¶
gal being as output by
galoisinit
, and subgrp a subgroup of gal as output bygaloissubgroups
,return \(1\) if subgrp is a normal subgroup of gal, else return 0.This command also accepts subgroups returned by
galoissubgroups
.
- galoispermtopol(gal, perm)¶
gal being a Galois group as output by
galoisinit
and perm a element of \(gal.group\), return the polynomial defining the Galois automorphism, as output bynfgaloisconj
, attached to the permutation perm of the roots \(gal.roots\). perm can also be a vector or matrix, in this case,galoispermtopol
is applied to all components recursively.Note that
G = galoisinit(pol); galoispermtopol(G, G[6])~
is equivalent to
nfgaloisconj(pol)
, if degree of pol is greater or equal to \(2\).
- galoissubcyclo(N, H, fl, v)¶
Computes the subextension of \(\mathbb{Q} (\zeta_n)\) fixed by the subgroup \(H \subset (\mathbb{Z}/n\mathbb{Z})^*\). By the Kronecker-Weber theorem, all abelian number fields can be generated in this way (uniquely if \(n\) is taken to be minimal).
The pair \((n, H)\) is deduced from the parameters \((N, H)\) as follows
\(N\) an integer: then \(n = N\); \(H\) is a generator, i.e. an integer or an integer modulo \(n\); or a vector of generators.
\(N\) the output of
znstar
\((n)\) orznstar
\((n,1)\). \(H\) as in the first case above, or a matrix, taken to be a HNF left divisor of the SNF for \((\mathbb{Z}/n\mathbb{Z})^*\) (:math:`N
.cyc`), giving the generators of \(H\) in terms of:math:`N
.gen`.\(N\) the output of
bnrinit(bnfinit(y), :math:`m
)` where \(m\) is a module. \(H\) as in the first case, or a matrix taken to be a HNF left divisor of the SNF for the ray class group modulo \(m\) (of type:math:`N
.cyc`), giving the generators of \(H\) in terms of:math:`N
.bid.gen` ( =:math:`N`
.gen if \(N\) includes generators).
In this last case, beware that \(H\) is understood relatively to \(N\); in particular, if the infinite place does not divide the module, e.g if \(m\) is an integer, then it is not a subgroup of \((\mathbb{Z}/n\mathbb{Z})^*\), but of its quotient by \({± 1}\).
If \(fl = 0\), compute a polynomial (in the variable v) defining the subfield of \(\mathbb{Q} (\zeta_n)\) fixed by the subgroup H of \((\mathbb{Z}/n\mathbb{Z})^*\).
If \(fl = 1\), compute only the conductor of the abelian extension, as a module.
If \(fl = 2\), output \([pol, N]\), where \(pol\) is the polynomial as output when \(fl = 0\) and \(N\) the conductor as output when \(fl = 1\).
The following function can be used to compute all subfields of \(\mathbb{Q} (\zeta_n)\) (of exact degree
d
, ifd
is set):subcyclo(n, d = -1)= { my(bnr,L,IndexBound); IndexBound = if (d < 0, n, [d]); bnr = bnrinit(bnfinit(y), [n,[1]]); L = subgrouplist(bnr, IndexBound, 1); vector(#L,i, galoissubcyclo(bnr,L[i])); }
Setting
L = subgrouplist(bnr, IndexBound)
would produce subfields of exact conductor \(n oo\).
- galoissubfields(G, flag, v)¶
Outputs all the subfields of the Galois group G, as a vector. This works by applying
galoisfixedfield
to all subgroups. The meaning of flag is the same as forgaloisfixedfield
.
- galoissubgroups(G)¶
Outputs all the subgroups of the Galois group
gal
. A subgroup is a vector [gen, orders], with the same meaning as for \(gal.gen\) and \(gal.orders\). Hence gen is a vector of permutations generating the subgroup, and orders is the relatives orders of the generators. The cardinality of a subgroup is the product of the relative orders. Such subgroup can be used instead of a Galois group in the following command:galoisisabelian
,galoissubgroups
,galoisexport
andgaloisidentify
.To get the subfield fixed by a subgroup sub of gal, use
galoisfixedfield(gal,sub[1])
- gamma(s, precision)¶
For \(s\) a complex number, evaluates Euler’s gamma function
\[\Gamma (s) = \int_0^ oo t^{s-1}\exp (-t)dt.\]Error if \(s\) is a nonpositive integer, where \(\Gamma\) has a pole.
For \(s\) a
t_PADIC
, evaluates the Morita gamma function at \(s\), that is the unique continuous \(p\)-adic function on the \(p\)-adic integers extending \(\Gamma_p(k) = (-1)^k \prod_{j < k}'j\), where the prime means that \(p\) does not divide \(j\).? gamma(1/4 + O(5^10)) %1= 1 + 4*5 + 3*5^4 + 5^6 + 5^7 + 4*5^9 + O(5^10) ? algdep(%,4) %2 = x^4 + 4*x^2 + 5
- gammah(x, precision)¶
Gamma function evaluated at the argument \(x+1/2\).
- gammamellininv(G, t, m, precision)¶
Returns the value at \(t\) of the inverse Mellin transform \(G\) initialized by
gammamellininvinit
. If the optional parameter \(m\) is present, return the \(m\)-th derivative \(G^{(m)}(t)\).? G = gammamellininvinit([0]); ? gammamellininv(G, 2) - 2*exp(-Pi*2^2) %2 = -4.484155085839414627 E-44
The shortcut
gammamellininv(A,t,m)
for
gammamellininv(gammamellininvinit(A,m), t)
is available.
- gammamellininvasymp(A, serprec, n)¶
Return the first \(n\) terms of the asymptotic expansion at infinity of the \(m\)-th derivative \(K^{(m)}(t)\) of the inverse Mellin transform of the function
\[f(s) = \Gamma_\mathbb{R} (s+a_1)...\Gamma_\mathbb{R} (s+a_d) ,\]where
A
is the vector \([a_1,...,a_d]\) and \(\Gamma_\mathbb{R} (s) = \pi^{-s/2} \Gamma (s/2)\) (Euler’sgamma
). The result is a vector \([M[1]...M[n]]\) with M[1] = 1, such that\[K^{(m)}(t) = \sqrt{2^{d+1}/d}t^{a+m(2/d-1)}e^{-d\pi t^{2/d}} \sum_{n >= 0} M[n+1] (\pi t^{2/d})^{-n}\]with \(a = (1-d+\sum_{1 <= j <= d}a_j)/d\). We also allow \(A\) to be the output of
gammamellininvinit
.
- gammamellininvinit(A, m, precision)¶
Initialize data for the computation by
gammamellininv
of the \(m\)-th derivative of the inverse Mellin transform of the function\[f(s) = \Gamma_\mathbb{R} (s+a_1)...\Gamma_\mathbb{R} (s+a_d)\]where
A
is the vector \([a_1,...,a_d]\) and \(\Gamma_\mathbb{R} (s) = \pi^{-s/2} \Gamma (s/2)\) (Euler’sgamma
). This is the special case of Meijer’s \(G\) functions used to compute \(L\)-values via the approximate functional equation. By extension, \(A\) is allowed to be anLdata
or anLinit
, understood as the inverse Mellin transform of the \(L\)-function gamma factor.Caveat. Contrary to the PARI convention, this function guarantees an absolute (rather than relative) error bound.
For instance, the inverse Mellin transform of \(\Gamma_\mathbb{R} (s)\) is \(2\exp (-\pi z^2)\):
? G = gammamellininvinit([0]); ? gammamellininv(G, 2) - 2*exp(-Pi*2^2) %2 = -4.484155085839414627 E-44
The inverse Mellin transform of \(\Gamma_\mathbb{R} (s+1)\) is \(2 z\exp (-\pi z^2)\), and its second derivative is \(4\pi z \exp (-\pi z^2)(2\pi z^2 - 3)\):
? G = gammamellininvinit([1], 2); ? a(z) = 4*Pi*z*exp(-Pi*z^2)*(2*Pi*z^2-3); ? b(z) = gammamellininv(G,z); ? t(z) = b(z) - a(z); ? t(3/2) %3 = -1.4693679385278593850 E-39
- gcd(x, y)¶
Creates the greatest common divisor of \(x\) and \(y\). If you also need the \(u\) and \(v\) such that \(x*u + y*v = \mathrm{gcd} (x,y)\), use the
gcdext
function. \(x\) and \(y\) can have rather quite general types, for instance both rational numbers. If \(y\) is omitted and \(x\) is a vector, returns the \(gcd\) of all components of \(x\), i.e. this is equivalent tocontent(x)
.When \(x\) and \(y\) are both given and one of them is a vector/matrix type, the GCD is again taken recursively on each component, but in a different way. If \(y\) is a vector, resp. matrix, then the result has the same type as \(y\), and components equal to
gcd(x, y[i])
, resp.gcd(x, y[,i])
. Else if \(x\) is a vector/matrix the result has the same type as \(x\) and an analogous definition. Note that for these types,gcd
is not commutative.The algorithm used is a naive Euclid except for the following inputs:
integers: use modified right-shift binary (“plus-minus” variant).
univariate polynomials with coefficients in the same number field (in particular rational): use modular gcd algorithm.
general polynomials: use the subresultant algorithm if coefficient explosion is likely (non modular coefficients).
If \(u\) and \(v\) are polynomials in the same variable with inexact coefficients, their gcd is defined to be scalar, so that
? a = x + 0.0; gcd(a,a) %1 = 1 ? b = y*x + O(y); gcd(b,b) %2 = y ? c = 4*x + O(2^3); gcd(c,c) %3 = 4
A good quantitative check to decide whether such a gcd “should be” nontrivial, is to use
polresultant
: a value close to \(0\) means that a small deformation of the inputs has nontrivial gcd. You may also usegcdext
, which does try to compute an approximate gcd \(d\) and provides \(u\), \(v\) to check whether \(u x + v y\) is close to \(d\).
- gcdext(x, y)¶
Returns \([u,v,d]\) such that \(d\) is the gcd of \(x,y\), \(x*u+y*v = \mathrm{gcd} (x,y)\), and \(u\) and \(v\) minimal in a natural sense. The arguments must be integers or polynomials.
? [u, v, d] = gcdext(32,102) %1 = [16, -5, 2] ? d %2 = 2 ? gcdext(x^2-x, x^2+x-2) %3 = [-1/2, 1/2, x - 1]
If \(x,y\) are polynomials in the same variable and inexact coefficients, then compute \(u,v,d\) such that \(x*u+y*v = d\), where \(d\) approximately divides both and \(x\) and \(y\); in particular, we do not obtain
gcd(x,y)
which is defined to be a scalar in this case:? a = x + 0.0; gcd(a,a) %1 = 1 ? gcdext(a,a) %2 = [0, 1, x + 0.E-28] ? gcdext(x-Pi, 6*x^2-zeta(2)) %3 = [-6*x - 18.8495559, 1, 57.5726923]
For inexact inputs, the output is thus not well defined mathematically, but you obtain explicit polynomials to check whether the approximation is close enough for your needs.
- genus2red(PQ, p)¶
Let \(PQ\) be a polynomial \(P\), resp. a vector \([P,Q]\) of polynomials, with rational coefficients. Determines the reduction at \(p > 2\) of the (proper, smooth) genus 2 curve \(C/\mathbb{Q}\), defined by the hyperelliptic equation \(y^2 = P(x)\), resp. \(y^2 + Q(x)*y = P(x)\). (The special fiber \(X_p\) of the minimal regular model \(X\) of \(C\) over \(\mathbb{Z}\).)
If \(p\) is omitted, determines the reduction type for all (odd) prime divisors of the discriminant.
This function was rewritten from an implementation of Liu’s algorithm by Cohen and Liu (1994),
genus2reduction-0.3
, seehttp://www.math.u-bordeaux.fr/~liu/G2R/
.CAVEAT. The function interface may change: for the time being, it returns \([N,FaN, T, V]\) where \(N\) is either the local conductor at \(p\) or the global conductor, FaN is its factorization, \(y^2 = T\) defines a minimal model over \(\mathbb{Z}[1/2]\) and \(V\) describes the reduction type at the various considered \(p\). Unfortunately, the program is not complete for \(p = 2\), and we may return the odd part of the conductor only: this is the case if the factorization includes the (impossible) term \(2^{-1}\); if the factorization contains another power of \(2\), then this is the exact local conductor at \(2\) and \(N\) is the global conductor.
? default(debuglevel, 1); ? genus2red(x^6 + 3*x^3 + 63, 3) (potential) stable reduction: [1, []] reduction at p: [III{9}] page 184, [3, 3], f = 10 %1 = [59049, Mat([3, 10]), x^6 + 3*x^3 + 63, [3, [1, []], ["[III{9}] page 184", [3, 3]]]] ? [N, FaN, T, V] = genus2red(x^3-x^2-1, x^2-x); \\ X_1(13), global reduction p = 13 (potential) stable reduction: [5, [Mod(0, 13), Mod(0, 13)]] reduction at p: [I{0}-II-0] page 159, [], f = 2 ? N %3 = 169 ? FaN %4 = Mat([13, 2]) \\ in particular, good reduction at 2 ! ? T %5 = x^6 + 58*x^5 + 1401*x^4 + 18038*x^3 + 130546*x^2 + 503516*x + 808561 ? V %6 = [[13, [5, [Mod(0, 13), Mod(0, 13)]], ["[I{0}-II-0] page 159", []]]]
We now first describe the format of the vector \(V = V_p\) in the case where \(p\) was specified (local reduction at \(p\)): it is a triple \([p, stable, red]\). The component \(stable = [type, vecj]\) contains information about the stable reduction after a field extension; depending on type s, the stable reduction is
1: smooth (i.e. the curve has potentially good reduction). The Jacobian \(J(C)\) has potentially good reduction.
2: an elliptic curve \(E\) with an ordinary double point; vecj contains \(j\) mod \(p\), the modular invariant of \(E\). The (potential) semi-abelian reduction of \(J(C)\) is the extension of an elliptic curve (with modular invariant \(j\) mod \(p\)) by a torus.
3: a projective line with two ordinary double points. The Jacobian \(J(C)\) has potentially multiplicative reduction.
4: the union of two projective lines crossing transversally at three points. The Jacobian \(J(C)\) has potentially multiplicative reduction.
5: the union of two elliptic curves \(E_1\) and \(E_2\) intersecting transversally at one point; vecj contains their modular invariants \(j_1\) and \(j_2\), which may live in a quadratic extension of \(\mathbb{F}_p\) and need not be distinct. The Jacobian \(J(C)\) has potentially good reduction, isomorphic to the product of the reductions of \(E_1\) and \(E_2\).
6: the union of an elliptic curve \(E\) and a projective line which has an ordinary double point, and these two components intersect transversally at one point; vecj contains \(j\) mod \(p\), the modular invariant of \(E\). The (potential) semi-abelian reduction of \(J(C)\) is the extension of an elliptic curve (with modular invariant \(j\) mod \(p\)) by a torus.
7: as in type 6, but the two components are both singular. The Jacobian \(J(C)\) has potentially multiplicative reduction.
The component \(red = [NUtype, neron]\) contains two data concerning the reduction at \(p\) without any ramified field extension.
The NUtype is a
t_STR
describing the reduction at \(p\) of \(C\), following Namikawa-Ueno, The complete classification of fibers in pencils of curves of genus two, Manuscripta Math., vol. 9, (1973), pages 143-186. The reduction symbol is followed by the corresponding page number or page range in this article.The second datum neron is the group of connected components (over an algebraic closure of \(\mathbb{F}_p\)) of the Néron model of \(J(C)\), given as a finite abelian group (vector of elementary divisors).
If \(p = 2\), the red component may be omitted altogether (and replaced by
[]
, in the case where the program could not compute it. When \(p\) was not specified, \(V\) is the vector of all \(V_p\), for all considered \(p\).Notes about Namikawa-Ueno types.
A lower index is denoted between braces: for instance,
[I{2}-II-5]
means[I_2-II-5]
.If \(K\) and \(K'\) are Kodaira symbols for singular fibers of elliptic curves, then
[:math:`K
-\(K'\)-m]` and[:math:`K'
-\(K\)-m]` are the same.
We define a total ordering on Kodaira symbol by fixing \(I < I* < II < II*,...\). If the reduction type is the same, we order by the number of components, e.g. \(I_2 < I_4\), etc. Then we normalize our output so that \(K <= K'\).
[:math:`K
-\(K'\)-\(-1\)]` is[:math:`K
-\(K'\)-\(\alpha\)]` in the notation of Namikawa-Ueno.The figure
[2I_0-m]
in Namikawa-Ueno, page 159, must be denoted by[2I_0-(m+1)]
.
- getabstime()¶
Returns the CPU time (in milliseconds) elapsed since
gp
startup. This provides a reentrant version ofgettime
:my (t = getabstime()); ... print("Time: ", strtime(getabstime() - t));
For a version giving wall-clock time, see
getwalltime
.
- getcache()¶
Returns information about various auto-growing caches. For each resource, we report its name, its size, the number of cache misses (since the last extension), the largest cache miss and the size of the cache in bytes.
The caches are initially empty, then set automatically to a small inexpensive default value, then grow on demand up to some maximal value. Their size never decreases, they are only freed on exit.
The current caches are
Hurwitz class numbers \(H(D)\) for \(\|D\| <= N\), computed in time \(O(N^{3/2})\) using \(O(N)\) space.
Factorizations of small integers up to \(N\), computed in time \(O(N^{1+\varepsilon})\) using \(O(N\log N)\) space.
Divisors of small integers up to \(N\), computed in time \(O(N^{1+\varepsilon})\) using \(O(N\log N)\) space.
Coredisc’s of negative integers down to \(-N\), computed in time \(O(N^{1+\varepsilon})\) using \(O(N)\) space.
Primitive dihedral forms of weight \(1\) and level up to \(N\), computed in time \(O(N^{2+\varepsilon})\) and space \(O(N^2)\).
? getcache() \\ on startup, all caches are empty %1 = [ "Factors" 0 0 0 0] [ "Divisors" 0 0 0 0] [ "H" 0 0 0 0] ["CorediscF" 0 0 0 0] [ "Dihedral" 0 0 0 0] ? mfdim([500,1,0],0); \\ nontrivial computation time = 540 ms. ? getcache() %3 = [ "Factors" 50000 0 0 4479272] ["Divisors" 50000 1 100000 5189808] [ "H" 50000 0 0 400008] ["Dihedral" 1000 0 0 2278208]
- getenv(s)¶
Return the value of the environment variable
s
if it is defined, otherwise return 0.
- getheap()¶
Returns a two-component row vector giving the number of objects on the heap and the amount of memory they occupy in long words. Useful mainly for debugging purposes.
- getlocalbitprec(precision)¶
Returns the current dynamic bit precision.
- getlocalprec(precision)¶
Returns the current dynamic precision, in decimal digits.
- getrand()¶
Returns the current value of the seed used by the pseudo-random number generator
random
. Useful mainly for debugging purposes, to reproduce a specific chain of computations. The returned value is technical (reproduces an internal state array), and can only be used as an argument tosetrand
.
- getstack()¶
Returns the current value of \(top-avma\), i.e. the number of bytes used up to now on the stack. Useful mainly for debugging purposes.
- gettime()¶
Returns the CPU time (in milliseconds) used since either the last call to
gettime
, or to the beginning of the containing GP instruction (if insidegp
), whichever came last.For a reentrant version, see
getabstime
.For a version giving wall-clock time, see
getwalltime
.
- getwalltime()¶
Returns the time (in milliseconds) elapsed since 00:00:00 UTC Thursday 1, January 1970 (the Unix epoch).
my (t = getwalltime()); ... print("Time: ", strtime(getwalltime() - t));
- halfgcd(x, y)¶
Let inputs \(x\) and \(y\) be both integers, or both polynomials in the same variable. Return a vector
[M, [a,b]~]
, where \(M\) is an invertible \(2 x 2\) matrix such thatM*[x,y]~ = [a,b]~
, where \(b\) is small. More precisely,polynomial case: \(\det M\) has degree \(0\) and we have
\[\deg a >= ceil{\max (\deg x,\deg y))/2} > \deg b.\]integer case: \(\det M = ± 1\) and we have
\[ \begin{align}\begin{aligned} a >= ceil{\sqrt{\max (\|x\|,\|y\|)}} > b.\\Assuming :math:`x` and :math:`y` are nonnegative, then :math:`M^{-1}` has nonnegative coefficients, and :math:`\det M` is equal to the sign of both main diagonal terms :math:`M[1,1]` and :math:`M[2,2]`.\end{aligned}\end{align} \]
- hammingweight(x)¶
If \(x\) is a
t_INT
, return the binary Hamming weight of \(\|x\|\). Otherwise \(x\) must be of typet_POL
,t_VEC
,t_COL
,t_VECSMALL
, ort_MAT
and the function returns the number of nonzero coefficients of \(x\).? hammingweight(15) %1 = 4 ? hammingweight(x^100 + 2*x + 1) %2 = 3 ? hammingweight([Mod(1,2), 2, Mod(0,3)]) %3 = 2 ? hammingweight(matid(100)) %4 = 100
- hilbert(x, y, p)¶
Hilbert symbol of \(x\) and \(y\) modulo the prime \(p\), \(p = 0\) meaning the place at infinity (the result is undefined if \(p != 0\) is not prime).
It is possible to omit \(p\), in which case we take \(p = 0\) if both \(x\) and \(y\) are rational, or one of them is a real number. And take \(p = q\) if one of \(x\), \(y\) is a
t_INTMOD
modulo \(q\) or a \(q\)-adic. (Incompatible types will raise an error.)
- hyperellcharpoly(X)¶
\(X\) being a nonsingular hyperelliptic curve defined over a finite field, return the characteristic polynomial of the Frobenius automorphism. \(X\) can be given either by a squarefree polynomial \(P\) such that \(X: y^2 = P(x)\) or by a vector \([P,Q]\) such that \(X: y^2 + Q(x) y = P(x)\) and \(Q^2+4 P\) is squarefree.
- hyperellpadicfrobenius(Q, q, n)¶
Let \(X\) be the curve defined by \(y^2 = Q(x)\), where \(Q\) is a polynomial of degree \(d\) over \(\mathbb{Q}\) and \(q >= d\) is a prime such that \(X\) has good reduction at \(q\). Return the matrix of the Frobenius endomorphism \(\varphi\) on the crystalline module \(D_p(X) = \mathbb{Q}_p \otimes H^1_{dR}(X/\mathbb{Q})\) with respect to the basis of the given model \((\omega, x \omega,...,x^{g-1} \omega)\), where \(\omega = dx/(2 y)\) is the invariant differential, where \(g\) is the genus of \(X\) (either \(d = 2 g+1\) or \(d = 2 g+2\)). The characteristic polynomial of \(\varphi\) is the numerator of the zeta-function of the reduction of the curve \(X\) modulo \(q\). The matrix is computed to absolute \(q\)-adic precision \(q^n\).
Alternatively, \(q\) may be of the form \([T,p]\) where \(p\) is a prime, \(T\) is a polynomial with integral coefficients whose projection to \(\mathbb{F}_p[t]\) is irreducible, \(X\) is defined over \(K = \mathbb{Q}[t]/(T)\) and has good reduction to the finite field \(\mathbb{F}_q = \mathbb{F}_p[t]/(T)\). The matrix of \(\varphi\) on \(D_q(X) = \mathbb{Q}_q \otimes H^1_{dR}(X/K)\) is computed to absolute \(p\)-adic precision \(p^n\).
? M=hyperellpadicfrobenius(x^5+'a*x+1,['a^2+1,3],10); ? liftall(M) [48107*a + 38874 9222*a + 54290 41941*a + 8931 39672*a + 28651] [ 21458*a + 4763 3652*a + 22205 31111*a + 42559 39834*a + 40207] [ 13329*a + 4140 45270*a + 25803 1377*a + 32931 55980*a + 21267] [15086*a + 26714 33424*a + 4898 41830*a + 48013 5913*a + 24088] ? centerlift(simplify(liftpol(charpoly(M)))) %8 = x^4+4*x^2+81 ? hyperellcharpoly((x^5+Mod(a,a^2+1)*x+1)*Mod(1,3)) %9 = x^4+4*x^2+81
- hyperellratpoints(X, h, flag)¶
\(X\) being a nonsingular hyperelliptic curve given by an rational model, return a vector containing the affine rational points on the curve of naive height less than \(h\).a If \(flag = 1\), stop as soon as a point is found; return either an empty vector or a vector containing a single point.
\(X\) is given either by a squarefree polynomial \(P\) such that \(X: y^2 = P(x)\) or by a vector \([P,Q]\) such that \(X: y^2+Q(x) y = P(x)\) and \(Q^2+4 P\) is squarefree.
The parameter \(h\) can be
an integer \(H\): find the points \([n/d,y]\) whose abscissas \(x = n/d\) have naive height ( = \(\max (\|n\|, d)\)) less than \(H\);
a vector \([N,D]\) with \(D <= N\): find the points \([n/d,y]\) with \(\|n\| <= N\), \(d <= D\).
a vector \([N,[D_1,D_2]]\) with \(D_1 < D_2 <= N\) find the points \([n/d,y]\) with \(\|n\| <= N\) and \(D_1 <= d <= D_2\).
- hypergeom(N, D, z, precision)¶
General hypergeometric function, where
N
andD
are the vector of parameters in the numerator and denominator respectively, evaluated at the complex argument \(z\).This function implements hypergeometric functions
\[_pF_q((a_i)_{1 <= i <= p},(b_j)_{1 <= j <= q};z) = \sum_{n >= 0}(\prod_{1 <= i <= p}(a_i)_n)/(\prod_{1 <= j <= q}(b_j)_n) (z^n)/(n!) ,\]where \((a)_n = a(a+1)...(a+n-1)\) is the rising Pochammer symbol. For this to make sense, none of the \(b_j\) must be a negative or zero integer. The corresponding general GP command is
hypergeom([a1,a2,...,ap], [b1,b2,...,bq], z)
Whenever \(p = 1\) or \(q = 1\), a one-element vector can be replaced by the element it contains. Whenever \(p = 0\) or \(q = 0\), an empty vector can be omitted. For instance hypergeom(,b,z) computes \(_0F_1(;b;z)\).
We distinguish three kinds of such functions according to their radius of convergence \(R\):
\(q >= p\): \(R = oo\).
\(q = p-1\): \(R = 1\). Nonetheless, by integral representations, \(_pF_q\) can be analytically continued outside the disc of convergence.
\(q <= p-2\): \(R = 0\). By integral representations, one can make sense of the function in a suitable domain.
The list of implemented functions and their domain of validity in our implementation is as follows:
F01
:hypergeom(,a,z)
(or[a]
). This is essentially a Bessel function and computed as such. \(R = oo\).F10
:hypergeom(a,,z)
This is \((1-z)^{-a}\).F11
:hypergeom(a,b,z)
is the Kummer confluent hypergeometric function, computed by summing the series. \(R = oo\)F20
:hypergeom([a,b],,z)
. \(R = 0\), computed as\[(1)/(\Gamma (a))\int_0^ oo t^{a-1}(1-zt)^{-b}e^{-t}dt .\]F21
:hypergeom([a,b],c,z)
(or[c]
). \(R = 1\), extended by\[(\Gamma (c))/(\Gamma (b)\Gamma (c-b)) \int_0^1 t^{b-1}(1-t)^{c-b-1}(1-zt)^adt .\]This is Gauss’s Hypergeometric function, and almost all of the implementation work is done for this function.
F31
:hypergeom([a,b,c],d,z)
(or[d]
). \(R = 0\), computed as\[(1)/(\Gamma (a))\int_0^ oo t^{a-1}e^{-t}_2F_1(b,c;d;tz)dt .\]F32
:hypergeom([a,b,c],[d,e],z)
. \(R = 1\), extended by\[(\Gamma (e))/(\Gamma (c)\Gamma (e-c)) \int_0^1t^{c-1}(1-t)^{e-c-1}_2F_1(a,b;d;tz)dt .\]For other inputs: if \(R = oo\) or \(R = 1\) and \(\|z\| < 1- \varepsilon\) is not too close to the circle of convergence, we simply sum the series.
? hypergeom([3,2], 3.4, 0.7) \\ 2F1(3,2; 3.4; 0.7) %1 = 7.9999999999999999999999999999999999999 ? a=5/3; T1=hypergeom([1,1,1],[a,a],1) \\ 3F2(1,1,1; a,a; 1) %2 = 3.1958592952314032651578713968927593818 ? T2=hypergeom([2,1,1],[a+1,a+1],1) %3 = 1.6752931349345765309211012564734179541 ? T3=hypergeom([2*a-1,1,1],[a+1,a+1],1) %4 = 1.9721037126267142061807688820853354440 ? T1 + (a-1)^2/(a^2*(2*a-3)) * (T2-2*(a-1)*T3) \\ - gamma(a)^2/((2*a-3)*gamma(2*a-2)) %5 = -1.880790961315660013 E-37 \\ ~ 0
This identity is due to Bercu.
- hyperu(a, b, z, precision)¶
\(U\)-confluent hypergeometric function with complex parameters \(a, b, z\). Note that \(_2F_0(a,b,z) = (-z)^{-a}U(a, a+1-b, -1/z)\),
? hyperu(1, 3/2, I) %1 = 0.23219... - 0.80952...*I ? -I * hypergeom([1, 1+1-3/2], [], -1/I) %2 = 0.23219... - 0.80952...*I
- idealadd(nf, x, y)¶
Sum of the two ideals \(x\) and \(y\) in the number field \(nf\). The result is given in HNF.
? K = nfinit(x^2 + 1); ? a = idealadd(K, 2, x + 1) \\ ideal generated by 2 and 1+I %2 = [2 1] [0 1] ? pr = idealprimedec(K, 5)[1]; \\ a prime ideal above 5 ? idealadd(K, a, pr) \\ coprime, as expected %4 = [1 0] [0 1]
This function cannot be used to add arbitrary \(\mathbb{Z}\)-modules, since it assumes that its arguments are ideals:
? b = Mat([1,0]~); ? idealadd(K, b, b) \\ only square t_MATs represent ideals *** idealadd: nonsquare t_MAT in idealtyp. ? c = [2, 0; 2, 0]; idealadd(K, c, c) \\ nonsense %6 = [2 0] [0 2] ? d = [1, 0; 0, 2]; idealadd(K, d, d) \\ nonsense %7 = [1 0] [0 1]
In the last two examples, we get wrong results since the matrices \(c\) and \(d\) do not correspond to an ideal: the \(\mathbb{Z}\)-span of their columns (as usual interpreted as coordinates with respect to the integer basis
K.zk
) is not an \(O_K\)-module. To add arbitrary \(\mathbb{Z}\)-modules generated by the columns of matrices \(A\) and \(B\), usemathnf(concat(A,B))
.
- idealaddtoone(nf, x, y)¶
\(x\) and \(y\) being two co-prime integral ideals (given in any form), this gives a two-component row vector \([a,b]\) such that \(a\in x\), \(b\in y\) and \(a+b = 1\).
The alternative syntax \(idealaddtoone (nf,v)\), is supported, where \(v\) is a \(k\)-component vector of ideals (given in any form) which sum to \(\mathbb{Z}_K\). This outputs a \(k\)-component vector \(e\) such that \(e[i]\in x[i]\) for \(1 <= i <= k\) and \(\sum_{1 <= i <= k}e[i] = 1\).
- idealappr(nf, x, flag)¶
If \(x\) is a fractional ideal (given in any form), gives an element \(\alpha\) in \(nf\) such that for all prime ideals \(p\) such that the valuation of \(x\) at \(p\) is nonzero, we have \(v_{p}(\alpha) = v_{p}(x)\), and \(v_{p}(\alpha) >= 0\) for all other \(p\).
The argument \(x\) may also be given as a prime ideal factorization, as output by
idealfactor
, but allowing zero exponents. This yields an element \(\alpha\) such that for all prime ideals \(p\) occurring in \(x\), \(v_{p}(\alpha) = v_{p}(x)\); for all other prime ideals, \(v_{p}(\alpha) >= 0\).flag is deprecated (ignored), kept for backward compatibility.
- idealchinese(nf, x, y)¶
\(x\) being a prime ideal factorization (i.e. a 2-columns matrix whose first column contains prime ideals and the second column contains integral exponents), \(y\) a vector of elements in \(nf\) indexed by the ideals in \(x\), computes an element \(b\) such that
\(v_{p}(b - y_{p}) >= v_{p}(x)\) for all prime ideals in \(x\) and \(v_{p}(b) >= 0\) for all other \(p\).
? K = nfinit(t^2-2); ? x = idealfactor(K, 2^2*3) %2 = [[2, [0, 1]~, 2, 1, [0, 2; 1, 0]] 4] [ [3, [3, 0]~, 1, 2, 1] 1] ? y = [t,1]; ? idealchinese(K, x, y) %4 = [4, -3]~
The argument \(x\) may also be of the form \([x, s]\) where the first component is as above and \(s\) is a vector of signs, with \(r_1\) components \(s_i\) in \({-1,0,1}\): if \(\sigma_i\) denotes the \(i\)-th real embedding of the number field, the element \(b\) returned satisfies further \(sign (\sigma_i(b)) = s_i\) for all \(i\) such that \(s_i = ±1\). In other words, the sign is fixed to \(s_i\) at the \(i\)-th embedding whenever \(s_i\) is nonzero.
? idealchinese(K, [x, [1,1]], y) %5 = [16, -3]~ ? idealchinese(K, [x, [-1,-1]], y) %6 = [-20, -3]~ ? idealchinese(K, [x, [1,-1]], y) %7 = [4, -3]~
If \(y\) is omitted, return a data structure which can be used in place of \(x\) in later calls and allows to solve many chinese remainder problems for a given \(x\) more efficiently.
? C = idealchinese(K, [x, [1,1]]); ? idealchinese(K, C, y) \\ as above %9 = [16, -3]~ ? for(i=1,10^4, idealchinese(K,C,y)) \\ ... but faster ! time = 80 ms. ? for(i=1,10^4, idealchinese(K,[x,[1,1]],y)) time = 224 ms.
Finally, this structure is itself allowed in place of \(x\), the new \(s\) overriding the one already present in the structure. This allows to initialize for different sign conditions more efficiently when the underlying ideal factorization remains the same.
? D = idealchinese(K, [C, [1,-1]]); \\ replaces [1,1] ? idealchinese(K, D, y) %13 = [4, -3]~ ? for(i=1,10^4,idealchinese(K,[C,[1,-1]])) time = 40 ms. \\ faster than starting from scratch ? for(i=1,10^4,idealchinese(K,[x,[1,-1]])) time = 128 ms.
- idealcoprime(nf, x, y)¶
Given two integral ideals \(x\) and \(y\) in the number field \(nf\), returns a \(\beta\) in the field, such that \(\beta.x\) is an integral ideal coprime to \(y\).
- idealdiv(nf, x, y, flag)¶
Quotient \(x.y^{-1}\) of the two ideals \(x\) and \(y\) in the number field \(nf\). The result is given in HNF.
If \(flag\) is nonzero, the quotient \(x.y^{-1}\) is assumed to be an integral ideal. This can be much faster when the norm of the quotient is small even though the norms of \(x\) and \(y\) are large. More precisely, the algorithm cheaply removes all maximal ideals above rational primes such that \(v_p(Nx) = v_p(Ny)\).
- idealdown(nf, x)¶
Let \(nf\) be a number field as output by
nfinit
, and \(x\) a fractional ideal. This function returns the nonnegative rational generator of \(x \cap \mathbb{Q}\). If \(x\) is an extended ideal, the extended part is ignored.? nf = nfinit(y^2+1); ? idealdown(nf, -1/2) %2 = 1/2 ? idealdown(nf, (y+1)/3) %3 = 2/3 ? idealdown(nf, [2, 11]~) %4 = 125 ? x = idealprimedec(nf, 2)[1]; idealdown(nf, x) %5 = 2 ? idealdown(nf, [130, 94; 0, 2]) %6 = 130
- idealfactor(nf, x, lim)¶
Factors into prime ideal powers the ideal \(x\) in the number field \(nf\). The output format is similar to the
factor
function, and the prime ideals are represented in the form output by theidealprimedec
function. If lim is set, return partial factorization, including only prime ideals above rational primes \(< lim\).? nf = nfinit(x^3-2); ? idealfactor(nf, x) \\ a prime ideal above 2 %2 = [[2, [0, 1, 0]~, 3, 1, ...] 1] ? A = idealhnf(nf, 6*x, 4+2*x+x^2) %3 = [6 0 4] [0 6 2] [0 0 1] ? idealfactor(nf, A) %4 = [[2, [0, 1, 0]~, 3, 1, ...] 2] [[3, [1, 1, 0]~, 3, 1, ...] 2] ? idealfactor(nf, A, 3) \\ restrict to primes above p < 3 %5 = [[2, [0, 1, 0]~, 3, 1, ...] 2]
- idealfactorback(nf, f, e, flag)¶
Gives back the ideal corresponding to a factorization. The integer \(1\) corresponds to the empty factorization. If \(e\) is present, \(e\) and \(f\) must be vectors of the same length (\(e\) being integral), and the corresponding factorization is the product of the \(f[i]^{e[i]}\).
If not, and \(f\) is vector, it is understood as in the preceding case with \(e\) a vector of 1s: we return the product of the \(f[i]\). Finally, \(f\) can be a regular factorization, as produced by
idealfactor
.? nf = nfinit(y^2+1); idealfactor(nf, 4 + 2*y) %1 = [[2, [1, 1]~, 2, 1, [1, 1]~] 2] [[5, [2, 1]~, 1, 1, [-2, 1]~] 1] ? idealfactorback(nf, %) %2 = [10 4] [0 2] ? f = %1[,1]; e = %1[,2]; idealfactorback(nf, f, e) %3 = [10 4] [0 2] ? % == idealhnf(nf, 4 + 2*y) %4 = 1
If
flag
is nonzero, perform ideal reductions (idealred
) along the way. This is most useful if the ideals involved are all extended ideals (for instance with trivial principal part), so that the principal parts extracted byidealred
are not lost. Here is an example:? f = vector(#f, i, [f[i], [;]]); \\ transform to extended ideals ? idealfactorback(nf, f, e, 1) %6 = [[1, 0; 0, 1], [2, 1; [2, 1]~, 1]] ? nffactorback(nf, %[2]) %7 = [4, 2]~
The extended ideal returned in
%6
is the trivial ideal \(1\), extended with a principal generator given in factored form. We usenffactorback
to recover it in standard form.
- idealfrobenius(nf, gal, pr)¶
Let \(K\) be the number field defined by \(nf\) and assume \(K/\mathbb{Q}\) be a Galois extension with Galois group given
gal = galoisinit(nf)
, and that pr is an unramified prime ideal \(p\) inprid
format. This function returns a permutation ofgal.group
which defines the Frobenius element \(\text{Frob}_{p}\) attached to \(p\). If \(p\) is the unique prime number in \(p\), then \(\text{Frob} (x) = x^p mod p\) for all \(x\in\mathbb{Z}_K\).? nf = nfinit(polcyclo(31)); ? gal = galoisinit(nf); ? pr = idealprimedec(nf,101)[1]; ? g = idealfrobenius(nf,gal,pr); ? galoispermtopol(gal,g) %5 = x^8
This is correct since \(101 = 8 mod 31\).
- idealhnf(nf, u, v)¶
Gives the Hermite normal form of the ideal \(u\mathbb{Z}_K+v\mathbb{Z}_K\), where \(u\) and \(v\) are elements of the number field \(K\) defined by nf.
? nf = nfinit(y^3 - 2); ? idealhnf(nf, 2, y+1) %2 = [1 0 0] [0 1 0] [0 0 1] ? idealhnf(nf, y/2, [0,0,1/3]~) %3 = [1/3 0 0] [0 1/6 0] [0 0 1/6]
If \(b\) is omitted, returns the HNF of the ideal defined by \(u\): \(u\) may be an algebraic number (defining a principal ideal), a maximal ideal (as given by
idealprimedec
oridealfactor
), or a matrix whose columns give generators for the ideal. This last format is a little complicated, but useful to reduce general modules to the canonical form once in a while:if strictly less than \(N = [K:\mathbb{Q}]\) generators are given, \(u\) is the \(\mathbb{Z}_K\)-module they generate,
if \(N\) or more are given, it is assumed that they form a \(\mathbb{Z}\)-basis of the ideal, in particular that the matrix has maximal rank \(N\). This acts as
mathnf
since the \(\mathbb{Z}_K\)-module structure is (taken for granted hence) not taken into account in this case.
? idealhnf(nf, idealprimedec(nf,2)[1]) %4 = [2 0 0] [0 1 0] [0 0 1] ? idealhnf(nf, [1,2;2,3;3,4]) %5 = [1 0 0] [0 1 0] [0 0 1]
Finally, when \(K\) is quadratic with discriminant \(D_K\), we allow \(u =\)
Qfb(a,b,c)
, provided \(b^2 - 4ac = D_K\). As usual, this represents the ideal \(a \mathbb{Z} + (1/2)(-b + \sqrt{D_K}) \mathbb{Z}\).? K = nfinit(x^2 - 60); K.disc %1 = 60 ? idealhnf(K, qfbprimeform(60,2)) %2 = [2 1] [0 1] ? idealhnf(K, Qfb(1,2,3)) *** at top-level: idealhnf(K,Qfb(1,2,3 *** ^-------------------- *** idealhnf: Qfb(1, 2, 3) has discriminant != 60 in idealhnf.
- idealintersect(nf, A, B)¶
Intersection of the two ideals \(A\) and \(B\) in the number field \(nf\). The result is given in HNF.
? nf = nfinit(x^2+1); ? idealintersect(nf, 2, x+1) %2 = [2 0] [0 2]
This function does not apply to general \(\mathbb{Z}\)-modules, e.g. orders, since its arguments are replaced by the ideals they generate. The following script intersects \(\mathbb{Z}\)-modules \(A\) and \(B\) given by matrices of compatible dimensions with integer coefficients:
ZM_intersect(A,B) = { my(Ker = matkerint(concat(A,B))); mathnf( A * Ker[1..#A,] ) }
- idealinv(nf, x)¶
Inverse of the ideal \(x\) in the number field \(nf\), given in HNF. If \(x\) is an extended ideal, its principal part is suitably updated: i.e. inverting \([I,t]\), yields \([I^{-1}, 1/t]\).
- idealismaximal(nf, x)¶
Given nf a number field as output by
nfinit
and an ideal \(x\), return \(0\) if \(x\) is not a maximal ideal. Otherwise return aprid
structure nf attached to the ideal. This function usesispseudoprime
and may return a wrong result in case the underlying rational pseudoprime is not an actual prime number: applyisprime(pr.p)
to guarantee correctness. If \(x\) is an extended ideal, the extended part is ignored.? K = nfinit(y^2 + 1); ? idealismaximal(K, 3) \\ 3 is inert %2 = [3, [3, 0]~, 1, 2, 1] ? idealismaximal(K, 5) \\ 5 is not %3 = 0 ? pr = idealprimedec(K,5)[1] \\ already a prid %4 = [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]] ? idealismaximal(K, pr) \\ trivial check %5 = [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]] ? x = idealhnf(K, pr) %6 = [5 3] [0 1] ? idealismaximal(K, x) \\ converts from matrix form to prid %7 = [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]]
This function is noticeably faster than
idealfactor
since it never involves an actually factorization, in particular when \(x \cap \mathbb{Z}\) is not a prime number.
- idealispower(nf, A, n, B)¶
Let nf be a number field and \(n > 0\) be a positive integer. Return \(1\) if the fractional ideal \(A = B^n\) is an \(n\)-th power and \(0\) otherwise. If the argument \(B\) is present, set it to the \(n\)-th root of \(A\), in HNF.
? K = nfinit(x^3 - 2); ? A = [46875, 30966, 9573; 0, 3, 0; 0, 0, 3]; ? idealispower(K, A, 3, &B) %3 = 1 ? B %4 = [75 22 41] [ 0 1 0] [ 0 0 1] ? A = [9375, 2841, 198; 0, 3, 0; 0, 0, 3]; ? idealispower(K, A, 3) %5 = 0
- ideallist(nf, bound, flag)¶
Computes the list of all ideals of norm less or equal to bound in the number field nf. The result is a row vector with exactly bound components. Each component is itself a row vector containing the information about ideals of a given norm, in no specific order, depending on the value of \(flag\):
The possible values of \(flag\) are:
0: give the bid attached to the ideals, without generators.
1: as 0, but include the generators in the bid.
2: in this case, nf must be a bnf with units. Each component is of the form \([bid,U]\), where bid is as case 0 and \(U\) is a vector of discrete logarithms of the units. More precisely, it gives the
ideallog
s with respect to bid of \((\zeta,u_1,...,u_r)\) where \(\zeta\) is the torsion unit generatorbnf.tu[2]
and \((u_i)\) are the fundamental units inbnf.fu
. This structure is technical, and only meant to be used in conjunction withbnrclassnolist
orbnrdisclist
.3: as 2, but include the generators in the bid.
4: give only the HNF of the ideal.
? nf = nfinit(x^2+1); ? L = ideallist(nf, 100); ? L[1] %3 = [[1, 0; 0, 1]] \\ A single ideal of norm 1 ? #L[65] %4 = 4 \\ There are 4 ideals of norm 4 in Z[i]
If one wants more information, one could do instead:
? nf = nfinit(x^2+1); ? L = ideallist(nf, 100, 0); ? l = L[25]; vector(#l, i, l[i].clgp) %3 = [[20, [20]], [16, [4, 4]], [20, [20]]] ? l[1].mod %4 = [[25, 18; 0, 1], []] ? l[2].mod %5 = [[5, 0; 0, 5], []] ? l[3].mod %6 = [[25, 7; 0, 1], []]
where we ask for the structures of the \((\mathbb{Z}[i]/I)^*\) for all three ideals of norm \(25\). In fact, for all moduli with finite part of norm \(25\) and trivial Archimedean part, as the last 3 commands show. See
ideallistarch
to treat general moduli.
- ideallistarch(nf, list, arch)¶
list is a vector of vectors of bid’s, as output by
ideallist
with flag \(0\) to \(3\). Return a vector of vectors with the same number of components as the original list. The leaves give information about moduli whose finite part is as in original list, in the same order, and Archimedean part is now arch (it was originally trivial). The information contained is of the same kind as was present in the input; seeideallist
, in particular the meaning of flag.? bnf = bnfinit(x^2-2); ? bnf.sign %2 = [2, 0] \\ two places at infinity ? L = ideallist(bnf, 100, 0); ? l = L[98]; vector(#l, i, l[i].clgp) %4 = [[42, [42]], [36, [6, 6]], [42, [42]]] ? La = ideallistarch(bnf, L, [1,1]); \\ add them to the modulus ? l = La[98]; vector(#l, i, l[i].clgp) %6 = [[168, [42, 2, 2]], [144, [6, 6, 2, 2]], [168, [42, 2, 2]]]
Of course, the results above are obvious: adding \(t\) places at infinity will add \(t\) copies of \(\mathbb{Z}/2\mathbb{Z}\) to \((\mathbb{Z}_K/f)^*\). The following application is more typical:
? L = ideallist(bnf, 100, 2); \\ units are required now ? La = ideallistarch(bnf, L, [1,1]); ? H = bnrclassnolist(bnf, La); ? H[98]; %4 = [2, 12, 2]
- ideallog(nf, x, bid)¶
\(nf\) is a number field, bid is as output by
idealstar(nf, D,...)
and \(x\) an element of nf which must have valuation equal to 0 at all prime ideals in the support of \(D\) and need not be integral. This function computes the discrete logarithm of \(x\) on the generators given in:emphasis:`bid
.gen`. In other words, if \(g_i\) are these generators, of orders \(d_i\) respectively, the result is a column vector of integers \((x_i)\) such that \(0 <= x_i < d_i\) and\[x = \prod_i g_i^{x_i} (mod ^*D) .\]Note that when the support of
D
contains places at infinity, this congruence implies also sign conditions on the attached real embeddings. Seeznlog
for the limitations of the underlying discrete log algorithms.When nf is omitted, take it to be the rational number field. In that case, \(x\) must be a
t_INT
and bid must have been initialized byznstar(N,1)
.
- idealmin(nf, ix, vdir)¶
This function is useless and kept for backward compatibility only, use :literal:`idealred`. Computes a pseudo-minimum of the ideal \(x\) in the direction vdir in the number field nf.
- idealmul(nf, x, y, flag)¶
Ideal multiplication of the ideals \(x\) and \(y\) in the number field nf; the result is the ideal product in HNF. If either \(x\) or \(y\) are extended ideals, their principal part is suitably updated: i.e. multiplying \([I,t]\), \([J,u]\) yields \([IJ, tu]\); multiplying \(I\) and \([J, u]\) yields \([IJ, u]\).
? nf