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 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 - dirichlet.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.10.0 lcov report (development 21353-12523aa) Lines: 84 88 95.5 %
Date: 2017-11-24 06:20:58 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2015  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             : /********************************************************************/
      15             : /**                                                                **/
      16             : /**           Dirichlet series through Euler product               **/
      17             : /**                                                                **/
      18             : /********************************************************************/
      19             : #include "pari.h"
      20             : #include "paripriv.h"
      21             : 
      22             : static void
      23          21 : err_direuler(GEN x)
      24          21 : { pari_err_DOMAIN("direuler","constant term","!=", gen_1,x); }
      25             : 
      26             : /* s = t_POL (tolerate t_SER of valuation 0) of constant term = 1
      27             :  * d = minimal such that p^d > X
      28             :  * V indexed by 1..X will contain the a_n
      29             :  * v[1..n] contains the indices nj such that V[nj] != 0 */
      30             : static long
      31       19124 : dirmuleuler_small(GEN V, GEN v, long n, ulong p, GEN s, long d)
      32             : {
      33       19124 :   long i, j, m = n, D = minss(d+2, lg(s));
      34       19124 :   ulong q = 1, X = lg(V)-1;
      35             : 
      36       59605 :   for (i = 3, q = p; i < D; i++, q *= p) /* q*p does not overflow */
      37             :   {
      38       40481 :     GEN aq = gel(s,i);
      39       40481 :     if (gequal0(aq)) continue;
      40             :     /* j = 1 */
      41       34566 :     gel(V,q) = aq;
      42       34566 :     v[++n] = q;
      43      980875 :     for (j = 2; j <= m; j++)
      44             :     {
      45      946309 :       ulong nj = umuluu_or_0(uel(v,j), q);
      46      946309 :       if (!nj || nj > X) continue;
      47       81634 :       gel(V,nj) = gmul(aq, gel(V,v[j]));
      48       81634 :       v[++n] = nj;
      49             :     }
      50             :   }
      51       19124 :   return n;
      52             : }
      53             : 
      54             : /* ap != 0 for efficiency, p > sqrt(X) */
      55             : static void
      56       93667 : dirmuleuler_large(GEN V, ulong p, GEN ap)
      57             : {
      58       93667 :   long j, jp, X = lg(V)-1;
      59       93667 :   gel(V,p) = ap;
      60       93667 :   for (j = 2, jp = 2*p; jp <= X; j++, jp += p) gel(V,jp) = gmul(ap, gel(V,j));
      61       93667 : }
      62             : 
      63             : static ulong
      64        7413 : direulertou(GEN a, GEN fl(GEN))
      65             : {
      66        7413 :   if (typ(a) != t_INT)
      67             :   {
      68          49 :     a = fl(a);
      69          28 :     if (typ(a) != t_INT) pari_err_TYPE("direuler", a);
      70             :   }
      71        7392 :   return signe(a)<=0 ? 0: itou(a);
      72             : }
      73             : 
      74             : GEN
      75        3507 : direuler_bad(void *E, GEN (*eval)(void *,GEN,long), GEN a,GEN b,GEN c, GEN Sbad)
      76             : {
      77             :   ulong au, bu, X, sqrtX, n, p;
      78        3507 :   pari_sp av0 = avma;
      79             :   GEN gp, v, V;
      80             :   forprime_t T;
      81             :   long i;
      82        3507 :   au = direulertou(a, gceil);
      83        3500 :   bu = direulertou(b, gfloor);
      84        3493 :   X = c ? direulertou(c, gfloor): bu;
      85        3486 :   if (X == 0) return cgetg(1,t_VEC);
      86        3479 :   if (bu > X) bu = X;
      87        3479 :   if (!u_forprime_init(&T, au, bu)) { avma = av0; return mkvec(gen_1); }
      88        3465 :   v = vecsmall_ei(X, 1);
      89        3465 :   V = vec_ei(X, 1);
      90        3465 :   n = 1;
      91        3465 :   if (Sbad)
      92             :   {
      93        2919 :     long l = lg(Sbad);
      94        2919 :     GEN pbad = gen_1;
      95        7665 :     for (i = 1; i < l; i++)
      96             :     {
      97        4746 :       GEN ai = gel(Sbad,i);
      98             :       ulong q;
      99        4746 :       if (typ(ai) != t_VEC || lg(ai) != 3)
     100           0 :         pari_err_TYPE("direuler [bad primes]",ai);
     101        4746 :       q = gtou(gel(ai,1));
     102        4746 :       if (q <= X)
     103             :       {
     104        3794 :         long d = ulogint(X, q) + 1;
     105        3794 :         GEN s = direuler_factor(gel(ai,2), d);
     106        3794 :         n = dirmuleuler_small(V, v, n, q, s, d);
     107        3794 :         pbad = muliu(pbad, q);
     108             :       }
     109             :     }
     110        2919 :     Sbad = pbad;
     111             :   }
     112        3465 :   p = 1; gp = cgetipos(3); sqrtX = usqrt(X);
     113       24920 :   while (p <= sqrtX && (p = u_forprime_next(&T)))
     114       18011 :     if (!Sbad || umodiu(Sbad, p))
     115             :     {
     116       15351 :       long d = ulogint(X, p) + 1; /* minimal d such that p^d > X */
     117             :       GEN s;
     118       15351 :       gp[2] = p; s = eval(E, gp, d);
     119       15330 :       n = dirmuleuler_small(V, v, n, p, s, d);
     120             :     }
     121      201250 :   while ((p = u_forprime_next(&T))) /* sqrt(X) < p <= X */
     122      194362 :     if (!Sbad || umodiu(Sbad, p))
     123             :     {
     124             :       GEN s;
     125      193228 :       gp[2] = p; s = eval(E, gp, 2);
     126      193228 :       if (degpol(s) && !gequal0(gel(s,3))) dirmuleuler_large(V, p, gel(s,3));
     127             :     }
     128        3444 :   return gerepilecopy(av0,V);
     129             : }
     130             : 
     131             : /* return a t_SER or a truncated t_POL to precision n */
     132             : GEN
     133       85281 : direuler_factor(GEN s, long n)
     134             : {
     135       85281 :   long t = typ(s);
     136       85281 :   if (is_scalar_t(t))
     137             :   {
     138       49791 :     if (!gequal1(s)) err_direuler(s);
     139       49784 :     return scalarpol_shallow(s,0);
     140             :   }
     141       35490 :   switch(t)
     142             :   {
     143        7042 :     case t_POL: break; /* no need to RgXn_red */
     144             :     case t_RFRAC:
     145             :     {
     146       28448 :       GEN p = gel(s,1), q = gel(s,2);
     147       28448 :       q = RgXn_red_shallow(q,n);
     148       28448 :       s = RgXn_inv(q, n);
     149       28448 :       if (typ(p) == t_POL && varn(p) == varn(q))
     150             :       {
     151          28 :         p = RgXn_red_shallow(p, n);
     152          28 :         s = RgXn_mul(s, p, n);
     153             :       }
     154             :       else
     155       28420 :         if (!gequal1(p)) s = RgX_Rg_mul(s, p);
     156       28448 :       if (!signe(s) || !gequal1(gel(s,2))) err_direuler(s);
     157       28434 :       break;
     158             :     }
     159             :     case t_SER:
     160           0 :       if (!signe(s) || valp(s) || !gequal1(gel(s,2))) err_direuler(s);
     161           0 :       break;
     162           0 :     default: pari_err_TYPE("direuler", s);
     163             :   }
     164       35476 :   return s;
     165             : }
     166             : 
     167             : struct eval_bad
     168             : {
     169             :   void *E;
     170             :   GEN (*eval)(void *, GEN);
     171             : };
     172             : static GEN
     173         399 : eval_bad(void *E, GEN p, long n)
     174             : {
     175         399 :   struct eval_bad *d = (struct eval_bad*) E;
     176         399 :   return direuler_factor(d->eval(d->E, p), n);
     177             : }
     178             : GEN
     179         126 : direuler(void *E, GEN (*eval)(void *, GEN), GEN a, GEN b, GEN c)
     180             : {
     181             :   struct eval_bad d;
     182         126 :   d.E= E; d.eval = eval;
     183         126 :   return direuler_bad((void*)&d, eval_bad, a, b, c, NULL);
     184             : }

Generated by: LCOV version 1.11