Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is to exceed 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - basemath - bnflog.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.12.0 lcov report (development 23036-b751c0af5) Lines: 273 278 98.2 %
Date: 2018-09-26 05:46:06 Functions: 24 24 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2016  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8             : ANY WARRANTY WHATSOEVER.
       9             : 
      10             : Check the License for details. You should have received a copy of it, along
      11             : with the package; see the file 'COPYING'. If not, write to the Free Software
      12             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      13             : 
      14             : #include "pari.h"
      15             : #include "paripriv.h"
      16             : /*******************************************************************/
      17             : /*                  LOGARITHMIC CLASS GROUP                        */
      18             : /*******************************************************************/
      19             : /* min(v, v(Log_p Norm_{F_\p/Q_p}(x))) */
      20             : static long
      21         280 : vlognorm(GEN nf, GEN T, GEN x, GEN p, long v)
      22             : {
      23         280 :   GEN a = nf_to_scalar_or_alg(nf, x);
      24         280 :   GEN N = RgXQ_norm(a, T);
      25         280 :   if (typ(N) != t_PADIC) N = cvtop(N, p, v);
      26         280 :   return minss(v, valp( Qp_log(N) ));
      27             : }
      28             : /* K number field, pr a maximal ideal, let K_pr be the attached local
      29             :  * field, K_pr = Q_p[X] / (T), T irreducible. Return \tilde{e}(K_pr/Q_p) */
      30             : static long
      31         546 : etilde(GEN nf, GEN pr, GEN T)
      32             : {
      33         546 :   GEN gp = pr_get_p(pr);
      34         546 :   ulong e = pr_get_e(pr);
      35             :   long v, voo, vmin, p, k;
      36             : 
      37         546 :   if (!u_pval(e, gp))
      38             :   {
      39         448 :     v = u_pval(pr_get_f(pr), gp);
      40         448 :     return itou( mului(e, powiu(gp, v)) );
      41             :   }
      42          98 :   nf = checknf(nf);
      43          98 :   p = itou(gp);
      44          98 :   k = e / (p-1) + 1;
      45             :   /* log Norm_{F_P/Q_p} (1 + P^k) = Tr(P^k) = p^[(k + v(Diff))/ e] Z_p */
      46          98 :   voo = (k + idealval(nf, nf_get_diff(nf), pr)) / e;
      47          98 :   vmin = vlognorm(nf, T, pr_get_gen(pr), gp, voo);
      48          98 :   if (k > 1)
      49             :   {
      50          98 :     GEN U = idealprincipalunits(nf, pr, k);
      51          98 :     GEN gen = abgrp_get_gen(U), cyc = abgrp_get_cyc(U);
      52          98 :     long i, l = lg(cyc);
      53         280 :     for (i = 1; i < l; i++)
      54             :     {
      55         182 :       if (voo - Z_lval(gel(cyc,i), p) >= vmin) break;
      56         182 :       vmin = vlognorm(nf, T, gel(gen,i), gp, vmin);
      57             :     }
      58             :   }
      59          98 :   v = u_lval(degpol(T), p) + (p == 2UL? 2 : 1) - vmin;
      60          98 :   (void)u_lvalrem(e, p, &e);
      61          98 :   return e * upowuu(p,v);
      62             : }
      63             : static long
      64         483 : ftilde_from_e(GEN pr, long e) { return pr_get_e(pr) * pr_get_f(pr) / e; }
      65             : static long
      66         483 : ftilde(GEN K, GEN pr, GEN T) { return ftilde_from_e(pr, etilde(K,pr, T)); }
      67             : 
      68             : static long
      69         553 : get_ZpX_index(GEN K, GEN pr, GEN T)
      70             : {
      71             :   GEN p, pi;
      72         553 :   long j, l = lg(T);
      73         553 :   if (l == 2) return 1;
      74         434 :   p = pr_get_p(pr); pi = nf_to_scalar_or_alg(K, pr_get_gen(pr));
      75        1323 :   for (j = 1; j < l; j++)
      76             :   {
      77        1323 :     GEN t = gel(T,j);
      78        1323 :     if (t && gvaluation(RgXQ_norm(pi, t), p)) return j;
      79             :   }
      80           0 :   return 0;
      81             : }
      82             : 
      83             : /* Given a number field K and a prime p, return
      84             :  * S = places of K above p [primedec]
      85             :  * R = corresponding p-adic factors of K.pol (mod p^k), in the same order */
      86             : static GEN
      87         238 : padicfact(GEN K, GEN S, long k)
      88             : {
      89         238 :     GEN R, p = pr_get_p(gel(S,1));
      90         238 :   GEN T = gel(factorpadic(nf_get_pol(K), p, k), 1);
      91             :   long l, i;
      92         238 :   S = idealprimedec(K, p);
      93         238 :   R = cgetg_copy(S, &l);
      94         770 :   for (i = 1; i < l; i++)
      95             :   {
      96         532 :     long j = get_ZpX_index(K, gel(S,i), T);
      97         532 :     gel(R,i) = gel(T,j);
      98         532 :     gel(T,j) = NULL;
      99             :   }
     100         238 :   return R;
     101             : }
     102             : 
     103             : /* K a bnf, compute Cl'(K) = ell-Sylow of Cl(K) / (places above ell).
     104             :  * Return [D, u, R0, U0, ordS]
     105             :  * - D: cyclic factors for Cl'(K)
     106             :  * - u: generators of cyclic factors (all coprime to ell)
     107             :  * - R0: subgroup isprincipal(<S>) (divides K.cyc)
     108             :  * - U0: generators of R0 are of the form S . U0
     109             :  * - ordS[i] = order of S[i] in CL(K)  */
     110             : static GEN
     111         175 : CL_prime(GEN K, GEN ell, GEN Sell)
     112             : {
     113         175 :   GEN g, ordS, R0, U0, U, D, u, cyc = bnf_get_cyc(K);
     114         175 :   long i, l, lD, lS = lg(Sell);
     115             : 
     116         175 :   g = leafcopy(bnf_get_gen(K));
     117         175 :   l = lg(g);
     118         511 :   for (i = 1; i < l; i++)
     119             :   {
     120         336 :     GEN A = gel(g,i), a = gcoeff(A,1,1);
     121         336 :     long v = Z_pvalrem(a, ell, &a);
     122         336 :     if (v) gel(g,i) = hnfmodid(A, a); /* make coprime to ell */
     123             :   }
     124         175 :   R0 = cgetg(lS, t_MAT);
     125         175 :   ordS = cgetg(lS, t_VEC);
     126         637 :   for (i = 1; i < lS; i++)
     127             :   {
     128         462 :     gel(R0,i) = isprincipal(K, gel(Sell,i));
     129         462 :     gel(ordS,i) = charorder(cyc, gel(R0,i)); /* order of Sell[i] */
     130             :   }
     131         175 :   R0 = shallowconcat(R0, diagonal_shallow(cyc));
     132             :   /* R0 = subgroup generated by S in Cl(K) [ divides diagonal(K.cyc) ]*/
     133         175 :   R0 = ZM_hnfall(R0, &U0, 2); /* [S | cyc] * U0 = R0 in HNF */
     134         175 :   D = ZM_snfall(R0, &U,NULL);
     135         175 :   D = RgM_diagonal_shallow(D);
     136         175 :   lD = lg(D);
     137         175 :   u = ZM_inv(U, NULL); settyp(u, t_VEC);
     138         175 :   for (i = 1; i < lD; i++) gel(u,i) = idealfactorback(K,g,gel(u,i),1);
     139         175 :   setlg(U0, l);
     140         175 :   U0 = rowslice(U0,1,lS-1); /* restrict to 'S' part */
     141         175 :   return mkvec5(D, u, R0, U0, ordS);
     142             : }
     143             : 
     144             : static GEN
     145         315 : ell1(GEN ell) { return equaliu(ell,2)? utoipos(5): addiu(ell,1); }
     146             : 
     147             : /* log N_{F_P/Q_p}(x) / deg_F P */
     148             : static GEN
     149        7672 : vtilde_i(GEN K, GEN x, GEN T, GEN deg, GEN ell, long prec)
     150             : {
     151             :   GEN L, cx;
     152        7672 :   if (typ(x) != t_POL) x = nf_to_scalar_or_alg(K, x);
     153        7672 :   if (typ(x) != t_POL) { cx = x; L = gen_0; }
     154             :   else
     155             :   {
     156             :     GEN N;
     157        7476 :     x = Q_primitive_part(x,&cx);
     158        7476 :     N = RgXQ_norm(x, T);
     159        7476 :     L = Qp_log(cvtop(N,ell,prec));
     160             :   }
     161        7672 :   if (cx)
     162             :   {
     163        7623 :     Q_pvalrem(cx, ell, &cx);
     164        7623 :     if (!isint1(cx))
     165        7245 :       L = gadd(L, gmulsg(degpol(T), Qp_log(cvtop(cx,ell,prec))));
     166             :   }
     167        7672 :   return gdiv(L, deg);
     168             : }
     169             : static GEN
     170        4214 : vtilde(GEN K, GEN x, GEN T, GEN deg, GEN ell, long prec)
     171             : {
     172             :   GEN G, E, vG;
     173             :   long i, l;
     174        4214 :   if (typ(x) != t_MAT) return vtilde_i(K,x,T,deg,ell,prec);
     175        3178 :   G = gel(x,1); vG = cgetg_copy(G, &l);
     176        3178 :   E = gel(x,2);
     177        3178 :   for (i = 1; i < l; i++) gel(vG, i) = vtilde_i(K, gel(G,i),T,deg,ell,prec);
     178        3178 :   return RgV_dotproduct(E, vG);
     179             : }
     180             : 
     181             : /* v[i] = deg S[i] mod p^prec */
     182             : static GEN
     183         294 : get_vdegS(GEN Ftilde, GEN ell, long prec)
     184             : {
     185         294 :   long i, l = lg(Ftilde);
     186         294 :   GEN v = cgetg(l, t_VEC), degell = Qp_log( cvtop(ell1(ell), ell, prec) );
     187         294 :   for (i = 1; i < l; i++) gel(v,i) = gmulsg(Ftilde[i], degell);
     188         294 :   return v;
     189             : }
     190             : /* K a bnf. Compute kernel \tilde{Cl}_K(ell); return cyclic factors.
     191             :  * Set *pM to (vtilde_S[i](US[j]))_{i,j} */
     192             : static GEN
     193         175 : CL_tilde(GEN K, GEN US, GEN ell, GEN T, GEN Ftilde, GEN *pM, long prec)
     194             : {
     195             :   GEN D, M, ellk, vdegS;
     196         175 :   long i, j, imin, vmin, k, lD, l = lg(T), lU = lg(US);
     197             : 
     198         175 :   *pM = cgetg(1, t_MAT);
     199         175 :   if (l == 2) return cgetg(1, t_VEC); /* p = P^e: \tilde{Cl}(l) = (1) */
     200         133 :   vdegS = get_vdegS(Ftilde, ell, prec);
     201         133 :   imin = 1; vmin = l; /* upper bound */
     202         553 :   for (i = 1; i < l; i++)
     203             :   {
     204         420 :     long v = z_pval(Ftilde[i], ell);
     205         420 :     if (v < vmin) { vmin = v; imin = i; }
     206             :   }
     207         133 :   M = cgetg(lU, t_MAT);
     208         805 :   for (j = 1; j < lU; j++)
     209             :   {
     210         672 :     GEN c = cgetg(l, t_COL), a = gel(US,j);
     211        3892 :     for (i = 1; i < l; i++)
     212        3220 :       gel(c,i) = vtilde(K, a, gel(T,i), gel(vdegS,i), ell, prec);
     213         672 :     gel(M,j) = c;
     214             :   }
     215         133 :   k = padicprec(M, ell); ellk = powiu(ell, k);
     216         133 :   *pM = M = gmod(M, ellk);
     217         133 :   M = rowsplice(M, imin);
     218         133 :   l--;
     219         133 :   if (l == 1) return cgetg(1, t_VEC);
     220         133 :   M = ZM_hnfmodid(M, ellk);
     221         133 :   D = matsnf0(M, 4); lD = lg(D);
     222         133 :   if (lD > 1 && Z_pval(gel(D,1), ell) >= k) return NULL;
     223         133 :   return D;
     224             : }
     225             : 
     226             : /* [L:K] = ell^k; return 1 if L/K is locally cyclotomic at ell, 0 otherwise */
     227             : long
     228          35 : rnfislocalcyclo(GEN rnf)
     229             : {
     230          35 :   pari_sp av = avma;
     231             :   GEN K, L, S, SK, TK, SLs, SL2, TL, ell;
     232             :   ulong ll;
     233             :   long i, j, k, lk, lSK;
     234          35 :   checkrnf(rnf);
     235          35 :   lk = rnf_get_degree(rnf);
     236          35 :   if (lk == 1) return 1;
     237          28 :   k = uisprimepower(lk, &ll);
     238          28 :   if (!k) pari_err_IMPL("rnfislocalcyclo for non-l-extensions");
     239          21 :   ell = utoi(ll);
     240          21 :   K = rnf_get_nf(rnf);
     241          21 :   L = rnf_build_nfabs(rnf, nf_get_prec(K));
     242          21 :   S = rnfidealprimedec(rnf, ell);
     243          21 :   SK  = gel(S,1);
     244          21 :   SLs = gel(S,2);
     245          21 :   SL2 = shallowconcat1(SLs);
     246          21 :   TK = padicfact(K, SK, 100); lSK = lg(SK);
     247          21 :   TL = padicfact(L, SL2, 100);
     248          35 :   for (i = 1; i < lSK; i++)
     249             :   {
     250          21 :     long eK = etilde(K, gel(SK,i), gel(TK,i));
     251          21 :     GEN SL = gel(SLs,i);
     252          21 :     long lSL = lg(SL);
     253          35 :     for (j = 1; j < lSL; j++)
     254             :     {
     255          21 :       long iS = gen_search(SL2, gel(SL,j), 0, (void*)&cmp_prime_over_p,
     256             :                 &cmp_nodata);
     257          21 :       long eL = etilde(L, gel(SL,j), gel(TL,iS));
     258          21 :       if (dvdui(eL/eK, ell)) return gc_long(av,0);
     259             :     }
     260             :   };
     261          14 :   return gc_long(av,1);
     262             : }
     263             : 
     264             : #if 0
     265             : /* Return 1 if L/Q is locally cyclotomic at ell */
     266             : static int
     267             : islocalcycloQ(GEN L, GEN ell)
     268             : {
     269             :   GEN SL = idealprimedec(L,ell), TL;
     270             :   long i, lSL = lg(SL);
     271             :   TL = padicfact(L,  SL, 100);
     272             :   for (i = 1; i < lSL; i++)
     273             :   {
     274             :     long eL = etilde(L, gel(SL,i), gel(TL,i));
     275             :     if (dvdui(eL,ell)) return 0;
     276             :   }
     277             :   return 1;
     278             : }
     279             : #endif
     280             : 
     281             : /* true nf, pr a prid */
     282             : static long
     283          91 : nfislocalpower_i(GEN nf, GEN pr, GEN a, GEN n)
     284             : {
     285             :   long v, e, t;
     286             :   GEN p, G, L;
     287          91 :   a = nf_to_scalar_or_basis(nf,a);
     288          91 :   if (!signe(n)) return isint1(a);
     289          77 :   v = nfvalrem(nf, a, pr, &a); if (!dvdsi(v, n)) return 0;
     290          63 :   p = pr_get_p(pr);
     291          63 :   v = Z_pvalrem(n, p, &n);
     292          63 :   if (!equali1(n))
     293             :   {
     294          21 :     GEN T, modpr = zk_to_Fq_init(nf, &pr, &T, &p);
     295          21 :     GEN ap = nf_to_Fq(nf, a, modpr);
     296          21 :     if (!Fq_ispower(ap, n, T, p)) return 0;
     297             :   }
     298          56 :   if (!v) return 1;
     299          56 :   e = pr_get_e(pr);
     300          56 :   if (v == 1) /* optimal formula */
     301          42 :     t = itos( divii(mului(e,p), subiu(p,1)) ) + 1;
     302             :   else /* straight Hensel */
     303          14 :     t = 2 * e * v + 1;
     304          56 :   G = Idealstarprk(nf, pr, t, nf_INIT);
     305          56 :   L = ideallog(nf, a, G);
     306          56 :   return (ZV_equal0(L) || ZV_pval(L, p) >= v);
     307             : }
     308             : long
     309         105 : nfislocalpower(GEN nf, GEN pr, GEN a, GEN n)
     310             : {
     311         105 :   pari_sp av = avma;
     312         105 :   if (typ(n) != t_INT) pari_err_TYPE("nfislocalpower",n);
     313         105 :   nf = checknf(nf); checkprid(pr);
     314          91 :   return gc_long(av, nfislocalpower_i(nf, pr, a, n));
     315             : }
     316             : 
     317             : /* v_ell(  exponent(D) ) */
     318             : static long
     319         350 : ellexpo(GEN D, GEN ell) { return lg(D) == 1? 0: Z_pval(gel(D,1), ell); }
     320             : 
     321             : static GEN
     322         161 : ellsylow(GEN cyc, GEN ell)
     323             : {
     324             :   long i, l;
     325         161 :   GEN d = cgetg_copy(cyc, &l);
     326         343 :   for (i = 1; i < l; i++)
     327             :   {
     328         266 :     GEN c = gel(cyc,i), a;
     329         266 :     if (!Z_pvalrem(c, ell, &a)) break;
     330         182 :     gel(d,i) = diviiexact(c, a);
     331             :   }
     332         161 :   setlg(d, i); return d;
     333             : }
     334             : 
     335             : static long
     336         889 : vnorm_x(GEN nf, GEN x, GEN ell)
     337             : {
     338         889 :   x = nf_to_scalar_or_alg(nf,x);
     339         889 :   if (typ(x) != t_POL) return 0;
     340         833 :   x = Q_primpart(x);
     341         833 :   return Q_pval(nfnorm(nf,x), ell);
     342             : }
     343             : static long
     344         462 : vtilde_prec_x(GEN nf, GEN x, GEN ell)
     345             : {
     346             :   long i, l, v;
     347             :   GEN G;
     348         462 :   if (typ(x) != t_MAT) return vnorm_x(nf,x,ell);
     349         462 :   G = gel(x,1); l = lg(G); v = 0;
     350         462 :   for (i = 1; i < l; i++) v = maxss(v, vnorm_x(nf,gel(G,i),ell));
     351         462 :   return v;
     352             : }
     353             : /* upper bound for \delta(vec): estimate loss of accuracy when evaluating
     354             :  * \tilde{v} on the vec[i] */
     355             : static long
     356         175 : vtilde_prec(GEN nf, GEN vec, GEN ell)
     357             : {
     358         175 :   long v0 = 0, i, l = lg(vec);
     359         637 :   for (i = 1; i < l; i++)
     360         462 :     v0 = maxss(v0, vtilde_prec_x(nf, gel(vec,i), ell));
     361         175 :   return 3 + v0 + z_pval(nf_get_degree(nf), ell);
     362             : }
     363             : 
     364             : static GEN
     365         175 : bnflog_i(GEN bnf, GEN ell)
     366             : {
     367             :   long prec0, prec;
     368             :   GEN nf, US, vdegS, S, T, M, CLp, CLt, Ftilde, vtG, ellk;
     369             :   GEN D, Ap, cycAp, bnfS;
     370             :   long i, j, lS, lvAp;
     371             : 
     372         175 :   checkbnf(bnf);
     373         175 :   nf = checknf(bnf);
     374         175 :   S = idealprimedec(nf, ell);
     375         175 :   bnfS = bnfsunit0(bnf, S, nf_GENMAT, LOWDEFAULTPREC); /* S-units */
     376         175 :   US = leafcopy(gel(bnfS,1));
     377         175 :   prec0 = maxss(30, vtilde_prec(nf, US, ell));
     378         175 :   US = shallowconcat(bnf_get_fu(bnf), US);
     379         175 :   settyp(US, t_COL);
     380         175 :   T = padicfact(nf, S, prec0);
     381         175 :   lS = lg(S); Ftilde = cgetg(lS, t_VECSMALL);
     382         175 :   for (j = 1; j < lS; j++) Ftilde[j] = ftilde(nf, gel(S,j), gel(T,j));
     383         175 :   CLp = CL_prime(bnf, ell, S);
     384         175 :   cycAp = gel(CLp,1);
     385         175 :   Ap = gel(CLp,2);
     386             :   for(;;)
     387             :   {
     388         175 :     CLt = CL_tilde(nf, US, ell, T, Ftilde, &vtG, prec0);
     389         175 :     if (CLt) break;
     390           0 :     prec0 <<= 1;
     391           0 :     T = padicfact(nf, S, prec0);
     392             :   }
     393         175 :   prec = ellexpo(cycAp, ell) + ellexpo(CLt,ell) + 1;
     394         175 :   if (prec == 1) return mkvec3(cgetg(1,t_VEC), cgetg(1,t_VEC), cgetg(1,t_VEC));
     395             : 
     396         161 :   vdegS = get_vdegS(Ftilde, ell, prec0);
     397         161 :   ellk = powiu(ell, prec);
     398         161 :   lvAp = lg(Ap);
     399         161 :   if (lvAp > 1)
     400             :   {
     401         154 :     GEN Kcyc = bnf_get_cyc(bnf);
     402         154 :     GEN C = zeromatcopy(lvAp-1, lS-1);
     403         154 :     GEN Rell = gel(CLp,3), Uell = gel(CLp,4), ordS = gel(CLp,5);
     404         476 :     for (i = 1; i < lvAp; i++)
     405             :     {
     406         322 :       GEN a, b, bi, A = gel(Ap,i), d = gel(cycAp,i);
     407         322 :       bi = isprincipal(bnf, A);
     408         322 :       a = vecmodii(ZC_Z_mul(bi,d), Kcyc);
     409             :       /* a in subgroup generated by S = Rell; hence b integral */
     410         322 :       b = hnf_invimage(Rell, a);
     411         322 :       b = vecmodii(ZM_ZC_mul(Uell, ZC_neg(b)), ordS);
     412         322 :       A = mkvec2(A, trivial_fact());
     413         322 :       A = idealpowred(nf, A, d);
     414             :       /* find a principal representative of A_i^cycA_i up to elements of S */
     415         322 :       a = isprincipalfact(bnf,gel(A,1),S,b,nf_GENMAT|nf_FORCE);
     416         322 :       if (!gequal0(gel(a,1))) pari_err_BUG("bnflog");
     417         322 :       a = famat_mul_shallow(gel(A,2), gel(a,2)); /* principal part */
     418         322 :       if (lg(a) == 1) continue;
     419        1316 :       for (j = 1; j < lS; j++)
     420         994 :         gcoeff(C,i,j) = vtilde(nf, a, gel(T,j), gel(vdegS,j), ell, prec0);
     421             :     }
     422         154 :     C = gmod(gneg(C),ellk);
     423         154 :     C = shallowtrans(C);
     424         154 :     M = mkmat2(mkcol2(diagonal_shallow(cycAp), C), mkcol2(gen_0, vtG));
     425         154 :     M = shallowmatconcat(M); /* relation matrix */
     426             :   }
     427             :   else
     428           7 :     M = vtG;
     429         161 :   M = ZM_hnfmodid(M, ellk);
     430         161 :   D = matsnf0(M, 4);
     431         161 :   if (lg(D) == 1 || !dvdii(gel(D,1), ellk))
     432           0 :     pari_err_BUG("bnflog [missing Z_l component]");
     433         161 :   D = vecslice(D,2,lg(D)-1);
     434         161 :   return mkvec3(D, CLt, ellsylow(cycAp, ell));
     435             : }
     436             : GEN
     437         175 : bnflog(GEN bnf, GEN ell)
     438             : {
     439         175 :   pari_sp av = avma;
     440         175 :   return gerepilecopy(av, bnflog_i(bnf, ell));
     441             : }
     442             : 
     443             : GEN
     444          42 : bnflogef(GEN nf, GEN pr)
     445             : {
     446          42 :   pari_sp av = avma;
     447             :   long e, f, ef;
     448             :   GEN p;
     449          42 :   checkprid(pr); p = pr_get_p(pr);
     450          42 :   nf = checknf(nf);
     451          42 :   e = pr_get_e(pr);
     452          42 :   f = pr_get_f(pr); ef = e*f;
     453          42 :   if (u_pval(ef, p))
     454             :   {
     455          21 :     GEN T = gel(factorpadic(nf_get_pol(nf), p, 100), 1);
     456          21 :     long j = get_ZpX_index(nf, pr, T);
     457          21 :     e = etilde(nf, pr, gel(T,j));
     458          21 :     f = ef / e;
     459             :   }
     460          42 :   set_avma(av); return mkvec2s(e,f);
     461             : }
     462             : 
     463             : GEN
     464          21 : bnflogdegree(GEN nf, GEN A, GEN ell)
     465             : {
     466          21 :   pari_sp av = avma;
     467             :   GEN AZ, A0Z, NA0;
     468             :   long vAZ;
     469             : 
     470          21 :   if (typ(ell) != t_INT) pari_err_TYPE("bnflogdegree", ell);
     471          21 :   nf = checknf(nf);
     472          21 :   A = idealhnf(nf, A);
     473          21 :   AZ = gcoeff(A,1,1);
     474          21 :   vAZ = Z_pvalrem(AZ, ell, &A0Z);
     475          21 :   if (is_pm1(A0Z))
     476           0 :     NA0 = gen_1;
     477             :   else
     478          21 :     (void)Z_pvalrem(idealnorm(nf,A), ell, &NA0);
     479          21 :   if (vAZ)
     480             :   {
     481          21 :     GEN Aell = ZM_hnfmodid(A, powiu(ell,vAZ));
     482          21 :     GEN S = idealprimedec(nf, ell), T;
     483          21 :     long l, i, s = 0;
     484          21 :     T = padicfact(nf, S, 100);
     485          21 :     l = lg(S);
     486          49 :     for (i = 1; i < l; i++)
     487             :     {
     488          28 :       GEN P = gel(S,i);
     489          28 :       long v = idealval(nf, Aell, P);
     490          28 :       if (v) s += v * ftilde(nf, P, gel(T,i));
     491             :     }
     492          21 :     if (s) NA0 = gmul(NA0, gpowgs(ell1(ell), s));
     493             :   }
     494          21 :   return gerepileupto(av, NA0);
     495             : }

Generated by: LCOV version 1.13