| Pari/GP Reference Documentation | Contents
- Global index
- GP keyboard shortcuts |
| Algebraic numbers and ideals Class group, units, and the GRH Extended ideals Member functions available for nf, bnf and bnr structures Number fields structures bnfcertify bnfdecodemodule bnfinit bnfisintnorm bnfisnorm bnfisprincipal bnfissunit bnfisunit bnflog bnflogdegree bnflogef bnfnarrow bnfsignunit bnfsunit bnfunits dirzetak factornf idealadd idealaddtoone idealappr idealchinese idealcoprime idealdiv idealdown idealfactor idealfactorback idealfrobenius idealfromgens idealhnf idealintersect idealinv idealismaximal idealispower ideallist ideallistarch ideallog idealmin idealmul idealnorm idealnumden idealpow idealprimedec idealprincipalunits idealramgroups idealred idealredmodpower idealstar idealtwoelt idealval matalgtobasis matbasistoalg modreverse newtonpoly nfalgtobasis nfbasis nfbasistoalg nfcertify nfcompositum nfdisc nfdiscfactors nfeltadd nfeltdiv nfeltdiveuc nfeltdivmodpr nfeltdivrem nfeltembed nfeltispower nfeltissquare nfeltmod nfeltmul nfeltmulmodpr nfeltnorm nfeltpow nfeltpowmodpr nfeltreduce nfeltreducemodpr nfeltsign nfelttrace nfeltval nffactor nffactorback nffactormod nfgaloisapply nfgaloisconj nfhilbert nfinit nfisideal nfisincl nfisisom nfislocalpower nfkermodpr nfmodpr nfmodprinit nfmodprlift nfnewprec nfpolsturm nfroots nfrootsof1 nfsolvemodpr nfsplitting nfsubfields nfsubfieldscm nfsubfieldsmax nfweilheight polcompositum polgalois polred polredabs polredbest polredord poltschirnhaus rnfpolredabs rnfpolredbest rnfpseudobasis rnfsteinitz subgrouplist | |
|
This section introduces functions related to the arithmetic of general number fields. Functions specific to quadratic number fields are found in Section se:arithmetic (Arithmetic functions); functions related to Galois theory and class field theory are found in Section se:CFT; functions related to relative extensions are found in Section se:rnf
| |
| Number fields structures |
![]() |
|
Let K = ℚ[X] / (T) be a number field, where T ∈ ℤ[X] is monic, and let ℤK be its ring of integers. Three basic number field structures can be attached to K in GP:
* nf denotes a number field, i.e. a data structure output by
* bnf denotes a "Buchmann's number field", i.e. a
data structure output by
* bnr denotes a "ray number field", i.e. a data structure
output by
Functions related to these structures, share the prefix
| |
| Class group, units, and the GRH |
![]() |
|
The
Important warning. Any of the class number, class group
structure, class group generators, regulator and fundamental units may be
wrong, independently of each other. And the same holds for ray class groups
and S-units. The only guarantee is that the units given generate a
subgroup of finite index in the full unit group. You must use
Since this requires exponential time, we recomend to
compute as far as possible with provisional data then come back to certify
what is really needed. A good example is the
| |
| Member functions available for nf, bnf and bnr structures |
![]() |
|
GP provides "member functions" to retrieve data from structures (once they have been initialized of course). The relevant types of number fields are indicated between parentheses:
The member functions
For instance, assume that bnf =
| |
| Algebraic numbers and ideals |
![]() |
|
An algebraic number belonging to K = ℚ[X]/(T) is given as
* a
* a
* a
Functions to manipulate elements in a number field share the
prefix An ideal is given in any of the following ways: * an algebraic number in one of the above forms, defining a principal ideal.
* a prime ideal, as output by
* a
One may use
| |
| Extended ideals |
![]() |
|
An extended ideal is a 2-component
vector [A, t], where A is an ideal as above and t is an algebraic
number. It represent the ideal (t)A. This is useful whenever
The "principal part" t in an extended ideal may be
represented in any of the above forms. Additionally, and this is the
preferred form, as a factorization
matrix, or famat. Such factorizations (in terms of number field
elements, not ideals!) can be multiplied in a formal way (generators merged,
exponents added), corresponding to the multiplication in K.
The empty factorization matrix
When t is such a factorization matrix, elements stay in factored form,
which is a convenient way to avoid coefficient explosion. To recover the
conventional expanded form, try
| |
| bnfcertify(bnf, {flag = 0}) |
![]() |
bnf being as output by
? K = bnfinit(x^3+2^2^3+1); bnfcertify(K)
*** at top-level: K=bnfinit(x^3+2^2^3+1);bnfcertify(K)
*** ^ — — — — -
*** bnfcertify: precision too low in makeunits [use bnfinit(,1)].
? K = bnfinit(x^3+2^2^3+1, 1); \\ include units
? bnfcertify(K)
%3 = 1
If flag is present, only certify that the class group is a quotient of the one computed in bnf (much simpler in general); likewise, the computed units may form a subgroup of the full unit group. In this variant, the units are no longer needed:
? K = bnfinit(x^3+2^2^3+1); bnfcertify(K, 1) %4 = 1
The library syntax is
| |
| bnfdecodemodule(nf, m) |
![]() |
If m is a module as output in the
first component of an extension given by
? K = bnfinit(x^2+23); L = bnrdisclist(K, 10); s = L[2]
%1 = [[[Vecsmall([8]), Vecsmall([1])], [[0, 0, 0]]],
[[Vecsmall([9]), Vecsmall([1])], [[0, 0, 0]]]]
? bnfdecodemodule(K, s[1][1])
%2 =
[2 0]
[0 1]
? bnfdecodemodule(K,s[2][1])
%3 =
[2 1]
[0 1]
The library syntax is
| |
| bnfinit(P, {flag = 0}, {tech = []}) |
![]() |
Initializes a This implements Buchmann's sub-exponential algorithm for computing the class group, the regulator and a system of fundamental units of the general algebraic number field K defined by the monic irreducible polynomial P with integer coefficients. The meaning of flag is as follows:
* flag = 0 (default). This is the historical behavior, kept for
compatibility reasons and speed. It has severe drawbacks but is likely to be
a little faster than the alternative, twice faster say, so only use it if
speed is paramount, you obtain a useful speed gain for the fields
under consideration, and you are only interested in the field invariants
such as the classgroup structure or its regulator. The computations involve
exact algebraic numbers which are replaced by floating point embeddings for
the sake of speed. If the precision is insufficient,
When flag = 1, we keep an exact algebraic version of all floating point data
and this allows to guarantee that functions using the structure will always
succeed, as well as to compute the fundamental units exactly. The units are
computed in compact form, as a product of small S-units, possibly with
huge exponents. This flag also allows The tech argument (technical).
This argument is better left omitted unless default tuning turns out to be
inadequate and it looks like the algorithm made little progress over
a few hours (or days). This can be diagnosed interactively using
Its format is [c1, c2, nrpid, max_fact, idex, usethr], You do not need to supply all values. However, should you choose to modify a subset, they must be given in the given order, where a 0 encodes "the default value". For example, to specify nrpid = 20 without affecting c1 and c2, you can provide [0,0,20]. Their meaning is as follows * 0 ≤ c1 ≤ c2 are real numbers. For i = 1,2, let Bi = ci(log |dK|)2, and denote by S(B) the set of maximal ideals of K whose norm is less than B. We want S(B1) to generate Cl(K) and hope that S(B2) can be proven to generate Cl(K).
More precisely, S(B1) is a factorbase used to compute a tentative
Cl(K) by generators and relations. We then check, using essentially
When c1 is unspecified (equal to 0) the algorithm takes it equal to c2. User-supplied ci are only used to compute initial guesses for the bounds Bi, and the algorithm increases them until one can prove under GRH that S(B2) generates Cl(K). A uniform result of Grenié and Molteni says that c2 = 4 is always suitable, but this bound is pessimistic and a direct algorithm due to Belabas-Diaz-Friedman, improved by Grenié and Molteni, is used to check the condition, assuming GRH.
If the algorithm does not find enough relations, you may
want to increase c1 and c2 to be larger than the so-called
Bach constant displayed by * nrpid is the maximal number of small norm relations attached to each ideal in the factor base. Set it to -1 to disable the search for small norm relations. Reasonable values are between 4 and 20. The default is 4 (which is also used if nrpid is zero). Increasing this value has seldom much effect, but setting it to -1 can have a large positive or negative effect on the running time. * max_fact is the maximal number of trial factorizations to perform per ideal. There is an inherent trade-off between testing more ideals or testing more elements per ideals. The default is 500 (which is also used if max_fact is zero). If the algorithm does not find enough small norm relations, increase this value. Reasonable values are between 100 and 10000. When using parallelism (see below) it can be reasonable to increase it up to about 106. * idex is the power of the ideal to use. Reasonable values are between 1 and 12. The default is 0, which lets the algorithm picks a small power of the ideal depending on its norm.
* usethr decides whether to use parallelism when searching for
relations. The possible values are 0: no parallelism (default), 1: use
A good strategy is to first try to change idex, then increase max_fact. If this is not sufficient, try to increase c1 and c2. If this causes the search to be too slow, try parallelism. The components of a bnf are technical. In fact: never access a component directly, always use a proper member function. However, for the sake of completeness and internal documentation, their description is as follows. We use the notations explained in the book by H. Cohen, A Course in Computational Algebraic Number Theory, Graduate Texts in Maths 138, Springer-Verlag, 1993, Section 6.5, and subsection 6.5.5 in particular. bnf[1] contains the matrix W, i.e. the matrix in Hermite normal form giving relations for the class group on prime ideal generators (𝔭i)1 ≤ i ≤ r. bnf[2] contains the matrix B, i.e. the matrix containing the expressions of the prime ideal factorbase in terms of the 𝔭i. It is an r x c matrix. bnf[3] contains the complex logarithmic embeddings of the system of fundamental units which has been found. It is an (r1+r2) x (r1+r2-1) matrix. bnf[4] contains the matrix M"C of Archimedean components of the relations of the matrix (W|B). bnf[5] contains the prime factor base, i.e. the list of prime ideals used in finding the relations. bnf[6] contains a dummy 0.
bnf[7] or
bnf[8] is a vector containing the classgroup
bnf[9] is a vector used in
bnf[10] is by default unused and set equal to 0. This field is used
to store further information about the field as it becomes available, which
is rarely needed, hence would be too expensive to compute during the initial
The library syntax is
Also available is
| |
| bnfisintnorm(bnf, b, {flag = 0}) |
![]() |
Computes a complete system of
solutions (modulo units of positive norm) of the absolute norm equation
Norm(a) = b,
where a is an integer in bnf. If bnf has not been certified,
the correctness of the result depends on the validity of GRH.
If (optional) flag is set, allows returning solutions in factored form, which
helps a lot when the fundamental units are large (equivalently, when
? bnf = bnfinit(x^4-2, 1); ? bnfisintnorm(bnf,7) %2 = [-x^2 + x - 1, x^2 + x + 1] ? bnfisintnorm(bnf,-7) %3 = [-x^3 - 1, x^3 + 2*x^2 + 2*x + 1] ? bnf = bnfinit(x^2-2305843005992468481, 1); b = 2305843008139952128; ? bnf.reg \\ fundamental unit is huge %5 = 14054016.227457155120413774802385952043 ? v = bnfisintnorm(bnf, b, 1); #v %7 = 31 \\ succeeds instantly ? s = v[1]; [type(s), matsize(s)] %8 = ["t_MAT", [162, 2]] \\ solution 1 is a product of 162 factors ? exponent(s[,2]) %9 = 22
The exponents have 22 bits, so there is little
hope of writing down the solutions in expanded form. And indeed,
See also
The library syntax is
| |
| bnfisnorm(bnf, x, {flag = 1}) |
![]() |
Tries to tell whether the rational number x is the norm of some element y in bnf. Returns a vector [a,b] where x = Norm(a)*b. Looks for a solution which is an S-unit, with S a certain set of prime ideals containing (among others) all primes dividing x. If bnf is known to be Galois, you may set flag = 0 (in this case, x is a norm iff b = 1). If flag is nonzero the program adds to S the following prime ideals, depending on the sign of flag. If flag > 0, the ideals of norm less than flag. And if flag < 0 the ideals dividing flag. Assuming GRH, the answer is guaranteed (i.e. x is a norm iff b = 1), if S contains all primes less than 4log(disc(Bnf))2, where Bnf is the Galois closure of bnf.
See also
The library syntax is
| |
| bnfisprincipal(bnf, x, {flag = 1}) |
![]() |
bnf being the
number field data output by In particular, x is principal if and only if e is the zero vector. Note that the empty vector, which is returned when the class number is 1, is considered to be a zero vector (of dimension 0).
? K = bnfinit(y^2+23); ? K.cyc %2 = [3] ? K.gen %3 = [[2, 0; 0, 1]] \\ a prime ideal above 2 ? P = idealprimedec(K,3)[1]; \\ a prime ideal above 3 ? v = bnfisprincipal(K, P) %5 = [[2]~, [3/4, 1/4]~] ? idealmul(K, v[2], idealfactorback(K, K.gen, v[1])) %6 = [3 0] [0 1] ? % == idealhnf(K, P) %7 = 1 The binary digits of flag mean: * 1: If set, outputs [e,t] as explained above, otherwise returns only e, which is easier to compute. The following idiom only tests whether an ideal is principal:
is_principal(bnf, x) = !bnfisprincipal(bnf,x,0);
* 2: It may not be possible to recover t, given the initial accuracy
to which the
* 4: Return t in factored form (compact representation),
as a small product of S-units for a small set of finite places S,
possibly with huge exponents. This kind of result can be cheaply mapped to
K*/(K*)ℓ or to ℂ or ℚp to bounded accuracy and this
is usually enough for applications. Explicitly expanding such a compact
representation is possible using
The library syntax is
| |
| bnfissunit(bnf, sfu, x) |
![]() |
This function is obsolete, use
The library syntax is
| |
| bnfisunit(bnf, x, {U}) |
![]() |
bnf being the number field data
output by Note that bnf need not contain the fundamental units explicitly: it may contain the placeholder 0 instead:
? setrand(1); bnf = bnfinit(x^2-x-100000);
? bnf.fu
%2 = 0
? u = [119836165644250789990462835950022871665178127611316131167, \
379554884019013781006303254896369154068336082609238336]~;
? bnfisunit(bnf, u)
%3 = [-1, 0]~
The given u is 1/u1, where u1 is the fundamental
unit implicitly stored in bnf. In this case, u1 was not computed
and stored in algebraic form since the default accuracy was too low. Re-run
the This function allows x to be given in factored form, but it then assumes that x is an actual unit. (Because it is general too costly to check whether this is the case.)
? { v = [2, 85; 5, -71; 13, -162; 17, -76; 23, -37; 29, -104; [224, 1]~, -66;
[-86, 1]~, 86; [-241, 1]~, -20; [44, 1]~, 30; [124, 1]~, 11; [125, -1]~, -11;
[-214, 1]~, 33; [-213, -1]~, -33; [189, 1]~, 74; [190, -1]~, 104;
[-168, 1]~, 2; [-167, -1]~, -8]; }
? bnfisunit(bnf,v)
%5 = [1, 0]~
Note that v is the fundamental unit of
If the argument
? bnf = bnfinit(x^4 - x^3 + 4*x^2 + 3*x + 9, 1);
? bnf.sign
%2 = [0, 2]
? S = idealprimedec(bnf,5); #S
%3 = 2
? US = bnfunits(bnf,S);
? g = US[1]; #g \\ #S = #g, four S-units generators, in factored form
%5 = 4
? g[1]
%6 = [[6, -3, -2, -2]~ 1]
? g[2]
%7 =
[[-1, 1/2, -1/2, -1/2]~ 1]
[ [4, -2, -1, -1]~ 1]
? [nffactorback(bnf, x) | x <- g]
%8 = [[6, -3, -2, -2]~, [-5, 5, 0, 0]~, [-1, 1, -1, 0]~,
[1, -1, 0, 0]~]
? u = [10,-40,24,11]~;
? a = bnfisunit(bnf, u, US)
%9 = [2, 0, 1, 4]~
? nffactorback(bnf, g, a) \\ prodi g[i]^a[i] still in factored form
%10 =
[[6, -3, -2, -2]~ 2]
[ [0, 0, -1, -1]~ 1]
[ [2, -1, -1, 0]~ -2]
[ [1, 1, 0, 0]~ 2]
[ [-1, 1, 1, 1]~ -1]
[ [1, -1, 0, 0]~ 4]
? nffactorback(bnf,%) \\ u = prodi g[i]^a[i]
%11 = [10, -40, 24, 11]~
The library syntax is
| |
| bnflog(bnf, l) |
![]() |
Let bnf be a bnf structure attached to the number field F and let l be a prime number, hereafter denoted ℓ for typographical reasons. One define the logarithmic ℓ-class group ~{Cl}F of F, which is an infinite abelian group, and a logarithmic degree map with values in ℤℓ.
The function * D is the vector of elementary divisors for ~{Cl}F. * G(ℓ) is the vector of elementary divisors for the (conjecturally finite) abelian group ~{Cl}(ℓ) = { 𝔞 = ∑i ≤ k ai 𝔭i : degF 𝔞 = 0}, where the 𝔭i are the ℓ-adic places of F; this is a subgroup of ~{Cl}. * G' is the vector of elementary divisors for the ℓ-Sylow Cl' of the S-class group of F; the group ~{Cl} maps to Cl' with a simple co-kernel.
The library syntax is
| |
| bnflogdegree(nf, A, l) |
![]() |
Let nf be a nf structure attached to a number field F, and let l be a prime number (hereafter denoted ℓ). The ℓ-adified group of id\`{e}les of F quotiented by the group of logarithmic units is identified to the ℓ-group of logarithmic divisors ⨁ ℤℓ [𝔭], generated by the maximal ideals of F.
The degree map degF is additive with values in ℤℓ,
defined by degF 𝔭 = ~{f}𝔭 degℓ p,
where the integer ~{f}𝔭 is as in Let A = ∏ 𝔭n𝔭 be an ideal and let ~{A} = ∑ n𝔭 [𝔭] be the attached logarithmic divisor. Return the exponential of the ℓ-adic logarithmic degree degF A, which is a natural number.
The library syntax is
| |
| bnflogef(nf, pr) |
![]() |
Let nf be a nf structure attached to a number field F and let pr be a prid structure attached to a maximal ideal 𝔭 / p. Return [~{e}(F𝔭 / ℚp), ~{f}(F𝔭 / ℚp)] the logarithmic ramification and residue degrees. Let ℚpc/ℚp be the cyclotomic ℤp-extension, then ~{e} = [F𝔭 : F𝔭 ∩ ℚpc] and ~{f} = [F𝔭 ∩ ℚpc : ℚp]. Note that ~{e}~{f} = e(𝔭/p) f(𝔭/p), where e(𝔭/p) and f(𝔭/p) denote the usual ramification and residue degrees.
? F = nfinit(y^6 - 3*y^5 + 5*y^3 - 3*y + 1); ? bnflogef(F, idealprimedec(F,2)[1]) %2 = [6, 1] ? bnflogef(F, idealprimedec(F,5)[1]) %3 = [1, 2]
The library syntax is
| |
| bnfnarrow(bnf) |
![]() |
bnf being as output by
The library syntax is
| |
| bnfsignunit(bnf) |
![]() |
bnf being as output by
/* exponents of totally positive units generators on K.tu, K.fu */
tpuexpo(K)=
{ my(M, S = bnfsignunit(K), [m,n] = matsize(S));
\\ m = K.r1, n = r1+r2-1
S = matrix(m,n, i,j, if (S[i,j] < 0, 1,0));
S = concat(vectorv(m,i,1), S); \\ add sign(-1)
M = matkermod(S, 2);
if (M, mathnfmodid(M, 2), 2*matid(n+1))
}
/* totally positive fundamental units of bnf K */
tpu(K)=
{ my(ex = tpuexpo(K)[,^1]); \\ remove ex[,1], corresponds to 1 or -1
my(v = concat(K.tu[2], K.fu));
[ nffactorback(K, v, c) | c <- ex];
}
The library syntax is
| |
| bnfsunit(bnf, S) |
![]() |
Computes the fundamental S-units of the
number field bnf (output by v[1] gives a minimal system of (integral) generators of the S-unit group modulo the unit group.
v[2] contains technical data needed by v[3] is an obsoleted component, now the empty vector. v[4] is the S-regulator (this is the product of the regulator, the S-class number and the natural logarithms of the norms of the ideals in S). v[5] gives the S-class group structure, in the usual abelian group format: a vector whose three components give in order the S-class number, the cyclic components and the generators. v[6] is a copy of S.
The library syntax is
| |
| bnfunits(bnf, {S}) |
![]() |
Return the fundamental units of the number field bnf output by bnfinit; if S is present and is a list of prime ideals, compute fundamental S-units instead. The first component of the result contains independent integral S-units generators: first nonunits, then r1+r2-1 fundamental units, then the torsion unit. The result may be used as an optional argument to bnfisunit. The units are given in compact form: no expensive computation is attempted if the bnf does not already contain units.
? bnf = bnfinit(x^4 - x^3 + 4*x^2 + 3*x + 9, 1); ? bnf.sign \\ r1 + r2 - 1 = 1 %2 = [0, 2] ? U = bnfunits(bnf); u = U[1]; ? #u \\ r1 + r2 = 2 units %5 = 2; ? u[1] \\ fundamental unit as factorization matrix %6 = [[0, 0, -1, -1]~ 1] [[2, -1, -1, 0]~ -2] [ [1, 1, 0, 0]~ 2] [ [-1, 1, 1, 1]~ -1] ? u[2] \\ torsion unit as factorization matrix %7 = [[1, -1, 0, 0]~ 1] ? [nffactorback(bnf, z) | z <- u] \\ same units in expanded form %8 = [[-1, 1, -1, 0]~, [1, -1, 0, 0]~] Now an example involving S-units for a nontrivial S:
? S = idealprimedec(bnf,5); #S %9 = 2 ? US = bnfunits(bnf, S); uS = US[1]; ? g = [nffactorback(bnf, z) | z <- uS] \\ now 4 units %11 = [[6, -3, -2, -2]~, [-5, 5, 0, 0]~, [-1, 1, -1, 0]~, [1, -1, 0, 0]~] ? bnfisunit(bnf,[10,-40,24,11]~) %12 = []~ \\ not a unit ? e = bnfisunit(bnf, [10,-40,24,11]~, US) %13 = [2, 0, 1, 4]~ \\ ...but an S-unit ? nffactorback(bnf, g, e) %14 = [10, -40, 24, 11]~ ? nffactorback(bnf, uS, e) \\ in factored form %15 = [[6, -3, -2, -2]~ 2] [ [0, 0, -1, -1]~ 1] [ [2, -1, -1, 0]~ -2] [ [1, 1, 0, 0]~ 2] [ [-1, 1, 1, 1]~ -1] [ [1, -1, 0, 0]~ 4]
Note that in more complicated cases, any
The library syntax is
| |
| dirzetak(nf, b) |
![]() |
Gives as a vector the first b coefficients of the Dedekind zeta function of the number field nf considered as a Dirichlet series.
The library syntax is
| |
| factornf(x, t) |
![]() |
This function is obsolete, use
factorization of the univariate polynomial x
over the number field defined by the (univariate) polynomial t. x may
have coefficients in ℚ or in the number field. The algorithm reduces to
factorization over ℚ (Trager's trick). The direct approach of
The main variable of t must be of lower priority than that of x (see Section se:priority). However if nonrational number field elements occur (as polmods or polynomials) as coefficients of x, the variable of these polmods must be the same as the main variable of t. For example
? factornf(x^2 + Mod(y, y^2+1), y^2+1);
? factornf(x^2 + y, y^2+1); \\ these two are OK
? factornf(x^2 + Mod(z,z^2+1), y^2+1)
*** at top-level: factornf(x^2+Mod(z,z
*** ^ — — — — — — --
*** factornf: inconsistent data in rnf function.
? factornf(x^2 + z, y^2+1)
*** at top-level: factornf(x^2+z,y^2+1
*** ^ — — — — — — --
*** factornf: incorrect variable in rnf function.
The library syntax is
| |
| idealadd(nf, x, y) |
![]() |
Sum of the two ideals x and y in the number field nf. The result is given in HNF.
? K = nfinit(x^2 + 1); ? a = idealadd(K, 2, x + 1) \\ ideal generated by 2 and 1+I %2 = [2 1] [0 1] ? pr = idealprimedec(K, 5)[1]; \\ a prime ideal above 5 ? idealadd(K, a, pr) \\ coprime, as expected %4 = [1 0] [0 1] This function cannot be used to add arbitrary ℤ-modules, since it assumes that its arguments are ideals:
? b = Mat([1,0]~);
? idealadd(K, b, b) \\ only square t_MATs represent ideals
*** idealadd: nonsquare t_MAT in idealtyp.
? c = [2, 0; 2, 0]; idealadd(K, c, c) \\ nonsense
%6 =
[2 0]
[0 2]
? d = [1, 0; 0, 2]; idealadd(K, d, d) \\ nonsense
%7 =
[1 0]
[0 1]
In the last two examples, we get wrong results since the
matrices c and d do not correspond to an ideal: the ℤ-span of their
columns (as usual interpreted as coordinates with respect to the integer basis
The library syntax is
| |
| idealaddtoone(nf, x, {y}) |
![]() |
x and y being two co-prime integral ideals (given in any form), this gives a two-component row vector [a,b] such that a ∈ x, b ∈ y and a+b = 1.
The alternative syntax
The library syntax is
| |
| idealappr(nf, x, {flag}) |
![]() |
If x is a fractional ideal (given in any form), gives an element α in nf such that for all prime ideals 𝔭 such that the valuation of x at 𝔭 is nonzero, we have v𝔭(α) = v𝔭(x), and v𝔭(α) ≥ 0 for all other 𝔭.
The argument x may also be given as a prime ideal factorization, as
output by flag is deprecated (ignored), kept for backward compatibility.
The library syntax is
| |
| idealchinese(nf, x, {y}) |
![]() |
x being a prime ideal factorization (i.e. a 2-columns matrix whose first column contains prime ideals and the second column contains integral exponents), y a vector of elements in nf indexed by the ideals in x, computes an element b such that v𝔭(b - y𝔭) ≥ v𝔭(x) for all prime ideals in x and v𝔭(b) ≥ 0 for all other 𝔭.
? K = nfinit(t^2-2); ? x = idealfactor(K, 2^2*3) %2 = [[2, [0, 1]~, 2, 1, [0, 2; 1, 0]] 4] [ [3, [3, 0]~, 1, 2, 1] 1] ? y = [t,1]; ? idealchinese(K, x, y) %4 = [4, -3]~
The argument x may also be of the form [x, s] where the first component
is as above and s is a vector of signs, with r1 components
si in {-1,0,1}:
if σi denotes the i-th real embedding of the number field,
the element b returned satisfies further
? idealchinese(K, [x, [1,1]], y) %5 = [16, -3]~ ? idealchinese(K, [x, [-1,-1]], y) %6 = [-20, -3]~ ? idealchinese(K, [x, [1,-1]], y) %7 = [4, -3]~ If y is omitted, return a data structure which can be used in place of x in later calls and allows to solve many chinese remainder problems for a given x more efficiently. In this case, the right hand side y is not allowed to have denominators, unless they are coprime to x.
? C = idealchinese(K, [x, [1,1]]); ? idealchinese(K, C, y) \\ as above %9 = [16, -3]~ ? for(i=1,10^4, idealchinese(K,C,y)) \\ ... but faster ! time = 80 ms. ? for(i=1,10^4, idealchinese(K,[x,[1,1]],y)) time = 224 ms. Finally, this structure is itself allowed in place of x, the new s overriding the one already present in the structure. This allows to initialize for different sign conditions more efficiently when the underlying ideal factorization remains the same.
? D = idealchinese(K, [C, [1,-1]]); \\ replaces [1,1] ? idealchinese(K, D, y) %13 = [4, -3]~ ? for(i=1,10^4,idealchinese(K,[C,[1,-1]])) time = 40 ms. \\ faster than starting from scratch ? for(i=1,10^4,idealchinese(K,[x,[1,-1]])) time = 128 ms.
The library syntax is
| |
| idealcoprime(nf, x, y) |
![]() |
Given two integral ideals x and y in the number field nf, returns a β in the field, such that β.x is an integral ideal coprime to y. In fact, β is also guaranteed to be integral outside primes dividing y.
The library syntax is
| |
| idealdiv(nf, x, y, {flag = 0}) |
![]() |
Quotient x.y-1 of the two ideals x and y in the number field nf. The result is given in HNF. If flag is nonzero, the quotient x.y-1 is assumed to be an integral ideal. This can be much faster when the norm of the quotient is small even though the norms of x and y are large. More precisely, the algorithm cheaply removes all maximal ideals above rational primes such that vp(Nx) = vp(Ny).
The library syntax is
| |
| idealdown(nf, x) |
![]() |
Let nf be a number field as output by
? nf = nfinit(y^2+1); ? idealdown(nf, -1/2) %2 = 1/2 ? idealdown(nf, (y+1)/3) %3 = 2/3 ? idealdown(nf, [2, 11]~) %4 = 125 ? x = idealprimedec(nf, 2)[1]; idealdown(nf, x) %5 = 2 ? idealdown(nf, [130, 94; 0, 2]) %6 = 130
The library syntax is
| |
| idealfactor(nf, x, {lim}) |
![]() |
Factors into prime ideal powers the ideal x in the number field
nf. The output format is similar to the
? nf = nfinit(x^3-2); ? idealfactor(nf, x) \\ a prime ideal above 2 %2 = [[2, [0, 1, 0]~, 3, 1, ...] 1] ? A = idealhnf(nf, 6*x, 4+2*x+x^2) %3 = [6 0 4] [0 6 2] [0 0 1] ? idealfactor(nf, A) %4 = [[2, [0, 1, 0]~, 3, 1, ...] 2] [[3, [1, 1, 0]~, 3, 1, ...] 2] ? idealfactor(nf, A, 3) \\ restrict to primes above p < 3 %5 = [[2, [0, 1, 0]~, 3, 1, ...] 2]
The library syntax is
| |
| idealfactorback(nf, f, {e}, {flag = 0}) |
![]() |
Gives back the ideal corresponding to a factorization. The integer 1 corresponds to the empty factorization. If e is present, e and f must be vectors of the same length (e being integral), and the corresponding factorization is the product of the f[i]e[i].
If not, and f is vector, it is understood as in the preceding case with e
a vector of 1s: we return the product of the f[i]. Finally, f can be a
regular factorization, as produced by
? nf = nfinit(y^2+1); idealfactor(nf, 4 + 2*y) %1 = [ [2, [1, 1]~, 2, 1, [1, -1; 1, 1]] 2] [[5, [2, 1]~, 1, 1, [-2, -1; 1, -2]] 1] ? idealfactorback(nf, %) %2 = [10 4] [0 2] ? f = %1[,1]; e = %1[,2]; idealfactorback(nf, f, e) %3 = [10 4] [0 2] ? % == idealhnf(nf, 4 + 2*y) %4 = 1
If flag is nonzero, performs ideal reductions (
? f = vector(#f, i, [f[i], [;]]); \\ transforms to extended ideals ? idealfactorback(nf, f, e, 1) %6 = [[1, 0; 0, 1], [2, 1; [-2, 1]~, -1; 5, 1]] ? nffactorback(nf, %[2]) %7 = [-4, -2]~
The extended ideal returned in
The library syntax is
| |
| idealfrobenius(nf, gal, pr) |
![]() |
Let K be the number field defined by nf and assume K/ℚ be a
Galois extension with Galois group given
? nf = nfinit(polcyclo(31)); ? gal = galoisinit(nf); ? pr = idealprimedec(nf,101)[1]; ? g = idealfrobenius(nf,gal,pr); ? galoispermtopol(gal,g) %5 = x^8 This is correct since 101 = 8 mod 31.
The library syntax is
| |
| idealfromgens(nf, v) |
![]() |
Gives the Hermite normal form of the (fractional) ideal of the number
field
The library syntax is
| |
| idealhnf(nf, u, {v}) |
![]() |
Gives the Hermite normal form of the ideal uℤK+vℤK, where u and v are elements of the number field K defined by nf.
? nf = nfinit(y^3 - 2); ? idealhnf(nf, 2, y+1) %2 = [1 0 0] [0 1 0] [0 0 1] ? idealhnf(nf, y/2, [0,0,1/3]~) %3 = [1/3 0 0] [0 1/6 0] [0 0 1/6]
If v is omitted, returns the HNF of the ideal defined by u: u may be an
algebraic number (defining a principal ideal), a maximal ideal (as given by
? idealhnf(nf, idealprimedec(nf,2)[1]) %4 = [2 0 0] [0 1 0] [0 0 1] ? idealhnf(nf, %) \\ already in HNF %5 = [2 0 0] [0 1 0] [0 0 1]
Another deprecated format, generalizing the last one,
allows u to be a matrix whose columns give generators for the ideal.
This format is awkward and error-prone, please use * if strictly less than N = [K:ℚ] columns are present, u is the ℤK-module they generate,
* unfortunately, if N or more are given, it is assumed that
they form a ℤ-basis of the ideal, in particular that the matrix has
maximal rank N. This acts as
The function
Finally, when K is quadratic with discriminant DK, we
allow u =
? K = nfinit(x^2 - 60); K.disc
%1 = 60
? idealhnf(K, qfbprimeform(60,2))
%2 =
[2 1]
[0 1]
? idealhnf(K, Qfb(1,2,3))
*** at top-level: idealhnf(K,Qfb(1,2,3
*** ^ — — — — — — --
*** idealhnf: Qfb(1, 2, 3) has discriminant != 60 in idealhnf.
The library syntax is
| |
| idealintersect(nf, A, B) |
![]() |
Intersection of the two ideals A and B in the number field nf. The result is given in HNF.
? nf = nfinit(x^2+1); ? idealintersect(nf, 2, x+1) %2 = [2 0] [0 2] This function does not apply to general ℤ-modules, e.g. orders, since its arguments are replaced by the ideals they generate. The following script intersects ℤ-modules A and B given by matrices of compatible dimensions with integer coefficients:
ZM_intersect(A,B) =
{ my(Ker = matkerint(concat(A,B)));
mathnf( A * Ker[1..#A,] )
}
The library syntax is
| |
| idealinv(nf, x) |
![]() |
Inverse of the ideal x in the number field nf, given in HNF. If x is an extended ideal, its principal part is suitably updated: i.e. inverting [I,t], yields [I-1, 1/t].
The library syntax is
| |
| idealismaximal(nf, x) |
![]() |
Given nf a number field as output by
? K = nfinit(y^2 + 1); ? idealismaximal(K, 3) \\ 3 is inert %2 = [3, [3, 0]~, 1, 2, 1] ? idealismaximal(K, 5) \\ 5 is not %3 = 0 ? pr = idealprimedec(K,5)[1] \\ already a prid %4 = [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]] ? idealismaximal(K, pr) \\ trivial check %5 = [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]] ? x = idealhnf(K, pr) %6 = [5 3] [0 1] ? idealismaximal(K, x) \\ converts from matrix form to prid %7 = [5, [-2, 1]~, 1, 1, [2, -1; 1, 2]]
This function is noticeably faster than
The library syntax is
| |
| idealispower(nf, A, n, {&B}) |
![]() |
Let nf be a number field and n > 0 be a positive integer. Return 1 if the fractional ideal A = Bn is an n-th power and 0 otherwise. If the argument B is present, set it to the n-th root of A, in HNF.
? K = nfinit(x^3 - 2); ? A = [46875, 30966, 9573; 0, 3, 0; 0, 0, 3]; ? idealispower(K, A, 3, &B) %3 = 1 ? B %4 = [75 22 41] [ 0 1 0] [ 0 0 1] ? A = [9375, 2841, 198; 0, 3, 0; 0, 0, 3]; ? idealispower(K, A, 3) %5 = 0
The library syntax is
| |
| ideallist(nf, bound, {flag = 4}) |
![]() |
Computes the list of all ideals of norm less or equal to bound in the number field nf. The result is a row vector with exactly bound components. Each component is itself a row vector containing the information about ideals of a given norm, in no specific order. The information is inferred from local data and Chinese remainders and less expensive than computing than a direct global computation. The binary digits of flag mean: * 1: if the ideals are given by a bid, include generators; otherwise don't.
* 2: if this bit is set, nf must be a bnf with units. Each
component is of the form [bid,U], where bid is attached to
an ideal f and U is a vector of discrete logarithms of the units in
(ℤK/f)*. More precisely, U gives the * 4: give only the ideal (in HNF), else a bid. * 8: omit ideals which cannot be conductors, i.e. divisible exactly by a prime ideal of norm 2.
? nf = nfinit(x^2+1); ? L = ideallist(nf, 100); ? L[1] %3 = [[1, 0; 0, 1]] \\ A single ideal of norm 1 ? #L[65] %4 = 4 \\ There are 4 ideals of norm 65 in ℤ[i] If one wants more information:
? L = ideallist(nf, 100, 0); ? l = L[25]; vector(#l, i, l[i].clgp) %6 = [[20, [20]], [16, [4, 4]], [20, [20]]] ? l[1].mod %7 = [[25, 18; 0, 1], []] ? l[2].mod %8 = [[5, 0; 0, 5], []] ? l[3].mod %9 = [[25, 7; 0, 1], []]
where we ask for the structures of the (ℤ[i]/f)* for all
three ideals of norm 25. In fact, for all moduli with finite part of norm
25 and trivial Archimedean part, as the last 3 commands show. See
Finally, one can input a negative
The library syntax is
| |
| ideallistarch(nf, list, arch) |
![]() |
list is a vector of vectors of bid's, as output by
? bnf = bnfinit(x^2-2); ? bnf.sign %2 = [2, 0] \\ two places at infinity ? L = ideallist(bnf, 100, 0); ? l = L[98]; vector(#l, i, l[i].clgp) %4 = [[42, [42]], [36, [6, 6]], [42, [42]]] ? La = ideallistarch(bnf, L, [1,1]); \\ add them to the modulus ? l = La[98]; vector(#l, i, l[i].clgp) %6 = [[168, [42, 2, 2]], [144, [6, 6, 2, 2]], [168, [42, 2, 2]]] Of course, the results above are obvious: adding t places at infinity will add t copies of ℤ/2ℤ to (ℤK/f)*. The following application is more typical:
? L = ideallist(bnf, 100, 2); \\ units are required now ? La = ideallistarch(bnf, L, [1,1]); ? H = bnrclassnolist(bnf, La); ? H[98]; %4 = [2, 12, 2]
The library syntax is
| |
| ideallog({nf}, x, bid) |
![]() |
nf is a number field,
bid is as output by
When nf is omitted, take it to be the rational number field. In that
case, x must be a
The library syntax is
| |
| idealmin(nf, ix, {vdir}) |
![]() |
This function is useless and kept for backward compatibility only,
use
The library syntax is
| |
| idealmul(nf, x, y, {flag = 0}) |
![]() |
Ideal multiplication of the ideals x and y in the number field nf; the result is the ideal product in HNF. If either x or y are extended ideals, their principal part is suitably updated: i.e. multiplying [I,t], [J,u] yields [IJ, tu]; multiplying I and [J, u] yields [IJ, u].
? nf = nfinit(x^2 + 1); ? idealmul(nf, 2, x+1) %2 = [4 2] [0 2] ? idealmul(nf, [2, x], x+1) \\ extended ideal * ideal %3 = [[4, 2; 0, 2], x] ? idealmul(nf, [2, x], [x+1, x]) \\ two extended ideals %4 = [[4, 2; 0, 2], [-1, 0]~]
If flag is nonzero, reduce the result using
The library syntax is
See also
| |
| idealnorm(nf, x) |
![]() |
Computes the norm of the ideal x in the number field nf.
The library syntax is
| |
| idealnumden(nf, x) |
![]() |
Returns [A,B], where A,B are coprime integer ideals such that x = A/B, in the number field nf.
? nf = nfinit(x^2+1); ? idealnumden(nf, (x+1)/2) %2 = [[1, 0; 0, 1], [2, 1; 0, 1]]
The library syntax is
| |
| idealpow(nf, x, k, {flag = 0}) |
![]() |
Computes the k-th power of the ideal x in the number field nf; k ∈ ℤ. If x is an extended ideal, its principal part is suitably updated: i.e. raising [I,t] to the k-th power, yields [Ik, tk].
If flag is nonzero, reduce the result using
The library syntax is
See also
| |
| idealprimedec(nf, p, {f = 0}) |
![]() |
Computes the prime ideal decomposition of the (positive) prime number p in the number field K represented by nf. If a nonprime p is given the result is undefined. If f is present and nonzero, restrict the result to primes of residue degree ≤ f.
The result is a vector of prid structures, each representing one of the
prime ideals above p in the number field nf. The representation
The algebraic number a is guaranteed to have a valuation equal to 1 at the prime ideal (this is automatic if e > 1).
The components of
? K = nfinit(x^3-2); ? P = idealprimedec(K, 5); ? #P \\ 2 primes above 5 in Q(2^(1/3)) %3 = 2 ? [p1,p2] = P; ? [p1.e, p1.f] \\ the first is unramified of degree 1 %5 = [1, 1] ? [p2.e, p2.f] \\ the second is unramified of degree 2 %6 = [1, 2] ? p1.gen %7 = [5, [2, 1, 0]~] ? nfbasistoalg(K, %[2]) \\ a uniformizer for p1 %8 = Mod(x + 2, x^3 - 2) ? #idealprimedec(K, 5, 1) \\ restrict to f = 1 %9 = 1 \\ now only p1
The library syntax is
| |
| idealprincipalunits(nf, pr, k) |
![]() |
Given a prime ideal in
? K = nfinit(y^2+1); ? P = idealprimedec(K,2)[1]; ? G = idealprincipalunits(K, P, 20); ? G.cyc %4 = [512, 256, 4] \\ Z/512 x Z/256 x Z/4 ? G.gen %5 = [[-1, -2]~, 1021, [0, -1]~] \\ minimal generators of given order
The library syntax is
| |
| idealramgroups(nf, gal, pr) |
![]() |
Let K be the number field defined by nf and assume that K/ℚ is
Galois with Galois group G given by
*
* and for i ≥ 2,
* The length of g is the number of nontrivial groups in the sequence, thus is 0 if e = 1 and f = 1, and 1 if f > 1 and e = 1. The following function computes the cardinality of a subgroup of G, as given by the components of g:
card(H) =my(o=H[2]); prod(i=1,#o,o[i]);
? nf=nfinit(x^6+3); gal=galoisinit(nf); pr=idealprimedec(nf,3)[1]; ? g = idealramgroups(nf, gal, pr); ? apply(card,g) %3 = [6, 6, 3, 3, 3] \\ cardinalities of the Gi
? nf=nfinit(x^6+108); gal=galoisinit(nf); pr=idealprimedec(nf,2)[1]; ? iso=idealramgroups(nf,gal,pr)[2] %5 = [[Vecsmall([2, 3, 1, 5, 6, 4])], Vecsmall([3])] ? nfdisc(galoisfixedfield(gal,iso,1)) %6 = -3 The field fixed by the inertia group of 2 is not ramified at 2.
The library syntax is
| |
| idealred(nf, I, {v = 0}) |
![]() |
LLL reduction of
the ideal I in the number field K attached to nf, along the
direction v. The v parameter is best left omitted, but if it is present,
it must be an This function finds an a ∈ K* such that J = (a)I is "small" and integral (see the end for technical details). The result is the Hermite normal form of the "reduced" ideal J.
? K = nfinit(y^2+1); ? P = idealprimedec(K,5)[1]; ? idealred(K, P) %3 = [1 0] [0 1]
More often than not, a principal ideal yields the unit
ideal as above. This is a quick and dirty way to check if ideals are principal,
but it is not a necessary condition: a nontrivial result does not prove that
the ideal is nonprincipal. For guaranteed results, see If the input is an extended ideal [I,s], the output is [J, sa]; in this way, one keeps track of the principal ideal part:
? idealred(K, [P, 1]) %5 = [[1, 0; 0, 1], [2, -1]~]
meaning that P is generated by [2, -1] . The number field element in the
extended part is an algebraic number in any form or a factorization
matrix (in terms of number field elements, not ideals!). In the latter case,
elements stay in factored form, which is a convenient way to avoid
coefficient explosion; see also
Technical note. The routine computes an LLL-reduced
basis for the lattice I-1 equipped with the quadratic
form
|| x ||v2 = ∑i = 1r1+r2
2viϵi|σi(x)|2,
where as usual the σi are the (real and) complex embeddings and
ϵi = 1, resp. 2, for a real, resp. complex place. The element
a is simply the first vector in the LLL basis. The only reason you may want
to try to change some directions and set some vi != 0 is to randomize
the elements found for a fixed ideal, which is heuristically useful in index
calculus algorithms like Even more technical note. In fact, the above is a white lie. We do not use ||.||v exactly but a rescaled rounded variant which gets us faster and simpler LLLs. There's no harm since we are not using any theoretical property of a after all, except that it belongs to I-1 and that a I is "expected to be small".
The library syntax is
| |
| idealredmodpower(nf, x, n, {B = factorlimit}) |
![]() |
Let nf be a number field, x an ideal in nf and n > 0 be a positive integer. Return a number field element b such that x bn = v is small. If x is integral, then v is also integral.
More precisely, The bound B avoids a costly complete factorization of x; as soon as the n-core of x is B-smooth (i.e., as soon as I is n-power free), then J is as large as possible and so is the expected reduction.
? T = x^6+108; nf = nfinit(T); a = Mod(x,T); ? setrand(1); u = (2*a^2+a+3)*random(2^1000*x^6)^6; ? sizebyte(u) %3 = 4864 ? b = idealredmodpower(nf,u,2); ? v2 = nfeltmul(nf,u, nfeltpow(nf,b,2)) %5 = [34, 47, 15, 35, 9, 3]~ ? b = idealredmodpower(nf,u,6); ? v6 = nfeltmul(nf,u, nfeltpow(nf,b,6)) %7 = [3, 0, 2, 6, -7, 1]~
The last element
? idealnorm(nf,v2) %8 = 81309 ? idealnorm(nf,v6) %9 = 731781
The library syntax is
| |
| idealstar({nf}, N, {flag = 1}, {cycmod}) |
![]() |
Outputs a
If the positive integer
This bid is used in
If flag = 1 (default), the result is a If flag = 2, as flag = 1, but including generators. If flag = 0, only outputs (ℤK/N)* as an abelian group, i.e as a 3-component vector [h,d,g]: h is the order, d is the vector of SNF cyclic components and g the corresponding generators.
If nf is omitted, we take it to be the rational number fields, N must
be an integer and we return the structure of (ℤ/Nℤ)*. In other words
idealstar(nfinit(x), N, flag)
but faster. The alternative syntax
The library syntax is
| |
| idealtwoelt(nf, x, {a}) |
![]() |
Computes a two-element representation of the ideal x in the number field nf, combining a random search and an approximation theorem; x is an ideal in any form (possibly an extended ideal, whose principal part is ignored)
* When called as
? K = nfinit(t^5-23); ? x = idealhnf(K, t^2*(t+1), t^3*(t+1)) %2 = \\ some random ideal of norm 552*23 [552 23 23 529 23] [ 0 23 0 0 0] [ 0 0 1 0 0] [ 0 0 0 1 0] [ 0 0 0 0 1] ? [a,alpha] = idealtwoelt(K, x) %3 = [552, [23, 0, 1, 0, 0]~] ? nfbasistoalg(K, alpha) %4 = Mod(t^2 + 23, t^5 - 23)
* When called as
? alpha2 = idealtwoelt(K, x, 552) %5 = [-161, -161, -183, -207, 0]~ ? idealhnf(K, 552, alpha2) == x %6 = 1
Note that, in both cases, the return value is not
recognized as an ideal by GP functions; one must use
The library syntax is
| |
| idealval(nf, x, pr) |
![]() |
Gives the valuation of the ideal x at the prime ideal pr in the
number field nf, where pr is in
The library syntax is
| |
| matalgtobasis(nf, x) |
![]() |
This function is deprecated, use
nf being a number field in
The library syntax is
| |
| matbasistoalg(nf, x) |
![]() |
This function is deprecated, use
nf being a number field in
The library syntax is
| |
| modreverse(z) |
![]() |
Let z = This is quite useful when one changes the generating element in algebraic extensions:
? u = Mod(x, x^3 - x -1); v = u^5; ? w = modreverse(v) %2 = Mod(x^2 - 4*x + 1, x^3 - 5*x^2 + 4*x - 1) which means that x3 - 5x2 + 4x -1 is another defining polynomial for the cubic field ℚ(u) = ℚ[x]/(x3 - x - 1) = ℚ[x]/(x3 - 5x2 + 4x - 1) = ℚ(v), and that u → v2 - 4v + 1 gives an explicit isomorphism. From this, it is easy to convert elements between the A(u) ∈ ℚ(u) and B(v) ∈ ℚ(v) representations:
? A = u^2 + 2*u + 3; subst(lift(A), 'x, w) %3 = Mod(x^2 - 3*x + 3, x^3 - 5*x^2 + 4*x - 1) ? B = v^2 + v + 1; subst(lift(B), 'x, v) %4 = Mod(26*x^2 + 31*x + 26, x^3 - x - 1) If the minimal polynomial of z has lower degree than expected, the routine fails
? u = Mod(-x^3 + 9*x, x^4 - 10*x^2 + 1)
? modreverse(u)
*** modreverse: domain error in modreverse: deg(minpoly(z)) < 4
*** Break loop: type 'break' to go back to GP prompt
break> Vec( dbg_err() ) \\ ask for more info
["e_DOMAIN", "modreverse", "deg(minpoly(z))", "<", 4,
Mod(-x^3 + 9*x, x^4 - 10*x^2 + 1)]
break> minpoly(u)
x^2 - 8
The library syntax is
| |
| newtonpoly(x, p) |
![]() |
Gives the vector of the slopes of the Newton
polygon of the polynomial x with respect to the prime number p. The n
components of the vector are in decreasing order, where n is equal to the
degree of x. Vertical slopes occur iff the constant coefficient of x is
zero and are denoted by
The library syntax is
| |
| nfalgtobasis(nf, x) |
![]() |
Given an algebraic number x in the number field nf,
transforms it to a column vector on the integral basis
? nf = nfinit(y^2 + 4); ? nf.zk %2 = [1, 1/2*y] ? nfalgtobasis(nf, [1,1]~) %3 = [1, 1]~ ? nfalgtobasis(nf, y) %4 = [0, 2]~ ? nfalgtobasis(nf, Mod(y, y^2+4)) %5 = [0, 2]~
This is the inverse function of
The library syntax is
| |
| nfbasis(T, {&dK}) |
![]() |
Let T(X) be an irreducible polynomial with integral coefficients. This
function returns an integral basis of the number field defined by T,
that is a ℤ-basis of its maximal order. If present,
? nfbasis(x^2 + 4) \\ Z[X]/(T) has index 2 in ZK %1 = [1, x/2] ? nfbasis(x^2 + 4, &D) %2 = [1, x/2] ? D %3 = -4 This function uses a modified version of the round 4 algorithm, due to David Ford, Sebastian Pauli and Xavier Roblot. Local basis, orders maximal at certain primes. Obtaining the maximal order is hard: it requires factoring the discriminant D of T. Obtaining an order which is maximal at a finite explicit set of primes is easy, but it may then be a strict suborder of the maximal order. To specify that we are interested in a given set of places only, we can replace the argument T by an argument [T,listP], where listP encodes the primes we are interested in: it must be a factorization matrix, a vector of integers or a single integer. * Vector: we assume that it contains distinct prime numbers. * Matrix: we assume that it is a two-column matrix of a (partial) factorization of D; namely the first column contains distinct primes and the second one the valuation of D at each of these primes. * Integer B: this is replaced by the vector of primes up to B. Note that the function will use at least O(B) time: a small value, about 105, should be enough for most applications. Values larger than 232 are not supported.
In all these cases, the primes may or may not divide the discriminant D
of T. The function then returns a ℤ-basis of an order whose index is
not divisible by any of these prime numbers. The result may actually be
a global integral basis, in particular if all the prime divisors of the
field discriminant are included, but this is not guaranteed!
Note that
? K = nfinit([T, listP]); ? nfcertify(K) \\ we computed an actual maximal order %2 = [];
The first line initializes a number field structure
incorporating Of course, if listP contains a single prime number p, the function returns a local integral basis for ℤp[X]/(T):
? nfbasis(x^2+x-1001) %1 = [1, 1/3*x - 1/3] ? nfbasis( [x^2+x-1001, [2]] ) %2 = [1, x] The following function computes the index iT of ℤ[X]/(T) in the order generated by the ℤ-basis B:
nfbasisindex(T, B) = vecprod([denominator(pollead(Q)) | Q <- B]);
In particular, B is a basis of the maximal order
if and only if
? B = nfbasis([T, P], &D); ? dK = sign(D) * vecprod([p^valuation(D,p) | p<-P]); ? dK * nfbasisindex(T, B)^2 == poldisc(T)
The variable The Buchmann-Lenstra algorithm.
We now complicate the picture: it is in fact allowed to include
composite numbers instead of primes
in
? B = 10^5; ? listP = factor(poldisc(T), B); \\ primes <= B dividing D + cofactor ? basis = nfbasis([T, listP], &D)
If the computed discriminant D factors completely
over the primes less than B (together with the primes contained in the
F = factor(D, B); P = F[,1]; E = F[,2];
for (i = 1, #P,
if (P[i] > B && !isprime(P[i]), warning("nf may be incorrect")));
This is a sufficient but not a necessary condition, hence the warning, instead of an error.
The function
? B = 10^5; ? nf = nfinit([T, B]); ? nfcertify(nf) %3 = [] \\ nf is unconditionally correct ? [basis, disc] = [nf.zk, nf.disc];
The library syntax is
| |
| nfbasistoalg(nf, x) |
![]() |
Given an algebraic number x in the number field nf, transforms it
into
? nf = nfinit(y^2 + 4); ? nf.zk %2 = [1, 1/2*y] ? nfbasistoalg(nf, [1,1]~) %3 = Mod(1/2*y + 1, y^2 + 4) ? nfbasistoalg(nf, y) %4 = Mod(y, y^2 + 4) ? nfbasistoalg(nf, Mod(y, y^2+4)) %5 = Mod(y, y^2 + 4)
This is the inverse function of
The library syntax is
| |
| nfcertify(nf) |
![]() |
nf being as output by
The function returns a vector of coprime composite integers. If this vector
is empty, then
The library syntax is
| |
| nfcompositum(nf, P, Q, {flag = 0}) |
![]() |
Let nf be a number field structure attached to the field K and let P and Q be squarefree polynomials in K[X] in the same variable. Outputs the simple factors of the étale K-algebra A = K[X, Y] / (P(X), Q(Y)). The factors are given by a list of polynomials R in K[X], attached to the number field K[X]/ (R), and sorted by increasing degree (with respect to lexicographic ordering for factors of equal degrees). Returns an error if one of the polynomials is not squarefree. Note that it is more efficient to reduce to the case where P and Q are irreducible first. The routine will not perform this for you, since it may be expensive, and the inputs are irreducible in most applications anyway. In this case, there will be a single factor R if and only if the number fields defined by P and Q are linearly disjoint (their intersection is K). The binary digits of flag mean 1: outputs a vector of 4-component vectors [R,a,b,k], where R ranges through the list of all possible compositums as above, and a (resp. b) expresses the root of P (resp. Q) as an element of K[X]/(R). Finally, k is a small integer such that b + ka = X modulo R. 2: assume that P and Q define number fields that are linearly disjoint: both polynomials are irreducible and the corresponding number fields have no common subfield besides K. This allows to save a costly factorization over K. In this case return the single simple factor instead of a vector with one element. A compositum is often defined by a complicated polynomial, which it is advisable to reduce before further work. Here is an example involving the field K(ζ5, 51/10), K = ℚ(sqrt{5}):
? K = nfinit(y^2-5);
? L = nfcompositum(K, x^5 - y, polcyclo(5), 1); \\ list of [R,a,b,k]
? [R, a] = L[1]; \\ pick the single factor, extract R,a (ignore b,k)
? lift(R) \\ defines the compositum
%4 = x^10 + (-5/2*y + 5/2)*x^9 + (-5*y + 20)*x^8 + (-20*y + 30)*x^7 + \
(-45/2*y + 145/2)*x^6 + (-71/2*y + 121/2)*x^5 + (-20*y + 60)*x^4 + \
(-25*y + 5)*x^3 + 45*x^2 + (-5*y + 15)*x + (-2*y + 6)
? a^5 - y \\ a fifth root of y
%5 = 0
? [T, X] = rnfpolredbest(K, R, 1);
? lift(T) \\ simpler defining polynomial for K[x]/(R)
%7 = x^10 + (-11/2*y + 25/2)
? liftall(X) \\ root of R in K[x]/(T(x))
%8 = (3/4*y + 7/4)*x^7 + (-1/2*y - 1)*x^5 + 1/2*x^2 + (1/4*y - 1/4)
? a = subst(a.pol, 'x, X); \\
The main variables of P and Q must be the same and have higher priority
than that of nf (see
The library syntax is
| |
| nfdisc(T) |
![]() |
field discriminant of the number field defined by the integral, preferably monic, irreducible polynomial T(X). Returns the discriminant of the number field ℚ[X]/(T), using the Round 4 algorithm. Local discriminants, valuations at certain primes.
As in
In particular, if
? padicdisc(T,p) = p^valuation(nfdisc([T,[p]]), p); ? nfdisc(x^2 + 6) %2 = -24 ? padicdisc(x^2 + 6, 2) %3 = 8 ? padicdisc(x^2 + 6, 3) %4 = 3 The following function computes the discriminant of the maximal order under the assumption that P is a vector of prime numbers containing (at least) all prime divisors of the field discriminant:
globaldisc(T, P) =
{ my (D = nfdisc([T, P]));
sign(D) * vecprod([p^valuation(D,p) | p <-P]);
}
? globaldisc(x^2 + 6, [2, 3, 5])
%1 = -24
The library syntax is
| |
| nfdiscfactors(T) |
![]() |
Given a polynomial T with integer coefficients, return
[D, faD] where D is
? T = x^3 - 6021021*x^2 + 12072210077769*x - 8092423140177664432; ? [D,faD] = nfdiscfactors(T); print(faD); D [3, 3; 500009, 2] %2 = -6750243002187] ? T = x^3 + 9*x^2 + 27*x - 125014250689643346789780229390526092263790263725; ? [D,faD] = nfdiscfactors(T); print(faD); D [3, 3; 1000003, 2] %4 = -27000162000243 ? [D,faD] = nfdiscfactors([T, 10^3]); print(faD) [3, 3; 125007125141751093502187, 2] In the final example, we only get a partial factorization, which is only guaranteed correct at primes ≤ 103.
The function also accept number field structures, for instance as output by
? T = x^3 + 9*x^2 + 27*x - 125014250689643346789780229390526092263790263725; ? nf = nfinit(T); [D,faD] = nfdiscfactors(T); print(faD); D %2 = -27000162000243 ? nf.disc %3 = -27000162000243
The library syntax is
| |
| nfeltadd(nf, x, y) |
![]() |
Given two elements x and y in nf, computes their sum x+y in the number field nf.
? nf = nfinit(1+x^2); ? nfeltadd(nf, 1, x) \\ 1 + I %2 = [1, 1]~
The library syntax is
| |
| nfeltdiv(nf, x, y) |
![]() |
Given two elements x and y in nf, computes their quotient x/y in the number field nf.
The library syntax is
| |
| nfeltdiveuc(nf, x, y) |
![]() |
Given two elements x and y in
nf, computes an algebraic integer q in the number field nf
such that the components of x-qy are reasonably small. In fact, this is
functionally identical to
The library syntax is
| |
| nfeltdivmodpr(nf, x, y, pr) |
![]() |
This function is obsolete, use
Given two elements x
and y in nf and pr a prime ideal in
The library syntax is
| |
| nfeltdivrem(nf, x, y) |
![]() |
Given two elements x and y in nf, gives a two-element row vector [q,r] such that x = qy+r, q is an algebraic integer in nf, and the components of r are reasonably small.
The library syntax is
| |
| nfeltembed(nf, x, {pl}) |
![]() |
Given an element x in the number field nf, return
the (real or) complex embeddings of x specified by optional argument
pl, at the current * pl omitted: return the vector of embeddings at all r1+r2 places;
* pl an integer between 1 and r1+r2: return the
i-th embedding of x, attached to the i-th root of
* pl a vector or
? nf = nfinit('y^3 - 2);
? nf.sign
%2 = [1, 1]
? nfeltembed(nf, 'y)
%3 = [1.25992[...], -0.62996[...] + 1.09112[...]*I]]
? nfeltembed(nf, 'y, 1)
%4 = 1.25992[...]
? nfeltembed(nf, 'y, 3) \\ there are only 2 arch. places
*** at top-level: nfeltembed(nf,'y,3)
*** ^ — — — — — --
*** nfeltembed: domain error in nfeltembed: index > 2
The library syntax is
| |
| nfeltispower(nf, x, n, {&y}) |
![]() |
Returns 1 if x is an n-th power in the number field
? nf = nfinit(1+x^2); ? nfeltispower(nf, -4, 4, &y) %2 = 1 ? y %3 = [-1, -1]~
The library syntax is
| |
| nfeltissquare(nf, x, {&y}) |
![]() |
Returns 1 if x is a square in
? nf = nfinit(1+x^2); ? nfeltissquare(nf, -1, &y) %2 = 1 ? y %3 = [0, -1]~
The library syntax is
| |
| nfeltmod(nf, x, y) |
![]() |
Given two elements x and y in
nf, computes an element r of nf of the form r = x-qy with
q and algebraic integer, and such that r is small. This is functionally
identical to
The library syntax is
| |
| nfeltmul(nf, x, y) |
![]() |
Given two elements x and y in nf, computes their product x*y in the number field nf.
The library syntax is
| |
| nfeltmulmodpr(nf, x, y, pr) |
![]() |
This function is obsolete, use
Given two elements x and
y in nf and pr a prime ideal in
The library syntax is
| |
| nfeltnorm(nf, x) |
![]() |
Returns the absolute norm of x.
The library syntax is
| |
| nfeltpow(nf, x, k) |
![]() |
Given an element x in nf, and a positive or negative integer k, computes xk in the number field nf.
The library syntax is
| |
| nfeltpowmodpr(nf, x, k, pr) |
![]() |
This function is obsolete, use
Given an element x in nf, an integer k and a prime ideal
pr in
The library syntax is
| |
| nfeltreduce(nf, a, id) |
![]() |
Given an ideal id in Hermite normal form and an element a of the number field nf, finds an element r in nf such that a-r belongs to the ideal and r is small.
The library syntax is
| |
| nfeltreducemodpr(nf, x, pr) |
![]() |
This function is obsolete, use
Given an element x of the number field nf and a prime ideal
pr in
The library syntax is
| |
| nfeltsign(nf, x, {pl}) |
![]() |
Given an element x in the number field nf, returns the signs of the real embeddings of x specified by optional argument pl: * pl omitted: return the vector of signs at all r1 real places;
* pl an integer between 1 and r1: return the sign of the
i-th embedding of x, attached to the i-th real root of
* pl a vector or
? nf = nfinit(polsubcyclo(11,5,'y)); \\ Q(cos(2 pi/11))
? nf.sign
%2 = [5, 0]
? x = Mod('y, nf.pol);
? nfeltsign(nf, x)
%4 = [-1, -1, -1, 1, 1]
? nfeltsign(nf, x, 1)
%5 = -1
? nfeltsign(nf, x, [1..4])
%6 = [-1, -1, -1, 1]
? nfeltsign(nf, x, 6) \\ there are only 5 real embeddings
*** at top-level: nfeltsign(nf,x,6)
*** ^ — — — — — --
*** nfeltsign: domain error in nfeltsign: index > 5
The library syntax is
| |
| nfelttrace(nf, x) |
![]() |
Returns the absolute trace of x.
The library syntax is
| |
| nfeltval(nf, x, pr, {&y}) |
![]() |
Given an element x in
nf and a prime ideal pr in the format output by
? nf = nfinit(x^2 + 1); ? P = idealprimedec(nf, 2)[1]; ? nfeltval(nf, x+1, P) %3 = 1
This particular valuation can also be obtained using
If the y argument is present, sets y = x τv, where τ is a
fixed "anti-uniformizer" for pr: its valuation at pr is -1;
its valuation is 0 at other prime ideals dividing
? nfeltval(nf, x+1, P, &y); y %4 = [0, 1]~
For instance if x = ∏i xiei is known to be coprime to
pr, where the xi are algebraic integers and ei ∈ ℤ then,
if vi =
The library syntax is
| |
| nffactor(nf, T) |
![]() |
Factorization of the univariate
polynomial (or rational function) T over the number field nf given
by
The main variable of nf must be of lower
priority than that of T, see Section se:priority. However if
the polynomial defining the number field occurs explicitly in the
coefficients of T as modulus of a
? nf = nfinit(y^2 + 1); ? nffactor(nf, x^2 + y); \\ OK ? nffactor(nf, x^2 + Mod(y, y^2+1)); \\ OK ? nffactor(nf, x^2 + Mod(z, z^2+1)); \\ WRONG
It is possible to input a defining polynomial for nf
instead, but this is in general less efficient since parts of an
Caveat.
The library syntax is
| |
| nffactorback(nf, f, {e}) |
![]() |
Gives back the nf element corresponding to a factorization. The integer 1 corresponds to the empty factorization. If e is present, e and f must be vectors of the same length (e being integral), and the corresponding factorization is the product of the f[i]e[i]. If not, and f is vector, it is understood as in the preceding case with e a vector of 1s: we return the product of the f[i]. Finally, f can be a regular factorization matrix.
? nf = nfinit(y^2+1); ? nffactorback(nf, [3, y+1, [1,2]~], [1, 2, 3]) %2 = [12, -66]~ ? 3 * (I+1)^2 * (1+2*I)^3 %3 = 12 - 66*I
The library syntax is
| |
| nffactormod(nf, Q, pr) |
![]() |
This routine is obsolete, use
Factors the univariate polynomial Q modulo the prime ideal pr in
the number field nf. The coefficients of Q belong to the number
field (scalar, polmod, polynomial, even column vector) and the main variable
of nf must be of lower priority than that of Q (see
Section se:priority). The prime ideal pr is either in
? K = nfinit(y^2+1); ? P = idealprimedec(K, 3)[1]; ? nffactormod(K, x^2 + y*x + 18*y+1, P) %3 = [x + (2*y + 1) 1] [x + (2*y + 2) 1] ? P = nfmodprinit(K, P); \\ convert to nfmodprinit format ? nffactormod(K, x^2 + y*x + 18*y+1) %5 = [x + (2*y + 1) 1] [x + (2*y + 2) 1] Same result, of course, here about 10% faster due to the precomputation.
The library syntax is
| |
| nfgaloisapply(nf, aut, x) |
![]() |
Let nf be a
number field as output by
? nf = nfinit(x^2+1); ? L = nfgaloisconj(nf) %2 = [-x, x]~ ? aut = L[1]; /* the nontrivial automorphism */ ? nfgaloisapply(nf, aut, x) %4 = Mod(-x, x^2 + 1) ? P = idealprimedec(nf,5); /* prime ideals above 5 */ ? nfgaloisapply(nf, aut, P[2]) == P[1] %6 = 0 \\ !!!! ? idealval(nf, nfgaloisapply(nf, aut, P[2]), P[1]) %7 = 1
The surprising failure of the equality test (
The automorphism can also be given as a column vector, representing the
image of
? nf = nfinit(x^3 - 37*x^2 + 74*x - 37); ? aut = nfgaloisconj(nf)[2]; \\ an automorphism in basistoalg form %2 = -31/11*x^2 + 1109/11*x - 925/11 ? AUT = nfalgtobasis(nf, aut); \\ same in algtobasis form %3 = [16, -6, 5]~ ? v = [1, 2, 3]~; nfgaloisapply(nf, aut, v) == nfgaloisapply(nf, AUT, v) %4 = 1 \\ same result... ? for (i=1,10^5, nfgaloisapply(nf, aut, v)) time = 463 ms. ? for (i=1,10^5, nfgaloisapply(nf, AUT, v)) time = 343 ms. \\ but the latter is faster
The library syntax is
| |
| nfgaloisconj(nf, {flag = 0}, {d}) |
![]() |
nf being a number field as output by If no flags or flag = 0, use a combination of flag 4 and 1 and the result is always complete. There is no point whatsoever in using the other flags.
If flag = 1, use
If flag = 4, use This routine can only compute ℚ-automorphisms, but it may be used to get K-automorphism for any base field K as follows:
rnfgaloisconj(nfK, R) = \\ K-automorphisms of L = K[X] / (R)
{
my(polabs, N,al,S, ala,k, vR);
R *= Mod(1, nfK.pol); \\ convert coeffs to polmod elts of K
vR = variable(R);
al = Mod(variable(nfK.pol),nfK.pol);
[polabs,ala,k] = rnfequation(nfK, R, 1);
Rt = if(k==0,R,subst(R,vR,vR-al*k));
N = nfgaloisconj(polabs) % Rt; \\ Q-automorphisms of L
S = select(s->subst(Rt, vR, Mod(s,Rt)) == 0, N);
if (k==0, S, apply(s->subst(s,vR,vR+k*al)-k*al,S));
}
K = nfinit(y^2 + 7);
rnfgaloisconj(K, x^4 - y*x^3 - 3*x^2 + y*x + 1) \\ K-automorphisms of L
The library syntax is
| |
| nfhilbert(nf, a, b, {pr}) |
![]() |
If pr is omitted,
compute the global quadratic Hilbert symbol (a,b) in nf, that
is 1 if x2 - a y2 - b z2 has a non trivial solution (x,y,z) in
nf, and -1 otherwise. Otherwise compute the local symbol modulo
the prime ideal pr, as output by
The quaternion algebra (a,b) over nf can be created with
The library syntax is
Also available is
| |
| nfinit(pol, {flag = 0}) |
![]() |
pol being a nonconstant irreducible polynomial in ℚ[X],
preferably monic and integral, initializes a
number field (or nf) structure attached to the field K defined
by pol. As such, it's a technical object passed as the first argument
to most
nf[1] contains the polynomial pol (
nf[2] contains [r1,r2] (
nf[3] contains the discriminant d(K) (
nf[4] contains the index of nf[1] ( nf[5] is a vector containing 7 matrices M, G, roundG, T, MD, TI, MDI and a vector vP defined as follows: * M is the (r1+r2) x n matrix whose columns represent the numerical values of the conjugates of the elements of the integral basis. * G is an n x n matrix such that T2 = t G G, where T2 is the quadratic form T2(x) = ∑ |σ(x)|2, σ running over the embeddings of K into ℂ. * roundG is a rescaled copy of G, rounded to nearest integers. * T is the n x n matrix whose coefficients are Tr(ωiωj) where the ωi are the elements of the integral basis. Note also that det(T) is equal to the discriminant of the field K. Also, when understood as an ideal, the matrix T-1 generates the codifferent ideal.
* The columns of MD ( * TI is equal to the primitive part of T-1, which has integral coefficients.
* MDI is a two-element representation (for faster
ideal product) of d(K) times the codifferent ideal
(
* vP is the list of prime divisors of the field discriminant,
i.e, the ramified primes (
nf[6] is the vector containing the r1+r2 roots
(
nf[7] is a ℤ-basis for dℤK, where d = [ℤK:ℤ(θ)],
expressed on the powers of θ. The multiplication by
d ensures that all polynomials have integral coefficients
and nf[7] / d ( nf[8] is the n x n integral matrix expressing the power basis in terms of the integral basis, and finally nf[9] is the n x n2 matrix giving the multiplication table of the integral basis.
If a non monic or non integral polynomial is input,
? nf = nfinit(x^3 - 12); \\ initialize number field Q[X] / (X^3 - 12) ? nf.pol \\ defining polynomial %2 = x^3 - 12 ? nf.disc \\ field discriminant %3 = -972 ? nf.index \\ index of power basis order in maximal order %4 = 2 ? nf.zk \\ integer basis, lifted to Q[X] %5 = [1, x, 1/2*x^2] ? nf.sign \\ signature %6 = [1, 1] ? factor(abs(nf.disc )) \\ determines ramified primes %7 = [2 2] [3 5] ? idealfactor(nf, 2) %8 = [[2, [0, 0, -1]~, 3, 1, [0, 1, 0]~] 3] \\ 𝔭23 Huge discriminants, helping nfdisc. In case pol has a huge discriminant which is difficult to factor, it is hard to compute from scratch the maximal order. The following special input formats are also accepted:
* [pol, B] where pol is a monic integral polynomial and
B is the lift of an integer basis, as would be computed by * [pol, B, P] where pol and B are as above (a monic integral polynomial and the lift of an integer basis), and P is the list of ramified primes in the extension.
* [pol,
? pol = polcompositum(x^5 - 101, polcyclo(7))[1]; ? nf = nfinit( [pol, 10^3] ); ? nfcertify(nf) %3 = []
A priori,
In order to explain the meaning of flag, let P =
* 1: return [nf,
* 2: return
Both flags are set automatically when pol is not monic or not
integral: first a linear change of variables is performed, to get a monic
integral polynomial, then
* 4: do not LLL-reduce
? T = polcyclo(307); ? K = nfinit(T); time = 19,390 ms. ? a = idealhnf(K,1-x); time = 477ms ? idealfactor(K, a) time = 294ms ? Kno = nfinit(T, 4); time = 11,256 ms. ? ano = idealhnf(Kno,1-x); \\ no slowdown, even sligthly faster time = 460ms ? idealfactor(Kno, ano) time = 264ms ? nfinit(T, 2); \\ polredbest is very slow in high degree time = 4min, 34,870 ms. ? norml2(%.pol) == norml2(T) \\ and gains nothing here %9 = 1
The library syntax is
*
*
*
| |
| nfisideal(nf, x) |
![]() |
Returns 1 if x is an ideal in the number field nf, 0 otherwise.
The library syntax is
| |
| nfisincl(f, g, {flag = 0}) |
![]() |
Let f and g define number fields, where f and g are irreducible
polynomials in ℚ[X] and nf structures as output by * flag = 0 (default): return a vector of polynomials [a1,...,an] with rational coefficients, representing all distinct embeddings: we have g | f o ai for all i. * flag = 1: return a single polynomial a representing a single embedding; this can be n times faster than the default when the embeddings have huge coefficients. * flag = 2: return a vector of rational functions [r1,...,rn] whose denominators are coprime to g and such that ri % g is the polynomial ai from flag = 0. This variant is always faster than flag = 0 but produces results which are harder to use. If the denominators are hard to invert in ℚ[X]/(g), this may be even faster than flag = 1.
? T = x^6 + 3*x^4 - 6*x^3 + 3*x^2 + 18*x + 10; ? U = x^3 + 3*x^2 + 3*x - 2; ? nfisincl(U, T) %3 = [24/179*x^5-27/179*x^4+80/179*x^3-234/179*x^2+380/179*x+94/179] ? a = nfisincl(U, T, 1) %4 = 24/179*x^5-27/179*x^4+80/179*x^3-234/179*x^2+380/179*x+94/179 ? subst(U, x, Mod(a,T)) %5 = Mod(0, x^6 + 3*x^4 - 6*x^3 + 3*x^2 + 18*x + 10) ? nfisincl(U, T, 2) \\ a as a t_RFRAC %6 = [(2*x^3 - 3*x^2 + 2*x + 4)/(3*x^2 - 1)] ? (a - %[1]) % T %7 = 0 ? #nfisincl(x^2+1, T) \\ two embeddings %8 = 2 \\ same result with nf structures ? L = nfinit(T); K = nfinit(U); v = [a]; ? nfisincl(U, L) == v %10 = 1 ? nfisincl(K, T) == v %11 = 1 ? nfisincl(K, L) == v %12 = 1 \\ comparative bench: an nf is a little faster, esp. for the subfield ? B = 2000; ? for (i=1, B, nfisincl(U,T)) time = 1,364 ms. ? for (i=1, B, nfisincl(K,T)) time = 988 ms. ? for (i=1, B, nfisincl(U,L)) time = 1,341 ms. ? for (i=1, B, nfisincl(K,L)) time = 880 ms.
Using an nf structure for the tentative subfield is
faster if the structure is already available. On the other hand, the gain in
? for (i=1, B, nfinit(U)) time = 590 ms. A final more complicated example
? f = x^8 - 72*x^6 + 1944*x^4 - 30228*x^2 - 62100*x - 34749; ? g = nfsplitting(f); poldegree(g) %2 = 96 ? #nfisincl(f, g) time = 559 ms. %3 = 8 ? nfisincl(f,g,1); time = 172 ms. ? v = nfisincl(f,g,2); time = 199 ms. ? apply(x->poldegree(denominator(x)), v) %6 = [81, 81, 81, 81, 81, 81, 80, 81] ? v % g; time = 407 ms.
This final example shows that mapping rational functions to
ℚ[X]/(g) can be more costly than that the rest of the algorithm. Note that
The library syntax is
| |
| nfisisom(f, g) |
![]() |
As
? f = x^6 + 30*x^5 + 495*x^4 + 1870*x^3 + 16317*x^2 - 22560*x + 59648; ? g = x^6 + 42*x^5 + 999*x^4 + 8966*x^3 + 36117*x^2 + 21768*x + 159332; ? h = x^6 + 30*x^5 + 351*x^4 + 2240*x^3 + 10311*x^2 + 35466*x + 58321; ? #nfisisom(f,g) \\ two isomorphisms %3 = 2 ? nfisisom(f,h) \\ not isomorphic %4 = 0 \\ comparative bench ? K = nfinit(f); L = nfinit(g); B = 10^3; ? for (i=1, B, nfisisom(f,g)) time = 6,124 ms. ? for (i=1, B, nfisisom(K,g)) time = 3,356 ms. ? for (i=1, B, nfisisom(f,L)) time = 3,204 ms. ? for (i=1, B, nfisisom(K,L)) time = 3,173 ms. The function is usually very fast when the fields are nonisomorphic, whenever the fields can be distinguished via a simple invariant such as degree, signature or discriminant. It may be slower when the fields share all invariants, but still faster than computing actual isomorphisms:
\\ usually very fast when the answer is 'no': ? for (i=1, B, nfisisom(f,h)) time = 32 ms. \\ but not always ? u = x^6 + 12*x^5 + 6*x^4 - 377*x^3 - 714*x^2 + 5304*x + 15379 ? v = x^6 + 12*x^5 + 60*x^4 + 166*x^3 + 708*x^2 + 6600*x + 23353 ? nfisisom(u,v) %13 = 0 ? polsturm(u) == polsturm(v) %14 = 1 ? nfdisc(u) == nfdisc(v) %15 = 1 ? for(i=1,B, nfisisom(u,v)) time = 1,821 ms. ? K = nfinit(u); L = nfinit(v); ? for(i=1,B, nfisisom(K,v)) time = 232 ms.
The library syntax is
| |
| nfislocalpower(nf, pr, a, n) |
![]() |
Let nf be a nf structure attached to a number field K, let a ∈ K and let pr be a prid structure attached to a maximal ideal v. Return 1 if a is an n-th power in the completed local field Kv, and 0 otherwise.
? K = nfinit(y^2+1); ? P = idealprimedec(K,2)[1]; \\ the ramified prime above 2 ? nfislocalpower(K,P,-1, 2) \\ -1 is a square %3 = 1 ? nfislocalpower(K,P,-1, 4) \\ ... but not a 4-th power %4 = 0 ? nfislocalpower(K,P,2, 2) \\ 2 is not a square %5 = 0 ? Q = idealprimedec(K,5)[1]; \\ a prime above 5 ? nfislocalpower(K,Q, [0, 32]~, 30) \\ 32*I is locally a 30-th power %7 = 1
The library syntax is
| |
| nfkermodpr(nf, x, pr) |
![]() |
This function is obsolete, use
Kernel of the matrix a in ℤK/pr, where pr is in
modpr format (see
The library syntax is
| |
| nfmodpr(nf, x, pr) |
![]() |
Map x to a
Note that the function applies to number field elements and not to
vector / matrices / polynomials of such. Use
? K = nfinit(y^3-250); ? P = idealprimedec(K, 5)[2]; ? modP = nfmodprinit(K, P, 't); ? K.zk %4 = [1, 1/5*y, 1/25*y^2] ? apply(t->nfmodpr(K,t,modP), K.zk) %5 = [1, t, 2*t + 1] ? %[1].mod %6 = t^2 + 3*t + 4 ? K.index %7 = 125
For clarity, we represent elements in the residue
field 𝔽5[t]/(T) as polynomials in the variable t. Whenever the
underlying rational prime does not divide Elements can be given in factored form if their global valuation at pr is non-negative.
? nfmodpr(K, [y/5, 2; 1+y, 3], modP) \\ (y/5)^2 * (1 + y)^3 %8 = 2*t + 1 ? nfmodpr(K, [y, -1; 1+y, 3], modP) \\ negative valuation at pr *** at top-level: nfmodpr(K,[y,-1;1+y,3],modP) *** ^ — — — — — — — — — - *** nfmodpr: impossible inverse in nfmodpr: Mod(0, 5).
The library syntax is
| |
| nfmodprinit(nf, pr, {v = variable(nf.pol)}) |
![]() |
Transforms the prime ideal pr into
? K = nfinit(y^3-250); ? P = idealprimedec(K, 5)[2]; ? modP = nfmodprinit(K, P, 't); ? K.zk %4 = [1, 1/5*y, 1/25*y^2] ? apply(t->nfmodpr(K,t,modP), K.zk) %5 = [1, t, 2*t + 1] ? %[1].mod %6 = t^2 + 3*t + 4 ? K.index %7 = 125
For clarity, we represent elements in the residue
field 𝔽5[t]/(T) as polynomials in the variable t. Whenever the
underlying rational prime does not divide
The library syntax is
| |
| nfmodprlift(nf, x, pr) |
![]() |
Lift an element x from in the residue field modulo pr to the ring
of integers; x is a
The argument pr is either a maximal ideal in
The function
? K = nfinit(y^3-250); ? P = idealprimedec(K, 5)[2]; ? modP = nfmodprinit(K,P); ? K.zk %4 = [1, 1/5*y, 1/25*y^2] ? apply(t->nfmodpr(K,t,modP), K.zk) %5 = [1, y, 2*y + 1] ? nfmodprlift(K, %, modP) %6 = [1, 1/5*y, 2/5*y + 1] ? nfeltval(K, %[3] - K.zk[3], P) %7 = 1
The library syntax is
| |
| nfnewprec(nf) |
![]() |
Transforms the number field nf
into the corresponding data using current (usually larger) precision. This
function works as expected if nf is in fact a bnf, a bnr
or a rnf (update structure to current precision). If the original
bnf structure was not computed by
The library syntax is
| |
| nfpolsturm(nf, T, {pl}) |
![]() |
Given a polynomial T with coefficients in the number field nf, returns the number of real roots of the s(T) where s runs through the real embeddings of the field specified by optional argument pl: * pl omitted: all r1 real places;
* pl an integer between 1 and r1: the embedding attached to
the i-th real root of
* pl a vector or
? nf = nfinit('y^2 - 2);
? nf.sign
%2 = [2, 0]
? nf.roots
%3 = [-1.414..., 1.414...]
? T = x^2 + 'y;
? nfpolsturm(nf, T, 1) \\ subst(T,y,sqrt(2)) has two real roots
%5 = 2
? nfpolsturm(nf, T, 2) \\ subst(T,y,-sqrt(2)) has no real root
%6 = 0
? nfpolsturm(nf, T) \\ all embeddings together
%7 = [2, 0]
? nfpolsturm(nf, T, [2,1]) \\ second then first embedding
%8 = [0, 2]
? nfpolsturm(nf, x^3) \\ number of distinct roots !
%9 = [1, 1]
? nfpolsturm(nf, x, 6) \\ there are only 2 real embeddings !
*** at top-level: nfpolsturm(nf,x,6)
*** ^ — — — — — --
*** nfpolsturm: domain error in nfpolsturm: index > 2
The library syntax is
| |
| nfroots({nf}, x) |
![]() |
Roots of the polynomial x in the
number field nf given by
It is possible to input a defining polynomial for nf
instead, but this is in general less efficient since parts of an
Caveat.
The library syntax is
| |
| nfrootsof1(nf) |
![]() |
Returns a two-component vector [w,z] where w is the number of roots of unity in the number field nf, and z is a primitive w-th root of unity. It is possible to input a defining polynomial for nf instead.
? K = nfinit(polcyclo(11)); ? nfrootsof1(K) %2 = [22, [0, 0, 0, 0, 0, -1, 0, 0, 0, 0]~] ? z = nfbasistoalg(K, %[2]) \\ in algebraic form %3 = Mod(-x^5, x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1) ? [lift(z^11), lift(z^2)] \\ proves that the order of z is 22 %4 = [-1, -x^9 - x^8 - x^7 - x^6 - x^5 - x^4 - x^3 - x^2 - x - 1] This function guesses the number w as the gcd of the #k(v)* for unramified v above odd primes, then computes the roots in nf of the w-th cyclotomic polynomial. The algorithm is polynomial time with respect to the field degree and the bitsize of the multiplication table in nf (both of them polynomially bounded in terms of the size of the discriminant). Fields of degree up to 100 or so should require less than one minute.
The library syntax is
| |
| nfsolvemodpr(nf, a, b, P) |
![]() |
This function is obsolete, use
Let P be a prime ideal in modpr format (see
? K = nfinit(y^2+1); ? P = idealprimedec(K, 3)[1]; ? P = nfmodprinit(K, P); ? a = [y+1, y; y, 0]; b = [1, y]~ ? nfsolvemodpr(K, a,b, P) %5 = [1, 2]~
The library syntax is
| |
| nfsplitting(P, {d}, {fl}) |
![]() |
Defining polynomial S over ℚ for the splitting field of
P ∈ ℚ[x], that is the smallest field over which P is totally
split. If irreducible, the polynomial P can also be given by a If flag is non-zero, we assume P to be monic, integral and irreducible and the return value depends on flag:
* flag = 1: return [S,C] where S is as before and C is an
embedding of ℚ[x]/(P) in its splitting field given by a polynomial
(implicitly modulo S, as in * flag = 2: return [S,C] where C is vector of rational functions whose image in ℚ[x]/(S) yields the embedding; this avoids inverting the denominator, which is costly. when the degree of the splitting field is huge.
* flag = 3: return [S, v, p] a data structure allowing to quickly
compute the Galois group of the splitting field, which is used by
? K = nfinit(x^3 - 2); ? nfsplitting(K) %2 = x^6 + 108 ? nfsplitting(x^8 - 2) %3 = x^16 + 272*x^8 + 64 ? S = nfsplitting(x^6 - 8) \\ reducible %4 = x^4 + 2*x^2 + 4 ? lift(nfroots(subst(S,x,a),x^6-8)) %5 = [-a, a, -1/2*a^3 - a, -1/2*a^3, 1/2*a^3, 1/2*a^3 + a] ? P = x^8-2; ? [S,C] = nfsplitting(P,,1) %7 = [x^16 + 272*x^8 + 64, -7/768*x^13 - 239/96*x^5 + 1/2*x] ? subst(P, x, Mod(C,S)) %8 = Mod(0, x^16 + 272*x^8 + 64) Specifying the degree d of the splitting field can make the computation faster; if d is not a multiple of the true degree, it will be ignored with a warning.
? nfsplitting(x^17-123); time = 3,607 ms. ? poldegree(%) %2 = 272 ? nfsplitting(x^17-123,272); time = 150 ms. ? nfsplitting(x^17-123,273); *** nfsplitting: Warning: ignoring incorrect degree bound 273 time = 3,611 ms. The complexity of the algorithm is polynomial in the degree d of the
splitting field and the bitsize of T; if d is large the result will
likely be unusable, e.g.
? nfsplitting(x^6-x-1) [... degree 720 polynomial deleted ...] time = 11,020 ms.
Variant: Also available is
The library syntax is
| |
| nfsubfields(pol, {d = 0}, {flag = 0}) |
![]() |
Finds all subfields of degree d of the number field defined by the (monic, integral) polynomial pol (all subfields if d is null or omitted). The result is a vector of subfields, each being given by [g,h] (default) or simply g (flag = 1), where g is an absolute equation and h expresses one of the roots of g in terms of the root x of the polynomial defining nf. This routine uses
* Allombert's * Klüners's or van Hoeij-Klüners-Novocin algorithm in the general case. The latter runs in polynomial time and is generally superior unless there exists a small unramified prime p such that pol has few irreducible factors modulo p.
An input of the form
? pol = x^4 - x^3 - x^2 + x + 1;
? nfsubfields(pol)
%2 = [[x, 0], [x^2 - x + 1, x^3 - x^2 + 1], [x^4 - x^3 - x^2 + x + 1, x]]
? nfsubfields(pol,,1)
%2 = [x, x^2 - x + 1, x^4 - x^3 - x^2 + x + 1]
? y=varhigher("y"); fa = nffactor(pol,subst(pol,x,y));
? #nfsubfields([pol,fa])
%5 = 3
The library syntax is
| |
| nfsubfieldscm(nf, {flag = 0}) |
![]() |
Computes the maximal CM subfield of nf. Returns 0 if nf does
not have a CM subfield, otherwise returns [g,h] (default) or g (flag = 1)
where g is an absolute equation and h expresses a root of g in terms of
the generator of nf.
Moreover, the CM involution is given by X mod g(X)
An input of the form
? nf = nfinit(x^8 + 20*x^6 + 10*x^4 - 4*x^2 + 9); ? nfsubfieldscm(nf) %2 = [x^4 + 4480*x^2 + 3612672, 3*x^5 + 58*x^3 + 5*x] ? pol = y^16-8*y^14+29*y^12-60*y^10+74*y^8-48*y^6+8*y^4+4*y^2+1; ? fa = nffactor(pol, subst(pol,y,x)); ? nfsubfieldscm([pol,fa]) %5 = [y^8 + ... , ...]
The library syntax is
| |
| nfsubfieldsmax(nf, {flag = 0}) |
![]() |
Computes the list of maximal subfields of nf. The result is a vector
as in
An input of the form
The library syntax is
| |
| nfweilheight(nf, v) |
![]() |
Let nf be attached to a number field K, let v be a vector of
elements of K, not all of them 0, seen as element of the projective
space of dimension
When the entries of v are rational, the height is
? v = [1, 2, -3, 101]; Q = nfinit(x); Qi = nfinit(x^2 + 1); ? exponent(nfweilheight(Q, v) - log(101)) %2 = -125 ? exponent(nfweilheight(Qi, v) - log(101)) %3 = -125
The library syntax is
| |
| polcompositum(P, Q, {flag = 0}) |
![]() |
P and Q being squarefree polynomials in ℤ[X] in the same variable, outputs the simple factors of the étale ℚ-algebra A = ℚ(X, Y) / (P(X), Q(Y)). The factors are given by a list of polynomials R in ℤ[X], attached to the number field ℚ(X)/ (R), and sorted by increasing degree (with respect to lexicographic ordering for factors of equal degrees). Returns an error if one of the polynomials is not squarefree. Note that it is more efficient to reduce to the case where P and Q are irreducible first. The routine will not perform this for you, since it may be expensive, and the inputs are irreducible in most applications anyway. In this case, there will be a single factor R if and only if the number fields defined by P and Q are linearly disjoint (their intersection is ℚ). Assuming P is irreducible (of smaller degree than Q for efficiency), it is in general much faster to proceed as follows
nf = nfinit(P); L = nffactor(nf, Q)[,1]; vector(#L, i, rnfequation(nf, L[i]))
to obtain the same result. If you are only interested in the degrees of the
simple factors, the The binary digits of flag mean 1: outputs a vector of 4-component vectors [R,a,b,k], where R ranges through the list of all possible compositums as above, and a (resp. b) expresses the root of P (resp. Q) as an element of ℚ(X)/(R). Finally, k is a small integer such that b + ka = X modulo R. 2: assume that P and Q define number fields which are linearly disjoint: both polynomials are irreducible and the corresponding number fields have no common subfield besides ℚ. This allows to save a costly factorization over ℚ. In this case return the single simple factor instead of a vector with one element. A compositum is often defined by a complicated polynomial, which it is advisable to reduce before further work. Here is an example involving the field ℚ(ζ5, 51/5):
? L = polcompositum(x^5 - 5, polcyclo(5), 1); \\ list of [R,a,b,k]
? [R, a] = L[1]; \\ pick the single factor, extract R,a (ignore b,k)
? R \\ defines the compositum
%3 = x^20 + 5*x^19 + 15*x^18 + 35*x^17 + 70*x^16 + 141*x^15 + 260*x^14\
+ 355*x^13 + 95*x^12 - 1460*x^11 - 3279*x^10 - 3660*x^9 - 2005*x^8 \
+ 705*x^7 + 9210*x^6 + 13506*x^5 + 7145*x^4 - 2740*x^3 + 1040*x^2 \
- 320*x + 256
? a^5 - 5 \\ a fifth root of 5
%4 = 0
? [T, X] = polredbest(R, 1);
? T \\ simpler defining polynomial for ℚ[x]/(R)
%6 = x^20 + 25*x^10 + 5
? X \\ root of R in ℚ[y]/(T(y))
%7 = Mod(-1/11*x^15 - 1/11*x^14 + 1/22*x^10 - 47/22*x^5 - 29/11*x^4 + 7/22,\
x^20 + 25*x^10 + 5)
? a = subst(a.pol, 'x, X) \\ In the above example, x5-5 and the 5-th cyclotomic polynomial are irreducible over ℚ; they have coprime degrees so define linearly disjoint extensions and we could have started by
? [R,a] = polcompositum(x^5 - 5, polcyclo(5), 3); \\ [R,a,b,k]
The library syntax is
| |
| polgalois(T) |
![]() |
Galois group of the nonconstant
polynomial T ∈ ℚ[X]. In the present version 2.19.0, T must be irreducible
and the degree d of T must be less than or equal to 7. If the
The output is a 4-component vector [n,s,k,name] with the following meaning: n is the cardinality of the group, s is its signature (s = 1 if the group is a subgroup of the alternating group Ad, s = -1 otherwise) and name is a character string containing name of the transitive group according to the GAP 4 transitive groups library by Alexander Hulpke. k is the numbering of the group among all transitive subgroups of Sd, as given in "The transitive groups of degree up to eleven", G. Butler and J. McKay, Communications in Algebra, vol. 11, 1983, pp. 863–911 (group k is denoted Tk there). Specifically, for polynomials of degree d ≤ 7, the groups are coded as follows, using standard notations In degree 1: S1 = [1,1,1]. In degree 2: S2 = [2,-1,1]. In degree 3: A3 = C3 = [3,1,1], S3 = [6,-1,2]. In degree 4: C4 = [4,-1,1], V4 = [4,1,2], D4 = [8,-1,3], A4 = [12,1,4], S4 = [24,-1,5]. In degree 5: C5 = [5,1,1], D5 = [10,1,2], M20 = [20,-1,3], A5 = [60,1,4], S5 = [120,-1,5]. In degree 6: C6 = [6,-1,1], S3 = [6,-1,2], D6 = [12,-1,3], A4 = [12,1,4], G18 = [18,-1,5], A4 x C2 = [24,-1,6], S4+ = [24,1,7], S4− = [24,-1,8], G36− = [36,-1,9], G36+ = [36,1,10], S4 x C2 = [48,-1,11], A5 = PSL2(5) = [60,1,12], G72 = [72,-1,13], S5 = PGL2(5) = [120,-1,14], A6 = [360,1,15], S6 = [720,-1,16]. In degree 7: C7 = [7,1,1], D7 = [14,-1,2], M21 = [21,1,3], M42 = [42,-1,4], PSL2(7) = PSL3(2) = [168,1,5], A7 = [2520,1,6], S7 = [5040,-1,7].
For compatibility with older PARI/GP versions, when In degree 1: S1 = [1,1,1]. In degree 2: S2 = [2,-1,1]. In degree 3: A3 = C3 = [3,1,1], S3 = [6,-1,1]. In degree 4: C4 = [4,-1,1], V4 = [4,1,1], D4 = [8,-1,1], A4 = [12,1,1], S4 = [24,-1,1]. In degree 5: C5 = [5,1,1], D5 = [10,1,1], M20 = [20,-1,1], A5 = [60,1,1], S5 = [120,-1,1]. In degree 6: C6 = [6,-1,1], S3 = [6,-1,2], D6 = [12,-1,1], A4 = [12,1,1], G18 = [18,-1,1], S4− = [24,-1,1], A4 x C2 = [24,-1,2], S4+ = [24,1,1], G36− = [36,-1,1], G36+ = [36,1,1], S4 x C2 = [48,-1,1], A5 = PSL2(5) = [60,1,1], G72 = [72,-1,1], S5 = PGL2(5) = [120,-1,1], A6 = [360,1,1], S6 = [720,-1,1]. In degree 7: C7 = [7,1,1], D7 = [14,-1,1], M21 = [21,1,1], M42 = [42,-1,1], PSL2(7) = PSL3(2) = [168,1,1], A7 = [2520,1,1], S7 = [5040,-1,1]. Warning. The method used is that of resolvent polynomials and is sensitive to the current precision. The precision is updated internally but, in very rare cases, a wrong result may be returned if the initial precision was not sufficient.
The library syntax is
| |
| polred(T, {flag = 0}) |
![]() |
This function is deprecated, use
All T accepted by The following binary digits of flag are significant:
1: Possibly use a suborder of the maximal order. The
primes dividing the index of the order chosen are larger than
2: gives also elements. The result is a two-column matrix, the first column giving primitive elements defining these subalgebras, the second giving the corresponding minimal polynomials.
? M = polred(x^4 + 8, 2) %1 = [ 1 x - 1] [ 1/2*x^2 + 1 x^2 - 2*x + 3] [-1/2*x^2 + 1 x^2 - 2*x + 3] [ 1/2*x^2 x^2 + 2] [ 1/4*x^3 x^4 + 2] ? minpoly(Mod(M[4,1], x^4+8)) %2 = x^2 + 2
The library syntax is
| |
| polredabs(T, {flag = 0}) |
![]() |
Let T be a separable polynomial with rational coefficients and consider the étale algebra A = ℚ[x]/(T). Returns a canonical defining polynomial P defining A ~ Q[x]/(P), such that the sum of the squares of the modulus of the roots (i.e. the T2-norm) is minimal. This is mostly useful when T is irreducible and A is a number field, else you should probably first factor T, thereby factoring A as a product of number fields.
Different T defining
isomorphic algebras will yield the same P. All T accepted by
? polredabs(x^2 + 16) %1 = x^2 + 1 ? K = bnfinit(x^2 + 16); polredabs(K) %2 = x^2 + 1
Warning 1. Using a
Warning 2. Apart from the factorization of the discriminant of
T, this routine runs in polynomial time for a fixed degree.
But the complexity is exponential in the degree: this routine
may be exceedingly slow. If you do not need a canonical
polynomial, the function The binary digits of flag mean
1: outputs a two-component row vector [P,a], where P is the default
output and 4: gives all polynomials of minimal T2 norm; of the two polynomials P(x) and ± P(-x), only one is given.
16: (OBSOLETE) Possibly use a suborder of the maximal order, without
attempting to certify the result as in Warning 1. This makes
? T = x^16 - 136*x^14 + 6476*x^12 - 141912*x^10 + 1513334*x^8 \
- 7453176*x^6 + 13950764*x^4 - 5596840*x^2 + 46225
? T1 = polredabs(T); T2 = polredbest(T);
? [ norml2(polroots(T1)), norml2(polroots(T2)) ]
%3 = [88.0000000, 120.000000]
? [ sizedigit(poldisc(T1)), sizedigit(poldisc(T2)) ]
%4 = [75, 67]
The precise definition of the output of * Consider the finite list of characteristic polynomials of primitive elements of K that are in ℤK and minimal for the T2 norm; now remove from the list the polynomials whose discriminant do not have minimal absolute value. Note that this condition is restricted to the original list of polynomials with minimal T2 norm and does not imply that the defining polynomial for the algebra with smallest discriminant belongs to the list !
* To a polynomial P(x) = xn +...+ an ∈ ℝ[x] we attach
the sequence S(P) given by |a1|, a1,..., |an|, an.
Order the polynomials P by the lexicographic order on the coefficient
vectors S(P). Then the output of
The library syntax is
*
*
*
*
| |
| polredbest(T, {flag = 0}) |
![]() |
Let T be a separable polynomial with rational coefficients and consider the étale algebra A = ℚ[X]/(T). Finds a polynomial P with reasonably small coefficients defining the same algebra A ~ Q[X]/(P). This is mostly useful when T is irreducible and A is a number field, else you should probably first factor T, thereby factoring A as a product of number fields.
All T accepted by
This routine computes an LLL-reduced basis for an order in ℚ[X]/(T), then
examines small linear combinations of the basis vectors, computing their
characteristic polynomials. It returns the separable polynomial P of
smallest discriminant, the one with lexicographically smallest
It can happen that iterating this functions yields better and better polynomials, until it stabilizes:
? \p5 ? P = X^12+8*X^8-50*X^6+16*X^4-3069*X^2+625; ? poldisc(P)*1. %2 = 1.2622 E55 ? P = polredbest(P); ? poldisc(P)*1. %4 = 2.9012 E51 ? P = polredbest(P); ? poldisc(P)*1. %6 = 8.8704 E44
In this example, the initial polynomial P is the one
returned by
If flag = 1: outputs a two-component row vector [P,a], where P is the
default output and
? [P,a] = polredbest(x^4 + 8, 1) %1 = [x^4 + 2, Mod(x^3, x^4 + 2)] ? charpoly(a) %2 = x^4 + 8
In particular, the map ℚ[x]/(T) → ℚ[x]/(P),
x
subst(lift(Q), 'x, a)
if Q is a
The library syntax is
| |
| polredord(x) |
![]() |
This function is obsolete, use polredbest.
The library syntax is
| |
| poltschirnhaus(x) |
![]() |
Applies a random Tschirnhausen
transformation to the polynomial x, which is assumed to be nonconstant
and separable, so as to obtain a new equation for the étale algebra
defined by x. This is for instance useful when computing resolvents,
hence is used by the
The library syntax is
| |
| rnfpolredabs(nf, pol, {flag = 0}) |
![]() |
Relative version of The binary digits of flag correspond to 1: add information to convert elements to the new representation, 2: absolute polynomial, instead of relative, 16: possibly use a suborder of the maximal order. More precisely: 0: default, return P
1: returns [P,a] where P is the default output and a,
a 2: returns Pabs, an absolute, instead of a relative, polynomial. This polynomial is canonical and does not depend on the nf structure. Same as but faster than
polredabs(rnfequation(nf, pol))
3: returns [Pabs,a,b], where Pabs is an absolute polynomial
as above, a, b are
16: (OBSOLETE) possibly use a suborder of the maximal order. This makes
Warning. The complexity of
The library syntax is
| |
| rnfpolredbest(nf, pol, {flag = 0}) |
![]() |
Relative version of The binary digits of flag correspond to 1: add information to convert elements to the new representation, 2: absolute polynomial, instead of relative. More precisely: 0: default, return P
1: returns [P,a] where P is the default output and a,
a 2: returns Pabs, an absolute, instead of a relative, polynomial. Same as but faster than
rnfequation(nf, rnfpolredbest(nf,pol))
3: returns [Pabs,a,b], where Pabs is an absolute polynomial
as above, a, b are
? K = nfinit(y^3-2); pol = x^2 +x*y + y^2;
? [P, a] = rnfpolredbest(K,pol,1);
? P
%3 = x^2 - x + Mod(y - 1, y^3 - 2)
? a
%4 = Mod(Mod(2*y^2+3*y+4,y^3-2)*x + Mod(-y^2-2*y-2,y^3-2),
x^2 - x + Mod(y-1,y^3-2))
? subst(K.pol,y,a)
%5 = 0
? [Pabs, a, b] = rnfpolredbest(K,pol,3);
? Pabs
%7 = x^6 - 3*x^5 + 5*x^3 - 3*x + 1
? a
%8 = Mod(-x^2+x+1, x^6-3*x^5+5*x^3-3*x+1)
? b
%9 = Mod(2*x^5-5*x^4-3*x^3+10*x^2+5*x-5, x^6-3*x^5+5*x^3-3*x+1)
? subst(K.pol,y,a)
%10 = 0
? substvec(pol,[x,y],[a,b])
%11 = 0
The library syntax is
| |
| rnfpseudobasis(nf, T) |
![]() |
Given an nf structure attached to a number field K, as output by
? K = nfinit(y^2+1); ? [A,J,D,d] = rnfpseudobasis(K, x^2+y); ? A %3 = [1 0] [0 1] ? J %4 = [1, 1] ? D %5 = [0, -4]~ ? d %6 = [0, -1]~
Huge discriminants, helping rnfdisc. The format [T,B] is
also accepted instead of T and produce an order which is maximal at all
prime ideals specified by B, see
? p = 585403248812100232206609398101; ? q = 711171340236468512951957953369; ? T = x^2 + 3*(p*q)^2; ? [A,J,D,d] = V = rnfpseudobasis(K, T); D time = 22,178 ms. %10 = 3 ? [A,J,D,d] = W = rnfpseudobasis(K, [T,100]); D time = 5 ms. %11 = 3 ? V == W %12 = 1 ? [A,J,D,d] = W = rnfpseudobasis(K, [T, [3]]); D %13 = 3 ? V == W %14 = 1 In this example, the results are identical since D ∩ ℤ factors over primes less than 100 (and in fact, over 3). Had it not been the case, the order would have been guaranteed maximal at primes 𝔭 | p for p ≤ 100 only (resp. 𝔭 | 3). And might have been nonmaximal at any other prime ideal 𝔭 such that 𝔭2 divided D.
The library syntax is
| |
| rnfsteinitz(nf, M) |
![]() |
Given a nf attached to a number field K and a projective
module M given by a pseudo-matrix, returns a pseudo-basis (A,I)
(not in HNF in general) such that all the ideals of I except perhaps the
last one are equal to the ring of integers of nf. If M is a
polynomial with coefficients in K, replace it by the pseudo-matrix
returned by
The library syntax is
| |
| subgrouplist(cyc, {bound}, {flag = 0}) |
![]() |
cyc being a vector of positive integers giving the cyclic
components for a finite Abelian group G (or any object which has a
If flag = 0 (default) and cyc is a bnr structure output by
If bound is present, and is a positive integer, restrict the output to subgroups of index less than bound. If bound is a vector containing a single positive integer B, then only subgroups of index exactly equal to B are computed. For instance
? subgrouplist([6,2]) %1 = [[6, 0; 0, 2], [2, 0; 0, 2], [6, 3; 0, 1], [2, 1; 0, 1], [3, 0; 0, 2], [1, 0; 0, 2], [6, 0; 0, 1], [2, 0; 0, 1], [3, 0; 0, 1], [1, 0; 0, 1]] ? subgrouplist([6,2],3) \\ index less than 3 %2 = [[2, 1; 0, 1], [1, 0; 0, 2], [2, 0; 0, 1], [3, 0; 0, 1], [1, 0; 0, 1]] ? subgrouplist([6,2],[3]) \\ index 3 %3 = [[3, 0; 0, 1]] ? bnr = bnrinit(bnfinit(x), [120,[1]], 1); ? L = subgrouplist(bnr, [8]); In the last example, L corresponds to the 24 subfields of ℚ(ζ120), of degree 8 and conductor 120 oo (by setting flag, we see there are a total of 43 subgroups of degree 8).
? vector(#L, i, galoissubcyclo(bnr, L[i]))
will produce their equations. (For a general base field, you would
have to rely on
Warning. This function requires factoring the exponent of G.
If you are only interested in subgroups of index n (or dividing n), you
may considerably speed up the function by computing the subgroups of
G/Gn, whose cyclic components are
The library syntax is
| |