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 - ellpadiclambdamu.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.12.1 lcov report (development 25406-bf255ab81b) Lines: 113 113 100.0 %
Date: 2020-06-04 05:59:24 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2011  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
      13             : 
      14             : #include "pari.h"
      15             : #include "paripriv.h"
      16             : 
      17             : /** Batch p-adic logarithms **/
      18             : /* a/b mod q */
      19             : static ulong
      20        1771 : divmodulo(ulong a, ulong b, ulong p, ulong q)
      21             : {
      22        1771 :   long v = u_lvalrem(b, p, &b);
      23        1771 :   if (v) a /= upowuu(p,v);
      24             :   /* a/b is now a p-integer */
      25        1771 :   return Fl_div(a, b, q);
      26             : }
      27             : /* to compute log_p(a) mod q = p^n, p < 2^31 */
      28             : static GEN
      29         854 : initQplog(long p, ulong q, long n)
      30             : {
      31             :   long i, nn, nt;
      32             :   ulong a, P;
      33             :   GEN C;
      34        1316 :   for(nn = n, nt = n + 1; nn >= p; nn /= p) nt++;
      35         854 :   if (p == 2)
      36             :   {
      37          70 :     P = q - 8;
      38         378 :     while (3 * (nt - 1) > u_lval(nt-1, p) + n) nt--;
      39             :   }
      40             :   else
      41             :   {
      42         784 :     P = q - p;
      43        1750 :     while (nt > u_lval(nt-1, p) + n) nt--;
      44             :   }
      45         854 :   C = cgetg(nt, t_VECSMALL);
      46             :   /* [ P^(k-1) / k, k = 1..nt ] / (p - 1) */
      47        2625 :   for(i = 1, a = 1; i < nt; i++, a = Fl_mul(a, P, q))
      48        1771 :     C[i] = divmodulo(a, i * (p-1), p, q);
      49         854 :   return C;
      50             : }
      51             : /* compute log_p(a) / p (resp. log_2(a) / 4) mod p^n, 'a' a p-unit,
      52             :  * C = initQplog(p,q,n), q = p^n */
      53             : static ulong
      54     1638574 : logp(GEN C, ulong a, ulong p, ulong q, ulong pn)
      55             : {
      56     1638574 :   long i, b, z, n = lg(C)-1;
      57     1638574 :   a %= q;
      58             :   /* Euclidean quotient (a^2 = 1 mod 8, a^(p-1) = 1 mod p) */
      59     1638574 :   if (p == 2)
      60         476 :     b = Fl_sqr(a, q << 1) >> 3;
      61             :   else
      62     1638098 :     b = Fl_powu(a, p-1, q) / p;
      63     1638574 :   z = Fl_mul(b, C[n], pn);
      64     5354790 :   for (i = n-1; i > 0; i--) z = Fl_mul(z + C[i], b, pn);
      65     1638574 :   return z;
      66             : }
      67             : 
      68             : /* p-adic integration against d mu_E, mod p^n, m > 0. D fundamental,
      69             :  * W a msinit for k = 2, xpm an eigensymbol.
      70             :  * Assume |D p^n| < MAX_LONG. Much cheaper than oms at low precision.
      71             :  * Return 1/2 * correct value [half loop over a]. Assume xpm belongs to
      72             :  * (-1)^i (D/-1) - part */
      73             : static GEN
      74        1211 : polPn(GEN W, GEN xpm, long p, long D, long R, long n)
      75             : {
      76        1211 :   pari_sp av = avma, av2;
      77        1211 :   long N = (p == 2)? n + 2: n + 1;
      78        1211 :   ulong aD = labs(D), pn = upowuu(p, n), q = upowuu(p, N), ic = 0;
      79        1211 :   GEN v, Dq = muluu(aD, q), nc = icopy(gen_1), c = mkfrac(nc, Dq);
      80        1211 :   GEN C = n? initQplog(p, q, N): NULL;
      81        1211 :   GEN tab = R? ZV_to_Flv(teichmullerinit(p, N), q): NULL;
      82        1211 :   long a, A = itou(shifti(Dq,-1));
      83             : 
      84        1211 :   if (n) ic = Fl_inv(logp(C, 1 + (p == 2? 4: p), p, q, pn), pn);
      85        1211 :   v = zero_zv(pn); av2 = avma;
      86     3619819 :   for (a = 1; a <= A; a++, set_avma(av2))
      87             :   {
      88             :     GEN X;
      89     3618608 :     long s, ap = a % p;
      90             :     ulong x, j;
      91     3618608 :     if (!ap || !(s = kross(D,a))) continue;
      92     2210964 :     nc[2] = (long)a;
      93     2210964 :     X = mseval2_ooQ(W, xpm, c); /* xpm(a / Dq) */
      94     2210964 :     x = umodiu(X, q); if (!x) continue;
      95             :     /* log(a) / log(c) */
      96     1657705 :     j = n? Fl_mul(logp(C, a, p, q, pn), ic, pn): 0;
      97     1657705 :     if (R) x = Fl_mul(x, tab[Fl_powu(ap, R, p)], q);
      98     1657705 :     if (s < 0) x = Fl_neg(x, q);
      99     1657705 :     v[j + 1] = Fl_add(v[j + 1], x, q);
     100             :   }
     101        1211 :   v = Flv_to_Flx(v, evalvarn(0));
     102        1211 :   v = zlx_translate1(v, p, N);
     103        1211 :   return gerepileupto(av, Flx_to_ZX(v));
     104             : }
     105             : /* return lambda, assuming mu = 0 [else infinite loop] */
     106             : static long
     107         798 : lambda_ss(GEN W, GEN xpm, long v, long p, long D, long R, long n)
     108             : {
     109         378 :   for (;; n += 2)
     110         378 :   {
     111         798 :     GEN P = polPn(W, xpm, p, D, R, n);
     112             :     long mu;
     113         798 :     if (!signe(P)) continue;
     114         574 :     mu = ZX_lvalrem(P, p, &P) + v;
     115         574 :     if (!mu)
     116             :     {
     117         420 :       long M = upowuu(p,n);
     118         420 :       if (odd(n)) M -= p; else M--;
     119         420 :       M /= p + 1;
     120         420 :       return Flx_val(ZX_to_Flx(P, p)) - M;
     121             :     }
     122             :   }
     123             : }
     124             : /* return lambda, assuming mu = 0 [else infinite loop] */
     125             : static long
     126         147 : lambda_ord(GEN W, GEN xpm, long v, long p, long D, long R, GEN ap)
     127             : {
     128         147 :   GEN P1, P0 = polPn(W, xpm, p, D, R, 0);
     129             :   long n;
     130         147 :   for (n = 1;; n++, P0 = P1)
     131         119 :   {
     132         266 :     long mu, pn = upowuu(p,n);
     133         266 :     GEN P, xi, alpha, Q = utoipos(pn);
     134             : 
     135         266 :     P1 = polPn(W, xpm, p, D, R, n);
     136         266 :     alpha = mspadic_unit_eigenvalue(ap, 2, utoipos(p), n+1);
     137         266 :     alpha = padic_to_Q(ginv(alpha));
     138         266 :     xi = FpX_translate(polcyclo(pn, 0), gen_1, Q);
     139         266 :     P = ZX_sub(P1, ZX_Z_mul(FpX_mul(P0, xi, Q), alpha)); /* mod p^n */
     140             : 
     141         266 :     if (!signe(P) || n + v <= 0) continue;
     142         147 :     mu = ZX_lvalrem(P, p, &P) + v;
     143         147 :     if (!mu) return Flx_val(ZX_to_Flx(P, p));
     144             :   }
     145             : }
     146             : GEN
     147         378 : ellpadiclambdamu(GEN E, long p, long D, long R)
     148             : {
     149         378 :   pari_sp av = avma;
     150         378 :   long vC, s, muadd = 0;
     151             :   GEN W, xpm, C, ap;
     152             : 
     153         378 :   if (!sisfundamental(D))
     154           7 :     pari_err_DOMAIN("ellpadiclambdamu", "isfundamental(D)","=", gen_0, stoi(D));
     155         371 :   s = D < 0? -1: 1;
     156         371 :   if (odd(R)) s = -s;
     157             : 
     158         371 :   ap = ellap(E, utoi(p));
     159         371 :   if (ell_get_type(E) != t_ELL_Q)
     160           7 :     pari_err_TYPE("ellpadiclambdamu", E);
     161         364 :   if (!umodiu(ap, p))
     162             :   {
     163         217 :     if (Z_lval(ellQ_get_N(E), p) >= 2)
     164           7 :       pari_err_IMPL("additive reduction in ellpadiclambdamu");
     165         210 :     ap = NULL; /* supersingular */
     166             :   }
     167         357 :   if (ap)
     168             :   { /* ordinary */
     169         147 :     GEN v = ellisomat(E, p, 1), vE = gel(v,1), M = gel(v,2);
     170         147 :     if (lg(M) != 2) /* some p-isogeny */
     171             :     {
     172          70 :       long i, imax = 0, l = lg(vE);
     173          70 :       GEN wmax = NULL, vw = cgetg(l, t_VEC);
     174         245 :       for (i = 1; i < l; i++)
     175             :       {
     176         175 :         GEN w, e = ellinit(gel(vE,i), gen_1, 0), em = ellminimalmodel(e, NULL);
     177         175 :         gel(vE,i) = em; obj_free(e);
     178         175 :         w = ellQtwist_bsdperiod(gel(vE,i), s);
     179         175 :         if (s < 0) w = gel(w,2);
     180         175 :         gel(vw,i) = w;
     181             :         /* w is a positive real number, either Omega^+ or Omega^- / I */
     182         175 :         if (!imax || gcmp(w, wmax) > 0) { imax = i; wmax = w; }
     183             :       }
     184          70 :       if (imax != 1) muadd = Z_lval(ground(gdiv(gel(vw,imax), gel(vw,1))), p);
     185         245 :       for (i = 1; i < l; i++) obj_free(gel(vE,i));
     186          70 :       E = gel(vE, imax);
     187             :     }
     188             :   }
     189             : 
     190         357 :   W = msfromell(E, s);
     191         357 :   xpm = gel(W,2); W = gel(W,1);
     192         357 :   xpm = Q_primitive_part(xpm, &C);
     193         357 :   vC = C? Q_pval(C, utoipos(p)): 0;
     194         357 :   if (p == 2) vC++; /* due to half-loop in polPn */
     195         357 :   if (vC > 0) pari_err_BUG("ellpadiclambdamu [mu > 0]");
     196             : 
     197         357 :   if (ap)
     198             :   { /* ordinary */
     199         147 :     long L = lambda_ord(W, xpm, vC, p, D, R, ap);
     200         147 :     set_avma(av); return mkvec2s(L, muadd);
     201             :   }
     202             :   else
     203             :   {
     204         210 :     long Lp = lambda_ss(W, xpm, vC, p, D, R, 0);
     205         210 :     long Lm = lambda_ss(W, xpm, vC, p, D, R, 1);
     206         210 :     set_avma(av); retmkvec2(mkvec2s(Lp, Lm), zerovec(2));
     207             :   }
     208             : }

Generated by: LCOV version 1.13