Pari/GP Reference Documentation | Contents - Global index - GP keyboard shortcuts |
Arithmetic functions and the factoring engine Dirichlet characters Orders in finite groups and Discrete Logarithm functions addprimes bestappr bestapprPade bezout bigomega charconj chardiv chareval chargalois charker charmul charorder charpow chinese content contfrac contfracpnqn core coredisc dirdiv direuler dirmul dirpowerssum divisors divisorslenstra eulerphi factor factorback factorcantor factorff factorial factorint factormod factormodDDF factormodSQF factormodcyclo ffcompomap ffembed ffextend fffrobenius ffgen ffinit ffinvmap fflog ffmap ffmaprel ffnbirred fforder ffprimroot gcd gcdext halfgcd hilbert isfundamental ispolygonal ispower ispowerful isprime isprimepower ispseudoprime ispseudoprimepower issquare issquarefree istotient kronecker lcm logint moebius nextprime numdiv omega precprime prime primecert primecertexport primecertisvalid primepi primes qfbclassno qfbcomp qfbcompraw qfbcornacchia qfbhclassno qfbnucomp qfbnupow qfbpow qfbpowraw qfbprimeform qfbred qfbredsl2 qfbsolve quadclassunit quaddisc quadgen quadhilbert quadpoly quadray quadregulator quadunit quadunitindex quadunitnorm ramanujantau randomprime removeprimes sigma sqrtint sqrtnint sumdedekind sumdigits znchar zncharconductor znchardecompose znchargauss zncharinduce zncharisodd znchartokronecker znchartoprimitive znconreychar znconreyconductor znconreyexp znconreylog zncoppersmith znlog znorder znprimroot znstar znsubgroupgenerators | |
These functions are by definition functions whose natural domain of definition is either ℤ (or ℤ > 0). The way these functions are used is completely different from transcendental functions in that there are no automatic type conversions: in general only integers are accepted as arguments. An integer argument N can be given in the following alternate formats:
*
* This allows to compute different arithmetic functions at a given N while factoring the latter only once.
? N = 10!; faN = factor(N); ? eulerphi(N) %2 = 829440 ? eulerphi(faN) %3 = 829440 ? eulerphi(S = [N, faN]) %4 = 829440 ? sigma(S) %5 = 15334088
| |
Arithmetic functions and the factoring engine | |
All arithmetic functions in the narrow sense of the word — Euler's
totient function, the Moebius function,
the sums over divisors or powers of divisors etc. — call, after trial
division by small primes, the same versatile factoring machinery described
under
default(factor_proven, 1) to ensure that all tentative factorizations are fully proven. This should not slow down PARI too much, unless prime numbers with hundreds of decimal digits occur frequently in your application.
| |
Orders in finite groups and Discrete Logarithm functions | |
The following functions compute the order of an element in a finite group:
All such functions allow an optional argument specifying an integer N, representing the order of the group. (The order functions also allows any nonzero multiple of the order, with a minor loss of efficiency.) That optional argument follows the same format as given above:
*
*
* When the group is fixed and many orders or discrete logarithms will be computed, it is much more efficient to initialize this data once and pass it to the relevant functions, as in
? p = nextprime(10^30); ? v = [p-1, factor(p-1)]; \\ data for discrete log & order computations ? znorder(Mod(2,p), v) %3 = 500000000000000000000000000028 ? g = znprimroot(p); ? znlog(2, g, v) %5 = 543038070904014908801878611374
| |
Dirichlet characters | |
The finite abelian group G = (ℤ/Nℤ)* can be written G = ⨁ i ≤ n (ℤ/diℤ) gi, with dn | ... | d2 | d1 (SNF condition), all di > 0, and ∏i di = φ(N). The positivity and SNF condition make the di unique, but the generators gi, of respective order di, are definitely not unique. The ⨁ notation means that all elements of G can be written uniquely as ∏i gini where ni ∈ ℤ/diℤ. The gi are the so-called SNF generators of G. * a character on the abelian group ⨁ j (ℤ/djℤ) gj is given by a row vector χ = [a1,...,an] of integers 0 ≤ ai < di such that χ(gj) = e(aj / dj) for all j, with the standard notation e(x) := exp(2iπ x). In other words, χ(∏j gjnj) = e(∑j aj nj / dj). This will be generalized to more general abelian groups in later sections (Hecke characters), but in the present case of (ℤ/Nℤ)*, there is a useful alternate convention : namely, it is not necessary to impose the SNF condition and we can use Chinese remainders instead. If N = ∏ pep is the factorization of N into primes, the so-called Conrey generators of G are the generators of the (ℤ/pepℤ)* lifted to (ℤ/Nℤ)* by requesting that they be congruent to 1 modulo N/pep (for p odd we take the smallest positive primitive root mod p2, and for p = 2 we take -1 if e2 > 1 and additionally 5 if e2 > 2). We can again write G = ⨁ i ≤ n (ℤ/Diℤ) Gi, where again ∏i Di = φ(N). These generators don't satisfy the SNF condition in general since their orders are now (p-1)pep-1 for p odd; for p = 2, the generator -1 has order 2 and 5 has order 2e2-2 (e2 > 2). Nevertheless, any m ∈ (ℤ/Nℤ)* can be uniquely decomposed as m = ∏j Gimi for some mi modulo Di and we can define a character by χ(Gj) = e(mj / Dj) for all j.
* The column vector of the mj, 0 ≤ mj < Dj is
called the Conrey logarithm of m (discrete logarithm in terms of the
Conrey generators). Note that discrete logarithms in PARI/GP are always
expressed as * The attached character is called the Conrey character attached to m.
To sum up a Dirichlet character can be defined by a Concretely, this works as follows:
Also available are
| |
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
? 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
The library syntax is
| |
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
? 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
? 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 [].
The library syntax is
| |
bestapprPade(x, {B}, {Q}) | |
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 = 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 = 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
* If x is a
? 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 [].
The library syntax is
| |
bezout(x, y) | |
Deprecated alias for
The library syntax is
| |
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
The library syntax is
| |
charconj(cyc, chi) | |
Let cyc represent a finite abelian group by its elementary
divisors, i.e. (dj) represents ∑j ≤ k ℤ/djℤ with dk
| ... | d1; any object which has a
? 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
? G = znstar(16, 1); \\ (Z/16Z)* ? charconj(G, 3) \\ Conrey label %2 = [1, 1]~ ? znconreyexp(G, %) %3 = 11 \\ attached Conrey label; indeed 11 = 3^(-1) mod 16 ? chi = znconreylog(G, 3); ? charconj(G, chi) \\ Conrey logarithm %5 = [1, 1]~
The library syntax is
| |
chardiv(cyc, a, b) | |
Let cyc represent a finite abelian group by its elementary
divisors, i.e. (dj) represents ∑j ≤ k ℤ/djℤ with dk.
| ... | d1; any object which has a Given two characters a and b, return the character a / b = a 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 (ℤ/Nℤ)*, additional
representations are available (Conrey labels, Conrey logarithm),
see Section se:dirichletchar or
? 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
The library syntax is
| |
chareval(G, chi, x, {z}) | |
Let G be an abelian group structure affording a discrete logarithm
method, e.g G = Note on characters. Let K be some field. If G is an abelian group, let χ: G → K* be a character of finite order and let o be a multiple of the character order such that χ(n) = ζc(n) for some fixed ζ ∈ K* of multiplicative order o and a unique morphism c: G → (ℤ/oℤ,+). Our usual convention is to write G = (ℤ/o1ℤ) g1 ⨁ ...⨁ (ℤ/odℤ) gd for some generators (gi) of respective order di, where the group has exponent o := lcmi oi. Since ζo = 1, the vector (ci) in ∏i (ℤ/oiℤ) defines a character χ on G via χ(gi) = ζci (o/oi) for all i. Classical Dirichlet characters have values in K = ℂ and we can take ζ = exp(2iπ/o).
Note on Dirichlet characters.
In the special case where bid is attached to G = (ℤ/qℤ)*
(as per 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 ζ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 ℤ, or of Hecke characters to general ideals.) * Finally, z can be of the form [vzeta, o], where vzeta is a vector of powers ζ0,..., ζo-1 of some o-th root of 1 and o is a multiple of the character order. As above, we return ζc(x) after a table lookup. Or the sentinel value 0.
The library syntax is
| |
chargalois(cyc, {ORD}) | |
Let cyc represent a finite abelian group by its elementary divisors
(any object which has a
* if
* if
? 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 χ, of order n (
The library syntax is
| |
charker(cyc, chi) | |
Let cyc represent a finite abelian group by its elementary
divisors, i.e. (dj) represents ∑j ≤ k ℤ/djℤ with dk
| ... | d1; any object which has a
This function returns the kernel of χ, as a matrix K in HNF which is a
left-divisor of
? 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
? G = znstar(8, 1); \\ (Z/8Z)* ? charker(G, 1) \\ Conrey label for trivial character %2 = [1 0] [0 1]
The library syntax is
| |
charmul(cyc, a, b) | |
Let cyc represent a finite abelian group by its elementary
divisors, i.e. (dj) represents ∑j ≤ k ℤ/djℤ with dk
| ... | d1; any object which has a 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 (ℤ/Nℤ)*, additional
representations are available (Conrey labels, Conrey logarithm), see
Section se:dirichletchar or
? 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
The library syntax is
| |
charorder(cyc, chi) | |
Let cyc represent a finite abelian group by its elementary
divisors, i.e. (dj) represents ∑j ≤ k ℤ/djℤ with dk
| ... | d1; any object which has a
This function returns the order of the character
? 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
? G = znstar(100, 1); \\ (Z/100Z)* ? charorder(G, 7) \\ Conrey label %2 = 4
The library syntax is
| |
charpow(cyc, a, n) | |
Let cyc represent a finite abelian group by its elementary
divisors, i.e. (dj) represents ∑j ≤ k ℤ/djℤ with dk
| ... | d1; any object which has a Given n ∈ ℤ and a character a, return the character an.
? 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 (ℤ/Nℤ)*, additional
representations are available (Conrey labels, Conrey logarithm), see
Section se:dirichletchar or
? 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
The library syntax is
| |
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
? 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,
Finally
The library syntax is
| |
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 ( 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 The optional argument D allows to control over which ring we compute and get a more predictable behaviour: * 1: we only consider the underlying ℚ-structure and the denominator is a (positive) rational number
* a simple variable, say
? 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
The library syntax is
| |
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 [a0,...,an] means that x ~ a0+1/(a1+...+1/an). The output is normalized so that an ! = 1 (unless we also have n = 0).
The number of partial quotients n+1 is limited by
? \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/b0)(a0+b1/(a1+...+bn/an)); for a numerical continued
fraction (x real), the ai are integers, as large as possible;
if x is a
rational function, they are polynomials with deg ai = deg bi + 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
A direct implementation of the numerical continued fraction
\\ "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 ai; 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/a1 + 1/(a1a2) +...), 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
The library syntax is
| |
contfracpnqn(x, {n = -1}) | |
When x is a vector or a one-row matrix, x is considered as the list of partial quotients [a0,a1,...,an] of a rational number, and the result is the 2 by 2 matrix [pn,pn-1;qn,qn-1] in the standard notation of continued fractions, so pn/qn = a0+1/(a1+...+1/an). If x is a matrix with two rows [b0,b1,...,bn] and [a0,a1,...,an], this is then considered as a generalized continued fraction and we have similarly pn/qn = (1/b0)(a0+b1/(a1+...+bn/an)). Note that in this case one usually has b0 = 1. If n ≥ 0 is present, returns all convergents from p0/q0 up to pn/qn. (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]
The library syntax is
| |
core(n, {flag = 0}) | |
If n is an integer written as
n = df2 with d squarefree, returns d. If flag is nonzero,
returns the two-element row vector [d,f]. By convention, we write 0 = 0
x 12, so
The library syntax is
| |
coredisc(n, {flag = 0}) | |
A fundamental discriminant is an integer of the form t = 1 mod 4 or 4t = 8,12 mod 16, with t squarefree (i.e. 1 or the discriminant of a quadratic number field). Given a nonzero integer n, this routine returns the (unique) fundamental discriminant d such that n = df2, 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,
Note that
The library syntax is
| |
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.
The library syntax is
| |
direuler(p = a, b, expr, {c}) | |
Computes the Dirichlet series attached to the Euler product of expression expr as p ranges through the primes from a to b. expr must be a polynomial or rational function in another variable than p (say X) and expr(X) is understood as the local factor expr(p-s). The series is output as a vector of coefficients. If c is omitted, output the first b coefficients of the series; otherwise, output the first c coefficients. The following command computes the sigma function, attached to ζ(s)ζ(s-1):
? direuler(p=2, 10, 1/((1-X)*(1-p*X))) %1 = [1, 3, 4, 7, 6, 12, 8, 15, 13, 18] ? direuler(p=2, 10, 1/((1-X)*(1-p*X)), 5) \\ fewer terms %2 = [1, 3, 4, 7, 6] Setting c < b is useless (the same effect would be achieved by setting b = c). If c > b, the computed coefficients are "missing" Euler factors:
? direuler(p=2, 10, 1/((1-X)*(1-p*X)), 15) \\ more terms, no longer = sigma ! %3 = [1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 0, 28, 0, 24, 24]
The library syntax is
| |
dirmul(x, y) | |
x and y being vectors of perhaps different lengths representing the Dirichlet series ∑n xn n-s and ∑n yn 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
? dirmul([0,1], [0,1]); %2 = [0, 0, 0, 1]
The library syntax is
| |
dirpowerssum(N, x, {f}, {both = 0}) | |
For positive integer N and complex number x, return the sum
f(1)1× + f(2)2× +...+ f(N)N×, where f is a completely
multiplicative function. If f is omitted, return
1× +...+ N×. When N ≤ 0, the function returns 0.
If Caveat. when both is set, the present implementation assumes that |f(n)| is either 0 or 1, which is the case for Dirichlet characters. A vector-valued multiplicative function f is allowed, in which case the above conditions must be met componentwise and the vector length must be constant.
Unlike variants using
? dirpowers(5, 2) %1 = [1, 4, 9, 16, 25] ? vecsum(%) %2 = 55 ? dirpowerssum(5, 2) %3 = 55 ? dirpowerssum(5, -2) %4 = 1.4636111111111111111111111111111111111 ? \p200 ? s = 1/2 + I * sqrt(3); N = 10^7; ? dirpowerssum(N, s); time = 11,425 ms. ? vecsum(dirpowers(N, s)) time = 19,365 ms. ? dirpowerssum(N, s, n->kronecker(-23,n)) time = 10,981 ms.
The
The library syntax is
| |
divisors(x, {flag = 0}) | |
Creates a row vector whose components are the
divisors of x. The factorization of x (as output by
By definition, these divisors are the products of the irreducible
factors of n, as produced by
? 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) = matreduce(Mat([P,E])); ? tofact([2,3,5,7]~, [4,0,2,0]~) %4 = [2 4] [5 2]
We can then run the above loop with
The library syntax is
| |
divisorslenstra(N, r, s) | |
Given three integers N > s > r ≥ 0 such that (r,s) = 1 and s3 > 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 s3 < N.)
The library syntax is
| |
eulerphi(x) | |
Euler's φ (totient) function of the integer |x|, in other words |(ℤ/xℤ)*|.
? eulerphi(40) %1 = 16
According to this definition we let φ(0) := 2, since ℤ* = {-1,1};
this is consistent with
The library syntax is
| |
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 ℤ, if it is a polynomial with rational coefficients, it is factored in ℚ[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 01.
x ∈ ℚ.
See
? factor(-7/106) %1 = [-1 1] [ 2 -1] [ 7 1] [53 -1]
By convention, 1 is factored as
Large rational "primes" > 264 in the factorization are in fact
pseudoprimes (see
? 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
A
? factor(2^2^7 +1, 10^5) %4 = [340282366920938463463374607431768211457 1]
Deprecated feature. Setting D = 0 is the same
as setting it to
This routine uses trial division and perfect power tests, and should not be
used for huge values of D (at most 109, say):
? 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] x ∈ ℚ(i). The factorization is performed with Gaussian primes in ℤ[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.
Unless
? 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: ℚ, ℝ, ℂ, ℚp, finite fields and
number fields. See
The content is not included in the factorization, in particular
? 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 = ℚ : D a rational number (
* K = ℤ/pℤ with p prime : D a
* K = 𝔽q : D a
* K = ℚ[X]/(T) a number field : D a * K = ℚ(i) (alternate syntax for special case): D = I,
* K = ℚ(w) a quadratic number field (alternate syntax for special
case): D a
* K = ℝ : D a real number (
* K = ℂ : D a complex number with a
* K = ℚp : D a
? T = x^2+1; ? factor(T, 1); \\ over Q ? factor(T, Mod(1,3)) \\ over F3 ? factor(T, ffgen(ffinit(3,2,'t))^0) \\ over F3^2 ? factor(T, Mod(Mod(1,3), t^2+t+2)) \\ over F3^2, again ? factor(T, O(3^6)) \\ over Q3, precision 6 ? factor(T, 1.) \\ over R, current precision ? factor(T, I*1.) \\ over C ? factor(T, Mod(1, y^3-2)) \\ over Q(21/3) In most cases, it is possible and simpler to call a specialized variant rather than use the above scheme:
? factormod(T, 3) \\ over F3 ? factormod(T, [t^2+t+2, 3]) \\ over F3^2 ? factormod(T, ffgen(3^2, 't)) \\ over F3^2 ? factorpadic(T, 3,6) \\ over Q3, precision 6 ? nffactor(y^3-2, T) \\ over Q(21/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 = x^2+1; ? factor(T); \\ over Q ? factor(T*Mod(1,3)) \\ over F3 ? factor(T*ffgen(ffinit(3,2,'t))^0) \\ over F3^2 ? factor(T*Mod(Mod(1,3), t^2+t+2)) \\ over F3^2, again ? factor(T*(1 + O(3^6)) \\ over Q3, 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(21/3) Multiplying by a suitable field element equal to 1 ∈ 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 Q2 %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
? 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[t1,..., td] 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 (ℝ or ℂ) 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]
The library syntax is
| |
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(12) %1 = [2 2] [3 1] ? factorback(%) %2 = 12 ? factorback([2,3], [2,1]) \\ 2^2 * 3^1 %3 = 12 ? factorback([5,2,3]) %4 = 30
The library syntax is
| |
factorcantor(x, p) | |
This function is obsolete, use factormod.
The library syntax is
| |
factorff(x, {p}, {a}) | |
Obsolete, kept for backward compatibility: use factormod.
The library syntax is
| |
factorial(x) | |
Factorial of x. The expression x! gives a result which is an integer,
while
The library syntax is
| |
factorint(x, {flag = 0}) | |
Factors the integer n into a product of
pseudoprimes (see
By convention 0 is factored as 01, and 1 as the empty factorization;
also the divisors are by default not proven primes if they are larger than
264, they only failed the BPSW compositeness test (see
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
The library syntax is
| |
factormod(f, {D}, {flag = 0}) | |
Factors the polynomial f over the finite field defined by the domain D as follows: * D = p a prime: factor over 𝔽p; * D = [T,p] for a prime p and T(y) an irreducible polynomial over 𝔽p: factor over 𝔽p[y]/(T) (as usual the main variable of T must have lower priority than the main variable of f);
* D a * 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 01; 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 F3 %1 = [Mod(1, 3)*x^2 + Mod(1, 3) 1] ? liftall( factormod(x^2 + 1, [t^2+1, 3]) ) \\ over F9 %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]
The library syntax is
| |
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 𝔽p; * D = [T,p] for a prime p and T an irreducible polynomial over 𝔽p: factor over 𝔽p[x]/(T);
* D a * D omitted: factor over the field of definition of f, which must be a finite field. If f is not squarefree, the result is undefined. 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 the same degree d; * the second column contains the degrees of the irreducible factors. The factorization is ordered by increasing degree d of irreducible factors, and the result is obviously canonical. This function is somewhat faster than full factorization.
? f = (x^2 + 1) * (x^2-1); ? factormodSQF(f,3) \\ squarefree over F3 %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 a little slower time = 464 ms. ? liftall( factormodDDF(x^2 + 1, [3, t^2+1]) ) \\ over F9 %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]
The library syntax is
| |
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 𝔽p; * D = [T,p] for a prime p and T an irreducible polynomial over 𝔽p: factor over 𝔽p[x]/(T);
* D a * 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 contains monic squarefree pairwise coprime polynomials dividing f; * the second column contains the power to which the polynomial in column 1 divides f; This is somewhat faster than full factorization. The factors are ordered by increasing exponent and the result is obviously canonical.
? f = (x^2 + 1)^3 * (x^2-1)^2; ? factormodSQF(f, 3) \\ over F3 %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 F9 %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]
The library syntax is
| |
factormodcyclo(n, p, {single = 0}, {v = 'x}) | |
Factors n-th cyclotomic polynomial Φn(x) mod p,
where p is a prime number not dividing n.
Much faster than Let F = ℚ(ζn). Let K be the splitting field of p in F and e the conductor of K. Then Φn(x) and Φe(x) have the same number of irreducible factors mod p and there is a simple algorithm constructing irreducible factors of Φn(x) from irreducible factors of Φe(x). So we may assume n is equal to the conductor of K. Let d be the order of p in (ℤ/nℤ)× and ϕ(n) = df. Then Φn(x) has f irreducible factors gi(x) (1 ≤ i ≤ f) of degree d over 𝔽p or ℤp. * If d is small, then we factor gi(x) into d linear factors gij(x), 1 ≤ j ≤ d in 𝔽q[x] (q = pd) and construct Gi(x) = ∏j = 1d gij(x) ∈ 𝔽q[x]. Then Gi(x) ∈ 𝔽p[x] and gi(x) = Gi(x). * If f is small, then we work in K, which is a Galois extension of degree f over ℚ. The Gaussian period θk = TrF/K(ζnk) is a sum of k-th power of roots of gi(x) and K = ℚ(θ1). Now, for each k, there is a polynomial Tk(x) ∈ ℚ[x] satisfying θk = Tk(θ1) because all θk are in K. Let T(x) ∈ ℤ[x] be the minimal polynomial of θ1 over ℚ. We get θ1 mod p from T(x) and construct θ1,...,θd mod p using Tk(x). Finally we recover gi(x) from θ1,...,θd by Newton's formula.
? lift(factormodcyclo(15, 11)) %1 = [x^2 + 9*x + 4, x^2 + 4*x + 5, x^2 + 3*x + 9, x^2 + 5*x + 3] ? factormodcyclo(15, 11, 1) \\ single %2 = Mod(1, 11)*x^2 + Mod(5, 11)*x + Mod(3, 11) ? z1 = lift(factormod(polcyclo(12345),11311)[,1]); time = 32,498 ms. ? z2 = factormodcyclo(12345,11311); time = 47 ms. ? z1 == z2 %4 = 1
The library syntax is
| |
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
The library syntax is
| |
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
The library syntax is
| |
ffextend(a, P, {v}) | |
Extend the field K of definition of a by a root of the polynomial
P ∈ 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
? 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
The library syntax is
| |
fffrobenius(m, {n = 1}) | |
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
The library syntax is
| |
ffgen(k, {v = 'x}) | |
Return a generator for the finite field k as a * its order q * the pair [p,f] where q = pf
* a monic irreducible polynomial with
* a
If
When only the order is specified, the function uses the polynomial generated
by
To obtain a multiplicative generator, call
? 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 ? T = minpoly(a) \\ primitive polynomial %8 = Mod(1, 2)*x^4 + Mod(1, 2)*x^3 + Mod(1, 2) ? G = ffgen(T); \\ is now a multiplicative generator ? fforder(G) %10 = 15
The library syntax is
To create a generator for a prime finite field, the function
| |
ffinit(p, n, {v = 'x}) | |
Computes a monic polynomial of degree n which is irreducible over 𝔽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
The library syntax is
| |
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 ∈ 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 = []
The library syntax is
| |
fflog(x, g, {o}) | |
Discrete logarithm of the finite field element x in base g,
i.e. an e in ℤ such that ge = o. If
present, o represents the multiplicative order of g, see
Section se:DLfun; the preferred format for
this parameter is
* a combination of generic discrete log algorithms (see * 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
The library syntax is
| |
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
The library syntax is
| |
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
The library syntax is
| |
ffnbirred(q, n, {flag = 0}) | |
Computes the number of monic irreducible polynomials over 𝔽q of degree exactly n (flag = 0 or omitted) or at most n (flag = 1).
The library syntax is
| |
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 Section se:DLfun; the preferred format for
this parameter is
? 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
The library syntax is
| |
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
? 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
The library syntax is
| |
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 = gcd(x,y),
use the
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 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
The library syntax is
| |
gcdext(x, y) | |
Returns [u,v,d] such that d is the gcd of x,y, x*u+y*v = 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
? 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.
The library syntax is
| |
halfgcd(x, y) | |
Let inputs x and y be both integers, or both polynomials in the same
variable. Return a vector * 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 a ≥ ceil{sqrt{max(|x|,|y|)}} > b. Assuming x and y are nonnegative, then M-1 has nonnegative coefficients, and det M is equal to the sign of both main diagonal terms M[1,1] and M[2,2].
The library syntax is
| |
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
The library syntax is
| |
isfundamental(D) | |
True (1) if D is equal to 1 or to the discriminant of a quadratic field, false (0) otherwise. D can be input in factored form as for arithmetic functions:
? isfundamental(factor(-8)) %1 = 1 \\ count fundamental discriminants up to 10^8 ? c = 0; forfactored(d = 1, 10^8, if (isfundamental(d), c++)); c time = 40,840 ms. %2 = 30396325 ? c = 0; for(d = 1, 10^8, if (isfundamental(d), c++)); c time = 1min, 33,593 ms. \\ slower ! %3 = 30396325
The library syntax is
| |
ispolygonal(x, s, {&N}) | |
True (1) if the integer x is an s-gonal number, false (0) if not.
The parameter s > 2 must be a
? ispolygonal(36, 3, &N) %1 = 1 ? N
The library syntax is
| |
ispower(x, {k}, {&n}) | |
If k is given, returns true (1) if x is a k-th power, false
(0) if not. What it means to be a k-th power depends on the type of
x; see
If k is omitted, only integers and fractions are allowed for x and the
function returns the maximal k ≥ 2 such that x = nk is a perfect
power, or 0 if no such k exist; in particular If a third argument &n is given and x is indeed a k-th power, sets n to a k-th root of x.
For a
k = (x.p ^ x.f - 1) / fforder(x)
The library syntax is
| |
ispowerful(x) | |
True (1) if x is a powerful integer, false (0) if not; an integer is powerful if and only if its valuation at all primes dividing x is greater than 1.
? ispowerful(50) %1 = 0 ? ispowerful(100) %2 = 1 ? ispowerful(5^3*(10^1000+1)^2) %3 = 1
The library syntax is
| |
isprime(x, {flag = 0}) | |
True (1) if x is a prime number, false (0) otherwise. A prime number is a positive integer having exactly two distinct divisors among the natural numbers, namely 1 and itself.
This routine proves or disproves rigorously that a number is prime, which can
be very slow when x is indeed a large prime integer. For instance
a 1000 digits prime should require 15 to 30 minutes with default algorithms.
Use The function accepts vector/matrices arguments, and is then applied componentwise. If flag = 0, use a combination of
* Baillie-Pomerance-Selfridge-Wagstaff compositeness test
(see * Selfridge "p-1" test if x-1 is smooth enough, * Adleman-Pomerance-Rumely-Cohen-Lenstra (APRCL) for general medium-sized x (less than 1500 bits), * Atkin-Morain's Elliptic Curve Primality Prover (ECPP) for general large x. If flag = 1, use Selfridge-Pocklington-Lehmer "p-1" test; this requires partially factoring various auxilliary integers and is likely to be very slow. If flag = 2, use APRCL only. If flag = 3, use ECPP only.
The library syntax is
| |
isprimepower(x, {&n}) | |
If x = pk is a prime power (p prime, k > 0), return k, else return 0. If a second argument &n is given and x is indeed the k-th power of a prime p, sets n to p.
The library syntax is
| |
ispseudoprime(x, {flag}) | |
True (1) if x is a strong pseudo
prime (see below), false (0) otherwise. If this function returns false, x
is not prime; if, on the other hand it returns true, it is only highly likely
that x is a prime number. Use If flag = 0, checks whether x has no small prime divisors (up to 101 included) and is a Baillie-Pomerance-Selfridge-Wagstaff pseudo prime. Such a pseudo prime passes a Rabin-Miller test for base 2, followed by a Lucas test for the sequence (P,1), where P ≥ 3 is the smallest odd integer such that P2 - 4 is not a square mod x. (Technically, we are using an "almost extra strong Lucas test" that checks whether Vn is ± 2, without computing Un.)
There are no known composite numbers passing the above test, although it is
expected that infinitely many such numbers exist. In particular, all
composites ≤ 264 are correctly detected (checked using
If flag > 0, checks whether x is a strong Miller-Rabin pseudo prime for flag randomly chosen bases (with end-matching to catch square roots of -1).
The library syntax is
| |
ispseudoprimepower(x, {&n}) | |
If x = pk is a pseudo-prime power (p pseudo-prime as per
More precisely, k is always the largest integer such that x = nk for
some integer n and, when n ≤ 264 the function returns k > 0 if and
only if n is indeed prime. When n > 264 is larger than the threshold,
the function may return 1 even though n is composite: it only passed
an
The library syntax is
| |
issquare(x, {&n}) | |
True (1) if x is a square, false (0)
if not. What "being a square" means depends on the type of x: all
? issquare(3) \\ as an integer %1 = 0 ? issquare(3.) \\ as a real number %2 = 1 ? issquare(Mod(7, 8)) \\ in Z/8Z %3 = 0 ? issquare( 5 + O(13^4) ) \\ in Q_13 %4 = 0 If n is given, a square root of x is put into n.
? issquare(4, &n) %1 = 1 ? n %2 = 2 For polynomials, either we detect that the characteristic is 2 (and check directly odd and even-power monomials) or we assume that 2 is invertible and check whether squaring the truncated power series for the square root yields the original input.
For
? issquare(Mod(Mod(2,3), x^2+1), &n) %1 = 1 ? n %2 = Mod(Mod(2, 3)*x, Mod(1, 3)*x^2 + Mod(1, 3))
The library syntax is
| |
issquarefree(x) | |
True (1) if x is squarefree, false (0) if not. Here x can be an integer or a polynomial with coefficients in an integral domain.
? issquarefree(12) %1 = 0 ? issquarefree(6) %2 = 1 ? issquarefree(x^3+x^2) %3 = 0 ? issquarefree(Mod(1,4)*(x^2+x+1)) \\ Z/4Z is not a domain ! *** at top-level: issquarefree(Mod(1,4)*(x^2+x+1)) *** ^ — — — — — — — — — — -- *** issquarefree: impossible inverse in Fp_inv: Mod(2, 4).
A polynomial is declared squarefree if An integer can be input in factored form as in arithmetic functions.
? issquarefree(factor(6)) %1 = 1 \\ count squarefree integers up to 10^8 ? c = 0; for(d = 1, 10^8, if (issquarefree(d), c++)); c time = 3min, 2,590 ms. %2 = 60792694 ? c = 0; forfactored(d = 1, 10^8, if (issquarefree(d), c++)); c time = 45,348 ms. \\ faster ! %3 = 60792694
The library syntax is
| |
istotient(x, {&N}) | |
True (1) if x = φ(n) for some integer n, false (0) if not.
? istotient(14) %1 = 0 ? istotient(100) %2 = 0 If N is given, set N = n as well.
? istotient(4, &n) %1 = 1 ? n %2 = 10
The library syntax is
| |
kronecker(x, y) | |
Kronecker symbol (x|y), where x and y must be of type integer. By definition, this is the extension of Legendre symbol to ℤ x ℤ by total multiplicativity in both arguments with the following special rules for y = 0, -1 or 2: * (x|0) = 1 if |x |= 1 and 0 otherwise. * (x|-1) = 1 if x ≥ 0 and -1 otherwise. * (x|2) = 0 if x is even and 1 if x = 1,-1 mod 8 and -1 if x = 3,-3 mod 8.
The library syntax is
| |
lcm(x, {y}) | |
Least common multiple of x and y, i.e. such that lcm(x,y)*gcd(x,y) = x*y, up to units. If y is omitted and x is a vector, returns the lcm of all components of x. For integer arguments, return the nonnegative lcm.
When x and y are both given and one of them is a vector/matrix type,
the LCM is again taken recursively on each component, but in a different way.
If y is a vector, resp. matrix, then the result has the same type as y,
and components equal to
Note that
l = v[1]; for (i = 1, #v, l = lcm(l, v[i]))
Indeed,
? v = vector(10^5, i, random); ? lcm(v); time = 546 ms. ? l = v[1]; for (i = 1, #v, l = lcm(l, v[i])) time = 4,561 ms.
The library syntax is
| |
logint(x, b, {&z}) | |
Return the largest non-negative integer e so that be ≤ x, where b > 1 is an integer and x ≥ 1 is a real number. If the parameter z is present, set it to be.
? logint(1000, 2) %1 = 9 ? 2^9 %2 = 512 ? logint(1000, 2, &z) %3 = 9 ? z %4 = 512 ? logint(Pi^2, 2, &z) %5 = 3 ? z %6 = 8
The number of digits used to write x in base b is
? #digits(1000!, 10) %5 = 2568 ? logint(1000!, 10) %6 = 2567 This function may conveniently replace
floor( log(x) / log(b) ) which may not give the correct answer since PARI does not guarantee exact rounding.
The library syntax is
| |
moebius(x) | |
Moebius μ-function of |x|; x must be a nonzero integer.
The library syntax is
| |
nextprime(x) | |
Finds the smallest pseudoprime (see
? nextprime(2) %1 = 2 ? nextprime(Pi) %2 = 5 ? nextprime(-10) %3 = 2 \\ primes are positive
Despite the name, please note that the function is not guaranteed to return
a prime number, although no counter-example is known at present. The return
value is a guaranteed prime if x ≤ 264. To rigorously prove
that the result is prime in all cases, use
The library syntax is
| |
numdiv(x) | |
Number of divisors of |x|. x must be of type integer.
The library syntax is
| |
omega(x) | |
Number of distinct prime divisors of |x|. x must be of type integer.
? factor(392) %1 = [2 3] [7 2] ? omega(392) %2 = 2; \\ without multiplicity ? bigomega(392) %3 = 5; \\ = 3+2, with multiplicity
The library syntax is
| |
precprime(x) | |
Finds the largest pseudoprime (see
? precprime(2) %1 = 2 ? precprime(Pi) %2 = 3 ? precprime(-10) %3 = 0 \\ primes are positive
The function name comes from preceding prime.
Despite the name, please note that the function is not guaranteed to return
a prime number (although no counter-example is known at present); the return
value is a guaranteed prime if x ≤ 264. To rigorously prove
that the result is prime in all cases, use
The library syntax is
| |
prime(n) | |
The n-th prime number
? prime(10^9) %1 = 22801763489
Uses checkpointing and a naive O(n) algorithm. Will need
about 30 minutes for n up to 1011; make sure to start gp with
The library syntax is
| |
primecert(N, {flag = 0}, {partial = 0}) | |
If N is a prime, return a PARI Primality Certificate for the prime N,
as described below. Otherwise, return 0. A Primality Certificate
c can be checked using If flag = 0 (default), return an ECPP certificate (Atkin-Morain) If flag = 0 and partial > 0, return a (potentially) partial ECPP certificate.
A PARI ECPP Primality Certificate for the prime N is either a prime
integer N < 264 or a vector * Ni is a positive integer * ti is an integer such that ti2 < 4Ni * si is a positive integer which divides mi where mi = Ni + 1 - ti * If we set qi = (mi)/(si), then * qi > (Ni1/4+1)2 * qi = Ni+1 if 1 ≤ i < l * qℓ ≤ 264 is prime * ai is an integer
* * mi Pi = oo * si Pi ! = oo
Using the following theorem, the data in the vector Theorem. If N is an integer and there exist positive integers m, q and a point P on the elliptic curve E: y2 = x3 + ax + b defined modulo N such that q > (N1/4 + 1)2, q is a prime divisor of m, mP = oo and (m)/(q)P ! = oo , then N is prime. A partial certificate is identical except that the condition qℓ ≤ 264 is replaced by qℓ ≤ 2partial. Such partial certificate C can be extended to a full certificate by calling C = primecert(C), or to a longer partial certificate by calling C = primecert(C,,b) with b < partial.
? primecert(10^35 + 69) %1 = [[100000000000000000000000000000000069, 5468679110354 52074, 2963504668391148, 0, [60737979324046450274283740674 208692, 24368673584839493121227731392450025]], [3374383076 4501150277, -11610830419, 734208843, 0, [26740412374402652 72 4, 6367191119818901665]], [45959444779, 299597, 2331, 0 , [18022351516, 9326882 51]]] ? primecert(nextprime(2^64)) %2 = [[18446744073709551629, -8423788454, 160388, 1, [1059 8342506117936052, 2225259013356795550]]] ? primecert(6) %3 = 0 ? primecert(41) %4 = 41 ? N = 2^2000+841; ? Cp1 = primecert(N,,1500); \\ partial certificate time = 16,018 ms. ? Cp2 = primecert(Cp1,,1000); \\ (longer) partial certificate time = 5,890 ms. ? C = primecert(Cp2); \\ full certificate for N time = 1,777 ms. ? primecertisvalid(C) %9 = 1 ? primecert(N); time = 23,625 ms. As the last command shows, attempting a succession of partial certificates should be about as fast as a direct computation. If flag = 1 (very slow), return an N-1 certificate (Pocklington Lehmer) A PARI N-1 Primality Certificate for the prime N is either a prime integer N < 264 or a pair [N, C], where C is a vector with ℓ elements which are either a single integer pi < 264 or a triple [pi,ai,Ci] with pi > 264 satisfying the following properties: * pi is a prime divisor of N - 1; * ai is an integer such that aiN-1 = 1 (mod N) and ai(N-1)/pi - 1 is coprime with N; * Ci is an N-1 Primality Certificate for pi * The product F of the pivp_{i(N-1)} is strictly larger than N1/3. Provided that all pi are indeed primes, this implies that any divisor of N is congruent to 1 modulo F. * The Brillhart-Lehmer-Selfridge criterion is satisfied: when we write N = 1 + c1 F + c2 F2 in base F the polynomial 1 + c1 X + c2 X2 is irreducible over ℤ, i.e. c12 - 4c2 is not a square. This implies that N is prime. This algorithm requires factoring partially p-1 for various prime integers p with an unfactored parted ≤ p2/3 and this may be exceedingly slow compared to the default.
The algorithm fails if one of the pseudo-prime factors is not prime, which is
exceedingly unlikely and well worth a bug report. Note that if you monitor
the algorithm at a high enough debug level, you may see warnings about
untested integers being declared primes. This is normal: we ask for partial
factorizations (sufficient to prove primality if the unfactored part is not
too large), and
The library syntax is
| |
primecertexport(cert, {format = 0}) | |
Returns a string suitable for print/write to display a primality certificate
from
* 0 (default): Human-readable format. See * 1: Primo format 4. * 2: MAGMA format. Currently, only ECPP Primality Certificates are supported.
? cert = primecert(10^35+69); ? s = primecertexport(cert); \\ Human-readable ? print(s) [1] N = 100000000000000000000000000000000069 t = 546867911035452074 s = 2963504668391148 a = 0 D = -3 m = 99999999999999999453132088964547996 q = 33743830764501150277 E = [0, 1] P = [21567861682493263464353543707814204, 49167839501923147849639425291163552] [2] N = 33743830764501150277 t = -11610830419 s = 734208843 a = 0 D = -3 m = 33743830776111980697 q = 45959444779 E = [0, 25895956964997806805] P = [29257172487394218479, 3678591960085668324] \\ Primo format ? s = primecertexport(cert,1); write("cert.out", s); \\ Magma format, write to file ? s = primecertexport(cert,2); write("cert.m", s); ? cert = primecert(10^35+69, 1); \\ N-1 certificate ? primecertexport(cert) *** at top-level: primecertexport(cert) *** ^ — — — — — — — *** primecertexport: sorry, N-1 certificate is not yet implemented.
The library syntax is
| |
primecertisvalid(cert) | |
Verifies if cert is a valid PARI ECPP Primality certificate, as described
in
? cert = primecert(10^35 + 69) %1 = [[100000000000000000000000000000000069, 5468679110354 52074, 2963504668391148, 0, [60737979324046450274283740674 208692, 24368673584839493121227731392450025]], [3374383076 4501150277, -11610830419, 734208843, 0, [26740412374402652 72 4, 6367191119818901665]], [45959444779, 299597, 2331, 0 , [18022351516, 9326882 51]]] ? primecertisvalid(cert) %2 = 1 ? cert[1][1]++; \\ random perturbation ? primecertisvalid(cert) %4 = 0 \\ no longer valid ? primecertisvalid(primecert(6)) %5 = 0
The library syntax is
| |
primepi(x) | |
The prime counting function. Returns the number of primes p, p ≤ x.
? primepi(10) %1 = 4; ? primes(5) %2 = [2, 3, 5, 7, 11] ? primepi(10^11) %3 = 4118054813
Uses checkpointing and a naive O(x) algorithm;
make sure to start gp with
The library syntax is
| |
primes(n) | |
Creates a row vector whose components are the first n prime numbers.
(Returns the empty vector for n ≤ 0.) A
? primes(10) \\ the first 10 primes %1 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] ? primes([0,29]) \\ the primes up to 29 %2 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] ? primes([15,30]) %3 = [17, 19, 23, 29]
The library syntax is
| |
qfbclassno(D, {flag = 0}) | |
Ordinary class number of the quadratic order of discriminant D, for "small" values of D.
* if D > 0 or flag = 1, use a O(|D|1/2)
algorithm (compute L(1,χD) with the approximate functional equation).
This is slower than
* if D < 0 and flag = 0 (or omitted), use a O(|D|1/4)
algorithm (Shanks's baby-step/giant-step method). It should
be faster than
Important warning. In the latter case, this function only
implements part of Shanks's method (which allows to speed it up
considerably). It gives unconditionnally correct results for
|D| < 2.1010, but may give incorrect results for larger values
if the class
group has many cyclic factors. We thus recommend to double-check results
using the function Warning. Contrary to what its name implies, this routine does not compute the number of classes of binary primitive forms of discriminant D, which is equal to the narrow class number. The two notions are the same when D < 0 or the fundamental unit ϵ has negative norm; when D > 0 and Nϵ > 0, the number of classes of forms is twice the ordinary class number. This is a problem which we cannot fix for backward compatibility reasons. Use the following routine if you are only interested in the number of classes of forms:
? QFBclassno(D) = qfbclassno(D) * if (D > 0 && quadunitnorm(D) > 0, 2, 1) ? QFBclassno(136) %1 = 4 ? qfbclassno(136) %2 = 2 ? quadunitnorm(136) %3 = 1 ? bnfnarrow(bnfinit(x^2 - 136)).cyc %4 = [4] \\ narrow class group is cyclic ~ Z/4Z
Note that the use of
? qfbclassno(400000028) \\ D > 0: slow time = 3,140 ms. %1 = 1 ? quadclassunit(400000028).no time = 20 ms. \\ { much faster, assume GRH} %2 = 1 ? qfbclassno(-400000028) \\ D < 0: fast enough time = 0 ms. %3 = 7253 ? quadclassunit(-400000028).no time = 0 ms. %4 = 7253
See also
The library syntax is
| |
qfbcomp(x, y) | |
composition of the binary quadratic forms x and y, with reduction of the result.
? x=Qfb(2,3,-10);y=Qfb(5,3,-4); ? qfbcomp(x,y) %2 = Qfb(-2, 9, 1) ? qfbcomp(x,y)==qfbred(qfbcompraw(x,y)) %3 = 1
The library syntax is
| |
qfbcompraw(x, y) | |
composition of the binary quadratic forms x and y, without reduction of the result. This is useful e.g. to compute a generating element of an ideal. The result is undefined if x and y do not have the same discriminant.
? x=Qfb(2,3,-10);y=Qfb(5,3,-4); ? qfbcompraw(x,y) %2 = Qfb(10, 3, -2) ? x=Qfb(2,3,-10);y=Qfb(1,-1,1); ? qfbcompraw(x,y) *** at top-level: qfbcompraw(x,y) *** ^ — — — — — *** qfbcompraw: inconsistent qfbcompraw t_QFB , t_QFB.
The library syntax is
| |
qfbcornacchia(d, n) | |
Solves the equation x2 + dy2 = n in integers x and y, where
d > 0 and n is prime. Returns the empty vector
This function is a special case of
? qfbcornacchia(1, 113) %1 = [8, 7] ? qfbsolve(Qfb(1,0,1), 113) %2 = [8, 7] ? qfbcornacchia(1, 4*113) \\ misses the non-primitive solution 2*[8,7] %3 = [] ? qfbcornacchia(1, 4*109) \\ finds a non-primitive solution %4 = [20, 6] ? p = 122838793181521; isprime(p) %5 = 1 ? qfbcornacchia(24, p) %6 = [10547339, 694995] ? Q = Qfb(1,0,24); qfbsolve(Q,p) %7 = [10547339, 694995] ? for (i=1, 10^5, qfbsolve(Q, p)) time = 345 ms. ? for (i=1, 10^5, qfbcornacchia(24,p)) \\ faster time = 251 ms. ? for (i=1, 10^5, qfbsolve(Q, Mat([p,1]))) \\ just as fast time = 251 ms.
We used
The library syntax is
| |
qfbhclassno(x) | |
Hurwitz class number of x, when
x is nonnegative and congruent to 0 or 3 modulo 4, and 0 for other
values. For x > 5.105, we assume the GRH, and use
? qfbhclassno(1) \\ not 0 or 3 mod 4 %1 = 0 ? qfbhclassno(3) %2 = 1/3 ? qfbhclassno(4) %3 = 1/2 ? qfbhclassno(23) %4 = 3
The library syntax is
| |
qfbnucomp(x, y, L) | |
composition of the primitive positive
definite binary quadratic forms x and y (type The current implementation is slower than the generic routine for small D, and becomes faster when D has about 45 bits.
The library syntax is
| |
qfbnupow(x, n, {L}) | |
n-th power of the primitive positive definite
binary quadratic form x using Shanks's NUCOMP and NUDUPL algorithms;
if set, L should be equal to The current implementation is slower than the generic routine for small discriminant D, and becomes faster for D ~ 245.
The library syntax is
| |
qfbpow(x, n) | |
n-th power of the binary quadratic form
x, computed with reduction (i.e. using
The library syntax is
| |
qfbpowraw(x, n) | |
n-th power of the binary quadratic form
x, computed without doing any reduction (i.e. using
The library syntax is
| |
qfbprimeform(x, p) | |
Prime binary quadratic form of discriminant
x whose first coefficient is p, where |p| is a prime number.
By abuse of notation,
p = ± 1 is also valid and returns the unit form. Returns an
error if x is not a quadratic residue mod p, or if x < 0 and p < 0.
(Negative definite
The library syntax is
| |
qfbred(x, {flag = 0}, {isd}, {sd}) | |
Reduces the binary quadratic form x (updating Shanks's distance function d if x = [q,d] is an extended indefinite form). If flag is 1, the function performs a single reduction step, and a complete reduction otherwise. The arguments isd, sd, if present, supply the values of floor{sqrt{D}}, and sqrt{D} respectively, where D is the discriminant (this is not checked). If d < 0 these values are useless.
The library syntax is
| |
qfbredsl2(x, {isD}) | |
Reduction of the (real or imaginary) binary quadratic form x, returns
[y,g] where y is reduced and g in SL(2,ℤ) is such that
g.x = y; isD, if
present, must be equal to
The action of g on x can be computed using
? q1 = Qfb(33947,-39899,11650); ? [q2,U] = qfbredsl2(q1) %2 = [Qfb(749,2207,-1712),[-1,3;-2,5]] ? qfeval(q1,U) %3 = Qfb(749,2207,-1712)
The library syntax is
| |
qfbsolve(Q, n, {flag = 0}) | |
Solve the equation Q(x,y) = n in coprime integers x and y (primitive solutions), where Q is a binary quadratic form and n an integer, up to the action of the special orthogonal group G = SO(Q,ℤ), which is isomorphic to the group of units of positive norm of the quadratic order of discriminant D = disc Q. If D > 0, G is infinite. If D < -4, G is of order 2, if D = -3, G is of order 6 and if D = -4, G is of order 4. Binary digits of flag mean: 1: return all solutions if set, else a single solution; return [] if a single solution is wanted (bit unset) but none exist. 2: also include imprimitive solutions. When flag = 2 (return a single solution, possibly imprimitive), the algorithm returns a solution with minimal content; in particular, a primitive solution exists if and only if one is returned.
The integer n can also be given by its factorization matrix
? qfbsolve(Qfb(1,0,2), 603) \\ a single primitive solution %1 = [5, 17] ? qfbsolve(Qfb(1,0,2), 603, 1) \\ all primitive solutions %2 = [[5, 17], [-19, -11], [19, -11], [5, -17]] ? qfbsolve(Qfb(1,0,2), 603, 2) \\ a single, possibly imprimitive solution %3 = [5, 17] \\ actually primitive ? qfbsolve(Qfb(1,0,2), 603, 3) \\ all solutions %4 = [[5, 17], [-19, -11], [19, -11], [5, -17], [-21, 9], [-21, -9]] ? N = 2^128+1; F = factor(N); ? qfbsolve(Qfb(1,0,1),[N,F],1) %3 = [[-16382350221535464479,8479443857936402504], [18446744073709551616,-1],[-18446744073709551616,-1], [16382350221535464479,8479443857936402504]]
For fixed Q, assuming the factorisation of n is given, the algorithm
runs in probabilistic polynomial time in log p, where p is the largest
prime divisor of n, through the computation of square roots of D modulo
4 p). The dependency on Q is more complicated: polynomial time in log
|D| if Q is imaginary, but exponential time if Q is real (through the
computation of a full cycle of reduced forms). In the latter case, note that
The library syntax is
| |
quadclassunit(D, {flag = 0}, {tech = []}) | |
Buchmann-McCurley's sub-exponential algorithm for computing the class group of a quadratic order of discriminant D. By default, the results are conditional on the GRH.
This function should be used instead of The result is a vector v whose components should be accessed using member functions:
*
*
*
*
*
The flag is obsolete and should be left alone. In older versions,
it supposedly computed the narrow class group when D > 0, but this did not
work at all; use the general function Optional parameter tech is a row vector of the form [c1, c2], where c1 ≤ c2 are nonnegative real numbers which control the execution time and the stack size, see se:GRHbnf. The parameter is used as a threshold to balance the relation finding phase against the final linear algebra. Increasing the default c1 means that relations are easier to find, but more relations are needed and the linear algebra will be harder. The default value for c1 is 0 and means that it is taken equal to c2. The parameter c2 is mostly obsolete and should not be changed, but we still document it for completeness: we compute a tentative class group by generators and relations using a factorbase of prime ideals ≤ c1 (log |D|)2, then prove that ideals of norm ≤ c2 (log |D|)2 do not generate a larger group. By default an optimal c2 is chosen, so that the result is provably correct under the GRH — a result of Grenié and Molteni states that c2 = 23/6 ~ 3.83 is fine (and even c2 = 15/4 ~ 3.75 for large |D| > 2.41 E8). But it is possible to improve on this algorithmically. You may provide a smaller c2, it will be ignored (we use the provably correct one); you may provide a larger c2 than the default value, which results in longer computing times for equally correct outputs (under GRH).
The library syntax is
| |
quaddisc(x) | |
Discriminant of the étale algebra ℚ(sqrt{x}), where x ∈ ℚ*.
This is the same as
? quaddisc(7) %1 = 28 ? quaddisc(-7) %2 = -7
The library syntax is
| |
quadgen(D, {v = 'w}) | |
Creates the quadratic number ω = (a+sqrt{D})/2 where a = 0 if D = 0 mod 4, a = 1 if D = 1 mod 4, so that (1,ω) is an integral basis for the quadratic order of discriminant D. D must be an integer congruent to 0 or 1 modulo 4, which is not a square. If v is given, the variable name is used to display g else 'w' is used.
? w = quadgen(5, 'w); w^2 - w - 1 %1 = 0 ? w = quadgen(0, 'w) *** at top-level: w=quadgen(0) *** ^ — — — - *** quadgen: domain error in quadpoly: issquare(disc) = 1
The library syntax is
When v does not matter, the function
| |
quadhilbert(D) | |
Relative equation defining the Hilbert class field of the quadratic field of discriminant D. If D < 0, uses complex multiplication (Schertz's variant).
If D > 0 Stark units are used and (in rare cases) a
vector of extensions may be returned whose compositum is the requested class
field. See
The library syntax is
| |
quadpoly(D, {v = 'x}) | |
Creates the "canonical" quadratic
polynomial (in the variable v) corresponding to the discriminant D,
i.e. the minimal polynomial of
? quadpoly(5,'y) %1 = y^2 - y - 1 ? quadpoly(0,'y) *** at top-level: quadpoly(0,'y) *** ^ — — — — -- *** quadpoly: domain error in quadpoly: issquare(disc) = 1
The library syntax is
| |
quadray(D, f) | |
Relative equation for the ray
class field of conductor f for the quadratic field of discriminant D
using analytic methods. A For D < 0, uses the σ function and Schertz's method.
For D > 0, uses Stark's conjecture, and a vector of relative equations may be
returned. See
The library syntax is
| |
quadregulator(D) | |
Regulator of the quadratic order of positive discriminant D in time
Õ(D1/2) using the continued fraction algorithm. Raise
an error if D is not a discriminant (fundamental or not) or if D is a
square. The function
The library syntax is
| |
quadunit(D, {v = 'w}) | |
A fundamental unit u of the real quadratic order
of discriminant D. The integer D must be congruent to 0 or 1 modulo 4
and not a square; the result is a quadratic number (see Section se:quadgen).
If D is not a fundamental discriminant, the algorithm is wasteful: if D =
df2 with d fundamental, it will be faster to compute
If v is given, the variable name is used to display u
else 'w' is used. The algorithm computes the continued fraction
of (1 + sqrt{D}) / 2 or sqrt{D}/2 (see GTM 138, algorithm 5.7.2).
Although the continued fraction length is only O(sqrt{D}),
the function still runs in time Õ(D), in part because the
output size is not polynomially bounded in terms of log D.
See
The library syntax is
When v does not matter, the function
| |
quadunitindex(D, f) | |
Given a fundamental discriminant D, returns the index of the unit group
of the order of conductor f in the units of ℚ(sqrt{D}). This function
uses the continued fraction algorithm and has O(D1/2 + ϵ
fϵ) complexity;
? quadunitindex(-3, 2) %1 = 3 ? quadunitindex(5, 2^32) \\ instantaneous %2 = 3221225472 ? quadregulator(5 * 2^64) / quadregulator(5) time = 3min, 1,488 ms. %3 = 3221225472.0000000000000000000000000000
The conductor f can be given in factored form or as
[f,
? quadunitindex(5, [100, [2,2;5,2]]) %4 = 150 ? quadunitindex(5, 100) %5 = 150 ? quadunitindex(5, [2,2;5,2]) %6 = 150 If D is not fundamental, the result is undefined; you may use the following script instead:
index(d, f) = { my([D,F] = coredisc(d, 1)); quadunitindex(D, f * F) / quadunitindex(D, F) } ? index(5 * 10^2, 10) %7 = 10
The library syntax is
| |
quadunitnorm(D) | |
Returns the norm (1 or -1) of the fundamental unit of the quadratic
order of discriminant D. The integer D must be congruent to 0 or 1
modulo 4 and not a square. This is of course equal to
? quadunitnorm(-3) \\ the result is always 1 in the imaginary case %1 = 1 ? quadunitnorm(5) %2 = -1 ? quadunitnorm(17345) %3 = -1 ? u = quadunit(17345) %4 = 299685042291 + 4585831442*w ? norm(u) %5 = -1
This function computes the parity of the continued fraction
expansion and runs in time Õ(D1/2). If D is fundamental,
the function
Important remark. Assuming GRH, using
? GRHunitnorm(bnf) = vecprod(bnfsignunit(bnf)[,1]) ? bnf = bnfinit(x^2 - 17345, 1); GRHunitnorm(bnf) %2 = -1 ? bnf = bnfinit(x^2 - nextprime(2^60), 1); GRHunitnorm(bnf) time = 119 ms. %3 = -1 ? quadunitnorm(nextprime(2^60)) time = 24,086 ms. %4 = -1 Note that if the result is -1, it is unconditional because (if GRH is false) it could happen that our tentative fundamental unit in bnf is actually a power uk of the true fundamental unit, but we would still have Norm(u) = -1 (and k odd). We can also remove the GRH assumption when the result is 1 with a little more work:
? v = bnfunits(bnf)[1][1] \\ a unit in factored form ? v[,2] %= 2; ? nfeltissquare(bnf, nffactorback(bnf, v)) %7 = 0
Under GRH, we know that v is the fundamental unit, but as
above it can be a power uk of the true fundamental unit u. But the
final two lines prove that v is not a square, hence k is odd and
Norm(u) must also be 1. We modified the factorization matrix
giving v by reducing all exponents modulo 2: this allows to computed
The library syntax is
| |
ramanujantau(n, {ell = 12}) | |
Compute the value of Ramanujan's tau function at an individual n,
assuming the truth of the GRH (to compute quickly class numbers of imaginary
quadratic fields using
If all values up to N are required, then
∑ τ(n)qn = q ∏n ≥ 1 (1-qn)24
and more generally, setting u = ℓ - 13 and C = 2/ζ(-u) for ℓ
> 12,
∑τℓ(n)qn = q ∏n ≥ 1
(1-qn)24 ( 1 + C∑n ≥ 1nu qn / (1-qn))
produces them in time Õ(N), against Õ(N3/2) for
individual calls to
? tauvec(N) = Vec(q*eta(q + O(q^N))^24); ? N = 10^4; v = tauvec(N); time = 26 ms. ? ramanujantau(N) %3 = -482606811957501440000 ? w = vector(N, n, ramanujantau(n)); \\ much slower ! time = 13,190 ms. ? v == w %4 = 1
The library syntax is
| |
randomprime({N = 231}, {q}) | |
Returns a strong pseudo prime (see
? randomprime(100) %1 = 71 ? randomprime([3,100]) %2 = 61 ? randomprime([1,1]) *** at top-level: randomprime([1,1]) *** ^ — — — — — — *** randomprime: domain error in randomprime: *** floor(b) - max(ceil(a),2) < 0 ? randomprime([24,28]) \\ infinite loop If the optional parameter q is an integer, return a prime congruent to 1 mod q; if q is an intmod, return a prime in the given congruence class. If the class contains no prime in the given interval, the function will raise an exception if the class is not invertible, else run into an infinite loop
? randomprime(100, 4) \\ 1 mod 4 %1 = 71 ? randomprime(100, 4) %2 = 13 ? randomprime([10,100], Mod(2,5)) %3 = 47 ? randomprime(100, Mod(0,2)) \\ silly but works %4 = 2 ? randomprime([3,100], Mod(0,2)) \\ not invertible *** at top-level: randomprime([3,100],Mod(0,2)) *** ^ — — — — — — — — — -- *** randomprime: elements not coprime in randomprime: 0 2 ? randomprime(100, 97) \\ infinite loop
The library syntax is
| |
removeprimes({x = []}) | |
Removes the primes listed in x from
the prime number table. In particular
The library syntax is
| |
sigma(x, {k = 1}) | |
Sum of the k-th powers of the positive divisors of |x|. x and k must be of type integer.
The library syntax is
| |
sqrtint(x, {&r}) | |
Returns the integer square root of x, i.e. the largest integer y such that y2 ≤ x, where x a nonnegative real number. If r is present, set it to the remainder r = x - y2, which satisfies 0 ≤ r < 2y + 1. Further, when x is an integer, r is an integer satisfying 0 ≤ r ≤ 2y.
? x = 120938191237; sqrtint(x) %1 = 347761 ? sqrt(x) %2 = 347761.68741970412747602130964414095216 ? y = sqrtint(x, &r); r %3 = 478116 ? x - y^2 %4 = 478116 ? sqrtint(9/4, &r) \\ not 3/2 ! %5 = 1 ? r %6 = 5/4
The library syntax is
| |
sqrtnint(x, n) | |
Returns the integer n-th root of x, i.e. the largest integer y such that yn ≤ x, where x is a nonnegative real number.
? N = 120938191237; sqrtnint(N, 5) %1 = 164 ? N^(1/5) %2 = 164.63140849829660842958614676939677391 ? sqrtnint(Pi^2, 3) %3 = 2
The special case n = 2 is
The library syntax is
| |
sumdedekind(h, k) | |
Returns the Dedekind sum attached to the integers h and k, corresponding to a fast implementation of
s(h,k) = sum(n = 1, k-1, (n/k)*(frac(h*n/k) - 1/2))
The library syntax is
| |
sumdigits(n, {B = 10}) | |
Sum of digits in the integer n, when written in base B.
? sumdigits(123456789) %1 = 45 ? sumdigits(123456789, 2) %2 = 16 ? sumdigits(123456789, -2) %3 = 15
Note that the sum of bits in n is also returned by
The library syntax is
| |
znchar(D) | |
Given a datum D describing a group (ℤ/Nℤ)* and a Dirichlet
character χ, return the pair The following possibilities for D are supported
* a nonzero
* a
* a modular form space as per
In the remaining cases,
* a pair
* a pair
? [G,chi] = znchar(-3); ? G.cyc %2 = [2] ? chareval(G, chi, 2) %3 = 1/2 ? kronecker(-3,2) %4 = -1 ? znchartokronecker(G,chi) %5 = -3 ? mf = mfinit([28, 5/2, Mod(2,7)]); [f] = mfbasis(mf); ? [G,chi] = znchar(mf); [G.mod, chi] %7 = [7, [2]~] ? [G,chi] = znchar(f); chi %8 = [28, [0, 2]~]
The library syntax is
| |
zncharconductor(G, chi) | |
Let G be attached to (ℤ/qℤ)* (as per
? G = znstar(126000, 1); ? zncharconductor(G,11) \\ primitive %2 = 126000 ? zncharconductor(G,1) \\ trivial character, not primitive! %3 = 1 ? zncharconductor(G,1009) \\ character mod 5^3 %4 = 125
The library syntax is
| |
znchardecompose(G, chi, Q) | |
Let N = ∏p pep and a Dirichlet character χ, we have a decomposition χ = ∏p χp into character modulo N where the conductor of χp divides pep; it equals pep for all p if and only if χ is primitive.
Given a znstar G describing a group (ℤ/Nℤ)*, a Dirichlet
character
? G = znstar(40, 1); ? G.cyc %2 = [4, 2, 2] ? chi = [2, 1, 1]; ? chi2 = znchardecompose(G, chi, 2) %4 = [1, 1, 0]~ ? chi5 = znchardecompose(G, chi, 5) %5 = [0, 0, 2]~ ? znchardecompose(G, chi, 3) %6 = [0, 0, 0]~ ? c = charmul(G, chi2, chi5) %7 = [1, 1, 2]~ \\ t_COL: in terms of Conrey generators ! ? znconreychar(G,c) %8 = [2, 1, 1] \\ t_VEC: in terms of SNF generators
The library syntax is
| |
znchargauss(G, chi, {a = 1}) | |
Given a Dirichlet character χ on G = (ℤ/Nℤ)* (see
? [G,chi] = znchar(-3); \\ quadratic Gauss sum: I*sqrt(3) ? znchargauss(G,chi) %2 = 1.7320508075688772935274463415058723670*I ? [G,chi] = znchar(5); ? znchargauss(G,chi) \\ sqrt(5) %2 = 2.2360679774997896964091736687312762354 ? G = znstar(300,1); chi = [1,1,12]~; ? znchargauss(G,chi) / sqrt(300) - exp(2*I*Pi*11/25) \\ = 0 %4 = 2.350988701644575016 E-38 + 1.4693679385278593850 E-39*I ? lfuntheta([G,chi], 1) \\ = 0 %5 = -5.79[...] E-39 - 2.71[...] E-40*I
The library syntax is
| |
zncharinduce(G, chi, N) | |
Let G be attached to (ℤ/qℤ)* (as per
* a
* a
Let N be a multiple of q, return the character modulo N extending
? G = znstar(4, 1); ? chi = znconreylog(G,1); \\ trivial character mod 4 ? zncharinduce(G, chi, 80) \\ now mod 80 %3 = [0, 0, 0]~ ? zncharinduce(G, 1, 80) \\ same using directly Conrey label %4 = [0, 0, 0]~ ? G2 = znstar(80, 1); ? zncharinduce(G, 1, G2) \\ same %4 = [0, 0, 0]~ ? chi = zncharinduce(G, 3, G2) \\ extend the nontrivial character mod 4 %5 = [1, 0, 0]~ ? [G0,chi0] = znchartoprimitive(G2, chi); ? G0.mod %7 = 4 ? chi0 %8 = [1]~ Here is a larger example:
? G = znstar(126000, 1); ? label = 1009; ? chi = znconreylog(G, label) %3 = [0, 0, 0, 14, 0]~ ? [G0,chi0] = znchartoprimitive(G, label); \\ works also with 'chi' ? G0.mod %5 = 125 ? chi0 \\ primitive character mod 5^3 attached to chi %6 = [14]~ ? G0 = znstar(N0, 1); ? zncharinduce(G0, chi0, G) \\ induce back %8 = [0, 0, 0, 14, 0]~ ? znconreyexp(G, %) %9 = 1009
The library syntax is
| |
zncharisodd(G, chi) | |
Let G be attached to (ℤ/Nℤ)* (as per
* a
* a
Return 1 if and only if
? G = znstar(8, 1); ? zncharisodd(G, 1) \\ trivial character %2 = 0 ? zncharisodd(G, 3) %3 = 1 ? chareval(G, 3, -1) %4 = 1/2
The library syntax is
| |
znchartokronecker(G, chi, {flag = 0}) | |
Let G be attached to (ℤ/Nℤ)* (as per
* a
* a
If flag = 0, return the discriminant D if If flag = 1, return the fundamental discriminant attached to the corresponding primitive character.
? G = znstar(8,1); CHARS = [1,3,5,7]; \\ Conrey labels ? apply(t->znchartokronecker(G,t), CHARS) %2 = [4, -8, 8, -4] ? apply(t->znchartokronecker(G,t,1), CHARS) %3 = [1, -8, 8, -4]
The library syntax is
| |
znchartoprimitive(G, chi) | |
Let G be attached to (ℤ/qℤ)* (as per
? G = znstar(126000, 1); ? [G0,chi0] = znchartoprimitive(G,11) ? G0.mod %3 = 126000 ? chi0 %4 = 11 ? [G0,chi0] = znchartoprimitive(G,1);\\ trivial character, not primitive! ? G0.mod %6 = 1 ? chi0 %7 = []~ ? [G0,chi0] = znchartoprimitive(G,1009) ? G0.mod %4 = 125 ? chi0 %5 = [14]~
Note that
The library syntax is
| |
znconreychar(G, m) | |
Given a znstar G attached to (ℤ/qℤ)* (as per
Let q = ∏p pep be the factorization of q into distinct primes. For all odd p with ep > 0, let gp be the element in (ℤ/qℤ)* which is * congruent to 1 mod q/pep, * congruent mod pep to the smallest positive integer that generates (ℤ/p2ℤ)*. For p = 2, we let g4 (if 2e2 ≥ 4) and g8 (if furthermore (2e2 ≥ 8) be the elements in (ℤ/qℤ)* which are * congruent to 1 mod q/2e2, * g4 = -1 mod 2e2, * g8 = 5 mod 2e2.
Then the gp (and the extra g4 and g8 if 2e2 ≥ 2) are
independent generators of (ℤ/qℤ)*, i.e. every m in (ℤ/qℤ)*
can be written uniquely as ∏p gpmp, where mp is defined
modulo the
order op of gp and p ∈ Sq, the set of prime divisors of q
together with 4 if 4 | q and 8 if 8 | q. Note that the gp
are in general not SNF generators as produced by
The Conrey logarithm of m is the vector (mp)p ∈ S_{q}, obtained
via
? G = znstar(8,1); ? G.cyc %2 = [2, 2] \\ Z/2 x Z/2 ? G.gen %3 = [7, 3] ? znconreychar(G,1) \\ 1 is always the trivial character %4 = [0, 0] ? znconreychar(G,2) \\ 2 is not coprime to 8 !!! *** at top-level: znconreychar(G,2) *** ^ — — — — — -- *** znconreychar: elements not coprime in Zideallog: 2 8 *** Break loop: type 'break' to go back to GP prompt break> ? znconreychar(G,3) %5 = [0, 1] ? znconreychar(G,5) %6 = [1, 1] ? znconreychar(G,7) %7 = [1, 0] We indeed get all 4 characters of (ℤ/8ℤ)*. For convenience, we allow to input the Conrey logarithm of m instead of m:
? G = znstar(55, 1); ? znconreychar(G,7) %2 = [7, 0] ? znconreychar(G, znconreylog(G,7)) %3 = [7, 0]
The library syntax is
| |
znconreyconductor(G, chi, {&chi0}) | |
Let G be attached to (ℤ/qℤ)* (as per
* a
* a
Return the conductor of
If
? G = znstar(126000, 1); ? znconreyconductor(G,11) \\ primitive %2 = 126000 ? znconreyconductor(G,1) \\ trivial character, not primitive! %3 = [1, matrix(0,2)] ? N0 = znconreyconductor(G,1009, &chi0) \\ character mod 5^3 %4 = [125, Mat([5, 3])] ? chi0 %5 = [14]~ ? G0 = znstar(N0, 1); \\ format [N,factor(N)] accepted ? znconreyexp(G0, chi0) %7 = 9 ? znconreyconductor(G0, chi0) \\ now primitive, as expected %8 = 125
The group
The library syntax is
| |
znconreyexp(G, chi) | |
Given a znstar G attached to (ℤ/qℤ)* (as per
The character chi is given either as a
*
*
? G = znstar(126000, 1) ? znconreylog(G,1) %2 = [0, 0, 0, 0, 0]~ ? znconreyexp(G,%) %3 = 1 ? G.cyc \\ SNF generators %4 = [300, 12, 2, 2, 2] ? chi = [100, 1, 0, 1, 0]; \\ some random character on SNF generators ? znconreylog(G, chi) \\ in terms of Conrey generators %6 = [0, 3, 3, 0, 2]~ ? znconreyexp(G, %) \\ apply to a Conrey log %7 = 18251 ? znconreyexp(G, chi) \\ ... or a char on SNF generators %8 = 18251 ? znconreychar(G,%) %9 = [100, 1, 0, 1, 0]
The library syntax is
| |
znconreylog(G, m) | |
Given a znstar attached to (ℤ/qℤ)* (as per
Let q = ∏p pep be the factorization of q into distinct primes, where we assume e2 = 0 or e2 ≥ 2. (If e2 = 1, we can ignore 2 from the factorization, as if we replaced q by q/2, since (ℤ/qℤ)* ~ (ℤ/(q/2)ℤ)*.) For all odd p with ep > 0, let gp be the element in (ℤ/qℤ)* which is * congruent to 1 mod q/pep, * congruent mod pep to the smallest positive integer that generates (ℤ/p2ℤ)*. For p = 2, we let g4 (if 2e2 ≥ 4) and g8 (if furthermore (2e2 ≥ 8) be the elements in (ℤ/qℤ)* which are * congruent to 1 mod q/2e2, * g4 = -1 mod 2e2, * g8 = 5 mod 2e2.
Then the gp (and the extra g4 and g8 if 2e2 ≥ 2) are
independent generators of ℤ/qℤ*, i.e. every m in (ℤ/qℤ)* can be
written uniquely as ∏p gpmp, where mp is defined modulo
the order op of gp and p ∈ Sq, the set of prime divisors of
q together with 4 if 4 | q and 8 if 8 | q. Note that the
gp
are in general not SNF generators as produced by
The Conrey logarithm of m is the vector (mp)p ∈ S_{q}. The inverse
function
? G = znstar(126000, 1); ? znconreylog(G,1) %2 = [0, 0, 0, 0, 0]~ ? znconreyexp(G, %) %3 = 1 ? znconreylog(G,2) \\ 2 is not coprime to modulus !!! *** at top-level: znconreylog(G,2) *** ^ — — — — — -- *** znconreylog: elements not coprime in Zideallog: 2 126000 *** Break loop: type 'break' to go back to GP prompt break> ? znconreylog(G,11) \\ wrt. Conrey generators %4 = [0, 3, 1, 76, 4]~ ? log11 = ideallog(,11,G) \\ wrt. SNF generators %5 = [178, 3, -75, 1, 0]~
For convenience, we allow to input the ordinary discrete log of m,
? znconreylog(G, log11) %7 = [0, 3, 1, 76, 4]~
We also allow a character (
? G.cyc %8 = [300, 12, 2, 2, 2] ? chi = [10,1,0,1,1]; ? znconreylog(G, chi) %10 = [1, 3, 3, 10, 2]~ ? n = znconreyexp(G, chi) %11 = 84149 ? znconreychar(G, n) %12 = [10, 1, 0, 1, 1]
The library syntax is
| |
zncoppersmith(P, N, X, {B = N}) | |
Coppersmith's algorithm. N being an integer and P ∈ ℤ[t], finds in polynomial time in log(N) and d = deg(P) all integers x with |x| ≤ X such that gcd(N, P(x)) ≥ B. This is a famous application of the LLL algorithm meant to help in the factorization of N. Notice that P may be reduced modulo Nℤ[t] without affecting the situation. The parameter X must not be too large: assume for now that the leading coefficient of P is coprime to N, then we must have d log X log N < log2 B, i.e., X < N1/d when B = N. Let now P0 be the gcd of the leading coefficient of P and N. In applications to factorization, we should have P0 = 1; otherwise, either P0 = N and we can reduce the degree of P, or P0 is a non trivial factor of N. For completeness, we nevertheless document the exact conditions that X must satisfy in this case: let p := logN P0, b := logN B, x := logN X, then * either p ≥ d / (2d-1) is large and we must have x d < 2b - 1; * or p < d / (2d-1) and we must have both p < b < 1 - p + p/d and x(d + p(1-2d)) < (b - p)2. Note that this reduces to x d < b2 when p = 0, i.e., the condition described above.
Some x larger than X may be returned if you are
very lucky. The routine runs in polynomial time in log N and d
but the smaller B, or the larger X, the slower.
The strength of Coppersmith method is the ability to find roots modulo a
general composite N: if N is a prime or a prime power,
We shall now present two simple applications. The first one is finding nontrivial factors of N, given some partial information on the factors; in that case B must obviously be smaller than the largest nontrivial divisor of N.
setrand(1); \\ to make the example reproducible [a,b] = [10^30, 10^31]; D = 20; p = randomprime([a,b]); q = randomprime([a,b]); N = p*q; \\ assume we know 0) p | N; 1) p in [a,b]; 2) the last D digits of p p0 = p % 10^D; ? L = zncoppersmith(10^D*x + p0, N, b \ 10^D, a) time = 1ms. %6 = [738281386540] ? gcd(L[1] * 10^D + p0, N) == p %7 = 1 and we recovered p, faster than by trying all possibilities x < 1011. The second application is an attack on RSA with low exponent, when the message x is short and the padding P is known to the attacker. We use the same RSA modulus N as in the first example:
setrand(1); P = random(N); \\ known padding e = 3; \\ small public encryption exponent X = floor(N^0.3); \\ N^(1/e - epsilon) x0 = random(X); \\ unknown short message C = lift( (Mod(x0,N) + P)^e ); \\ known ciphertext, with padding P zncoppersmith((P + x)^3 - C, N, X) \\ result in 244ms. %14 = [2679982004001230401] ? %[1] == x0 %15 = 1 We guessed an integer of the order of 1018, almost instantly.
The library syntax is
| |
znlog(x, g, {o}) | |
This functions allows two distinct modes of operation depending on g:
* if g is the output of * else g is an explicit element in (ℤ/Nℤ)*, we compute the discrete logarithm of x in (ℤ/Nℤ)* in base g. The rest of this entry describes the latter possibility. The result is [] when x is not a power of g, though the function may also enter an infinite loop in this case.
If present, o represents the multiplicative order of g, see
Section se:DLfun; the preferred format for this parameter is
? p = nextprime(10^4); g = znprimroot(p); o = [p-1, factor(p-1)]; ? for(i=1,10^4, znlog(i, g, o)) time = 163 ms. ? for(i=1,10^4, znlog(i, g)) time = 200 ms. \\ a little slower The result is undefined if g is not invertible mod N or if the supplied order is incorrect. This function uses * a combination of generic discrete log algorithms (see below). * in (ℤ/Nℤ)* when N is prime: a linear sieve index calculus method, suitable for N < 1050, say, is used for large prime divisors of the order. The generic discrete log algorithms are: * Pohlig-Hellman algorithm, to reduce to groups of prime order q, where q | p-1 and p is an odd prime divisor of N, * Shanks baby-step/giant-step (q < 232 is small), * Pollard rho method (q > 232). The latter two algorithms require O(sqrt{q}) operations in the group on average, hence will not be able to treat cases where q > 1030, say. In addition, Pollard rho is not able to handle the case where there are no solutions: it will enter an infinite loop.
? g = znprimroot(101) %1 = Mod(2,101) ? znlog(5, g) %2 = 24 ? g^24 %3 = Mod(5, 101) ? G = znprimroot(2 * 101^10) %4 = Mod(110462212541120451003, 220924425082240902002) ? znlog(5, G) %5 = 76210072736547066624 ? G^% == 5 %6 = 1 ? N = 2^4*3^2*5^3*7^4*11; g = Mod(13, N); znlog(g^110, g) %7 = 110 ? znlog(6, Mod(2,3)) \\ no solution %8 = [] For convenience, g is also allowed to be a p-adic number:
? g = 3+O(5^10); znlog(2, g) %1 = 1015243 ? g^% %2 = 2 + O(5^10)
The library syntax is
| |
znorder(x, {o}) | |
x must be an integer mod n, and the
result is the order of x in the multiplicative group (ℤ/nℤ)*. Returns
an error if x is not invertible.
The parameter o, if present, represents a nonzero
multiple of the order of x, see Section se:DLfun; the preferred format for
this parameter is
The library syntax is
| |
znprimroot(n) | |
Returns a primitive root (generator) of (ℤ/nℤ)*, whenever this latter group is cyclic (n = 4 or n = 2pk or n = pk, where p is an odd prime and k ≥ 0). If the group is not cyclic, the function will raise an exception. If n is a prime power, then the smallest positive primitive root is returned. This may not be true for n = 2pk, p odd. Note that this function requires factoring p-1 for p as above, in order to determine the exact order of elements in (ℤ/nℤ)*: this is likely to be costly if p is large.
The library syntax is
| |
znstar(n, {flag = 0}) | |
Gives the structure of the multiplicative group (ℤ/nℤ)*. The output G depends on the value of flag:
* flag = 0 (default), an abelian group structure [h,d,g],
where h = φ(n) is the order (
* flag = 1 the result is a
? G = znstar(40) %1 = [16, [4, 2, 2], [Mod(17, 40), Mod(21, 40), Mod(11, 40)]] ? G.no \\ eulerphi(40) %2 = 16 ? G.cyc \\ cycle structure %3 = [4, 2, 2] ? G.gen \\ generators for the cyclic components %4 = [Mod(17, 40), Mod(21, 40), Mod(11, 40)] ? apply(znorder, G.gen) %5 = [4, 2, 2]
For user convenience, we define
The library syntax is
| |
znsubgroupgenerators(H, {flag = 0}) | |
Finds a minimal set of generators for the subgroup of (ℤ/fℤ)*
given by a vector (or vectorsmall) H of length f:
for 1 ≤ a ≤ f,
? G = znstar(f, 1); ? v = znsubgroupgenerators(H); ? subHNF(G, v) = mathnfmodid(Mat([znlog(h, G) | h<-v]), G.cyc);
The function For example, if H = {1,4,11,14} ⊂ (ℤ/15ℤ)×, then we have
? f = 15; H = vector(f); H[1]=H[4]=H[11]=H[14] = 1; ? v = znsubgroupgenerators(H) %2 = [4, 11] ? G = znstar(f, 1); G.cyc %3 = [4, 2] ? subHNF(G, v) %4 = [2 0] [0 1] ? subHNF(G, [1,4,11,14]) %5 = [2 0] [0 1]
This function is mostly useful when f is large
and H has small index: if H has few elements, one may just use
HK(m, p, flag = 0)= { my(d = quaddisc(m), f = lcm(d, p), H); H = vectorsmall(f, a, a % p == 1 && kronecker(d,a) > 0); [f, znsubgroupgenerators(H,flag)]; } ? [f, v] = HK(36322, 5) time = 193 ms. %1 = [726440, [41, 61, 111, 131]] ? G = znstar(f,1); G.cyc %2 = [1260, 12, 2, 2, 2, 2] ? A = subHNF(G, v) %3 = [2 0 1 1 0 1] [0 4 0 0 0 2] [0 0 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] \\ Double check ? p = 5; d = quaddisc(36322); ? w = select(a->a % p == 1 && kronecker(d,a) > 0, [1..f]); #w time = 133 ms. %5 = 30240 \\ w enumerates the elements of H ? subHNF(G, w) == A \\ same result, about twice slower time = 242 ms. %6 = 1
This shows that K = ℚ(sqrt{36322},ζ5) is contained in
ℚ(ζ726440) and H =
? HK(36322, 5, 1) %3 = [726440, [41, 31261, 324611, 506221]]
This time
H =
The library syntax is
| |