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-bordeaux1.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 - modules - part.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.8.0 lcov report (development 16358-a11f489) Lines: 158 192 82.3 %
Date: 2014-04-11 Functions: 13 14 92.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 100 153 65.4 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright (C) 2002  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                 :            : /* Original code contributed by: Ralf Stephan (ralf@ark.in-berlin.de).
      15                 :            :  *
      16                 :            :  * This program is basically the implementation of the script
      17                 :            :  *
      18                 :            :  * Psi(n, q) = my(a=sqrt(2/3)*Pi/q, b=n-1/24, c=sqrt(b));
      19                 :            :  *             (sqrt(q)/(2*sqrt(2)*b*Pi))*(a*cosh(a*c)-(sinh(a*c)/c))
      20                 :            :  * L(n,q)=if(q==1,1,sum(h=1,q-1,if(gcd(h,q)==1, cos((g(h,q)-24*h*n)*Pi/(12*q))))
      21                 :            :  * g(h, q) = if(q>=3, 12*sum(k=1,q-1,k*(frac(h*k/q)-1/2)))
      22                 :            :  *         \\ sumdedekind(h,q)*12*q
      23                 :            :  * part(n) = round(sum(q=1,5 + 0.24*sqrt(n),L(n,q)*Psi(n,q)))
      24                 :            :  *
      25                 :            :  * only faster. It is a translation of the C/mpfr version at
      26                 :            :  * http://www.ark.in-berlin.de/part.c
      27                 :            :  *
      28                 :            :  * ------------------------------------------------------------------
      29                 :            :  *   The first restriction depends on Pari's maximum precision of floating
      30                 :            :  * point reals, which is 268435454 bits in 2.2.4, since the algorithm needs
      31                 :            :  * high precision exponentials. For that engine, the maximum possible argument
      32                 :            :  * would be in [5*10^15,10^16], the computation of which would need days on
      33                 :            :  * a ~1-GHz computer. */
      34                 :            : 
      35                 :            : #include "pari.h"
      36                 :            : #include "paripriv.h"
      37                 :            : 
      38                 :            : /****************************************************************/
      39                 :            : 
      40                 :            : /* Given:  b = N-1/24;
      41                 :            :  *   c = sqrt(2/3)*Pi*sqrt(b)
      42                 :            :  *   d = 1 / ((2*b)^(3/2) * Pi);
      43                 :            :  *
      44                 :            :  * Psi(N, q) = my(a = c/q); sqrt(q) * (a*cosh(a) - sinh(a)) */
      45                 :            : static GEN
      46                 :     792294 : psi(GEN c, ulong q, long prec)
      47                 :            : {
      48                 :     792294 :   GEN a = divru(c, q), ea = mpexp(a), invea = invr(ea);
      49                 :     792294 :   GEN cha = shiftr(addrr(ea, invea), -1);  /* ch(a) */
      50                 :     792294 :   GEN sha = shiftr(subrr(ea, invea), -1);  /* sh(a) */
      51                 :     792294 :   return mulrr(sqrtr(stor(q,prec)), subrr(mulrr(a,cha), sha));
      52                 :            : }
      53                 :            : 
      54                 :            : /* g(h, q) = if(q>=3, 12*sum(k=1,q-1,k*(frac(h*k/q)-1/2)))
      55                 :            :  *   \\ this is an integer = sumdedekind(h,q)*12*q
      56                 :            :  * assume h < q and (h,q) = 1. Not memory clean. */
      57                 :            : static GEN
      58                 :    3543866 : g(ulong h, ulong q)
      59                 :            : {
      60                 :            :   long s1, s2;
      61                 :            :   GEN v;
      62                 :            : 
      63         [ -  + ]:    3543866 :   if (q < 3)  return gen_0;
      64         [ +  + ]:    3543866 :   if (h == 1) return muluu(q-1,q-2);
      65 [ +  + ][ +  - ]:    2618544 :   if (h == 2) return q == 3? gen_m2: muluu(q-1,(q-5)>>1);
      66                 :    2193897 :   v = u_sumdedekind_coprime(h, q);
      67                 :    2193897 :   s1 = v[1];
      68                 :    2193897 :   s2 = v[2];
      69                 :    3543866 :   return addis(mulss(q,s1), s2);
      70                 :            : }
      71                 :            : 
      72                 :            : /* L(n,q)=if(q==1,1,sum(h=1,q-1,if(gcd(h,q)==1, cos((g(h,q)-24*h*n)*Pi/(12*q))))
      73                 :            :  * Never called with q < 3, so ignore this case */
      74                 :            : static GEN
      75                 :     925322 : L(GEN n, ulong q, long bitprec)
      76                 :            : {
      77                 :     925322 :   long pr = nbits2prec(bitprec / q + q);
      78                 :     925322 :   ulong h, nmodq = umodiu(n, q), qov2 = q>>1, hn;
      79                 :     925322 :   GEN r, res = stor(0, pr), q12 = muluu(q,12), q24 = shifti(q12,1);
      80                 :     925322 :   GEN pi_q = divri(mppi(pr), q12);
      81                 :     925322 :   pari_sp av = avma;
      82         [ +  + ]:    6534203 :   for (h = 1, hn = 0; h <= qov2; h++, avma = av) /* symmetry h <-> q-h */
      83                 :            :   {
      84                 :            :     GEN t;
      85         [ +  + ]:    5608881 :     hn += nmodq; if (hn >= q) hn -= q;
      86         [ +  + ]:    5608881 :     if (ugcd(q, h) > 1) continue;
      87                 :    3543866 :     r = subii(g(h,q), muluu(hn, 24));
      88                 :    3543866 :     r = centermodii(r, q24, q12);
      89         [ +  + ]:    3543866 :     t = isintzero(r)? addrs(res, 1): addrr(res, mpcos(mulri(pi_q,r)));
      90                 :    3543866 :     affrr(t, res);
      91                 :            :   }
      92                 :     925322 :   return shiftr(res,1);
      93                 :            : }
      94                 :            : 
      95                 :            : /* Return a low precision estimate of log p(n). */
      96                 :            : static GEN
      97                 :      50000 : estim(GEN n)
      98                 :            : {
      99                 :      50000 :   pari_sp av = avma;
     100                 :      50000 :   GEN p1, pi = mppi (DEFAULTPREC);
     101                 :            : 
     102                 :      50000 :   p1 = divru( itor(shifti(n,1), DEFAULTPREC), 3 );
     103                 :      50000 :   p1 = mpexp( mulrr(pi, sqrtr(p1)) ); /* exp(Pi * sqrt(2N/3)) */
     104                 :      50000 :   p1 = divri (shiftr(p1,-2), n);
     105                 :      50000 :   p1 = divrr(p1, sqrtr( stor(3,DEFAULTPREC) ));
     106                 :      50000 :   return gerepileupto(av, mplog(p1));
     107                 :            : }
     108                 :            : 
     109                 :            : static void
     110                 :      50000 : pinit(GEN n, GEN *c, GEN *d, ulong prec)
     111                 :            : {
     112                 :      50000 :   GEN b = divru( itor( subis(muliu(n,24), 1), prec ), 24 ); /* n - 1/24 */
     113                 :      50000 :   GEN sqrtb = sqrtr(b), Pi = mppi(prec), pi2sqrt2, pisqrt2d3;
     114                 :            : 
     115                 :            : 
     116                 :      50000 :   pisqrt2d3 = mulrr(Pi, sqrtr( divru(stor(2, prec), 3) ));
     117                 :      50000 :   pi2sqrt2  = mulrr(Pi, sqrtr( stor(8, prec) ));
     118                 :      50000 :   *c = mulrr(pisqrt2d3, sqrtb);
     119                 :      50000 :   *d = invr( mulrr(pi2sqrt2, mulrr(b,sqrtb)) );
     120                 :      50000 : }
     121                 :            : 
     122                 :            : /* part(n) = round(sum(q=1,5 + 0.24*sqrt(n), L(n,q)*Psi(n,q))) */
     123                 :            : GEN
     124                 :      50015 : numbpart(GEN n)
     125                 :            : {
     126                 :      50015 :   pari_sp ltop = avma, av;
     127                 :            :   GEN sum, est, C, D, p1, p2;
     128                 :            :   long prec, bitprec;
     129                 :            :   ulong q;
     130                 :            : 
     131         [ -  + ]:      50015 :   if (typ(n) != t_INT) pari_err_TYPE("partition function",n);
     132         [ -  + ]:      50015 :   if (signe(n) < 0) return gen_0;
     133         [ +  + ]:      50015 :   if (cmpiu(n, 2) < 0) return gen_1;
     134         [ +  + ]:      50005 :   if (cmpii(n, uu32toi(0x38d7e, 0xa4c68000)) >= 0)
     135                 :          5 :     pari_err_OVERFLOW("numbpart [n < 10^15]");
     136                 :      50000 :   est = estim(n);
     137                 :      50000 :   bitprec = (long)(rtodbl(est)/LOG2) + 32;
     138                 :      50000 :   prec = nbits2prec(bitprec);
     139                 :      50000 :   pinit(n, &C, &D, prec);
     140                 :      50000 :   sum = cgetr (prec); affsr(0, sum);
     141                 :            :   /* Because N < 10^16 and q < sqrt(N), q fits into a long
     142                 :            :    * In fact q < 2 LONG_MAX / 3 */
     143                 :      50000 :   av = avma; togglesign(est);
     144         [ +  + ]:     975322 :   for (q = (ulong)(sqrt(gtodouble(n))*0.24 + 5); q >= 3; q--, avma=av)
     145                 :            :   {
     146                 :     925322 :     GEN t = L(n, q, bitprec);
     147         [ +  + ]:     925322 :     if (absr_cmp(t, mpexp(divru(est,q))) < 0) continue;
     148                 :            : 
     149                 :     692294 :     t = mulrr(t, psi(gprec_w(C, nbits2prec(bitprec / q + 32)), q, prec));
     150                 :     692294 :     affrr(addrr(sum, t), sum);
     151                 :            :   }
     152                 :      50000 :   p1 = addrr(sum, psi(C, 1, prec));
     153                 :      50000 :   p2 = psi(C, 2, prec);
     154         [ +  + ]:      50000 :   affrr(mod2(n)? subrr(p1,p2): addrr(p1,p2), sum);
     155                 :      50010 :   return gerepileuptoint (ltop, roundr(mulrr(D,sum)));
     156                 :            : }
     157                 :            : 
     158                 :            : /* for loop over partitions of integer k.
     159                 :            :  * nbounds can restrict partitions to have length between nmin and nmax
     160                 :            :  * (the length is the number of non zero entries) and
     161                 :            :  * abounds restrict to integers between amin and amax.
     162                 :            :  *
     163                 :            :  * Start from central partition.
     164                 :            :  * By default, remove zero entries on the left.
     165                 :            :  *
     166                 :            :  * Algorithm:
     167                 :            :  *
     168                 :            :  * A partition of k is an increasing sequence v1,... vn with sum(vi)=k
     169                 :            :  * The starting point is the minimal n-partition of k: a,...a,a+1,.. a+1
     170                 :            :  * (a+1 is repeated r times with k = a * n + r).
     171                 :            :  *
     172                 :            :  * The procedure to obtain the next partition:
     173                 :            :  * - find the last index i<n such that v{i-1} != v{i} (that is vi is the start
     174                 :            :  * of the last constant range excluding vn).
     175                 :            :  * - decrease vi by one, and set v{i+1},... v{n} to be a minimal partition (of
     176                 :            :  * the right sum).
     177                 :            :  *
     178                 :            :  * Examples: we highlight the index i
     179                 :            :  * 1 1 2 2 3
     180                 :            :  *     ^
     181                 :            :  * 1 1 1 3 3
     182                 :            :  *       ^
     183                 :            :  * 1 1 1 2 4
     184                 :            :  *       ^
     185                 :            :  * 1 1 1 1 5
     186                 :            :  * ^
     187                 :            :  * 0 2 2 2 3
     188                 :            :  *   ^
     189                 :            :  * This is recursive in nature. Restrictions on upper bounds of the vi or on
     190                 :            :  * the length of the partitions are straightforward to take into account. */
     191                 :            : 
     192                 :            : static void
     193                 :         70 : parse_interval(GEN a, long *amin, long *amax)
     194                 :            : {
     195      [ +  +  - ]:         70 :   switch (typ(a))
     196                 :            :   {
     197                 :            :   case t_INT:
     198                 :         30 :     *amax = itos(a);
     199                 :         30 :     break;
     200                 :            :   case t_VEC:
     201         [ -  + ]:         40 :     if (lg(a) != 3)
     202                 :          0 :       pari_err_TYPE("forpart [expect vector of type [amin,amax]]",a);
     203                 :         40 :     *amin = gtos(gel(a,1));
     204                 :         40 :     *amax = gtos(gel(a,2));
     205 [ +  - ][ +  - ]:         40 :     if (*amin>*amax || *amin<0 || *amax<=0)
                 [ -  + ]
     206                 :          0 :       pari_err_TYPE("forpart [expect 0<=min<=max, 0<max]",a);
     207                 :         40 :     break;
     208                 :            :   default:
     209                 :          0 :     pari_err_TYPE("forpart",a);
     210                 :            :   }
     211                 :         70 : }
     212                 :            : 
     213                 :            : void
     214                 :         90 : forpart_init(forpart_t *T, long k, GEN abound, GEN nbound)
     215                 :            : {
     216                 :            : 
     217                 :            :   /* bound on coefficients */
     218                 :         90 :   T->amin=1;
     219         [ +  + ]:         90 :   if (abound) parse_interval(abound,&T->amin,&T->amax);
     220                 :         50 :   else T->amax = k;
     221                 :            :   /* strip leading zeros ? */
     222                 :         90 :   T->strip = (T->amin > 0) ? 1 : 0;
     223                 :            :   /* bound on number of non-zero coefficients */
     224                 :         90 :   T->nmin=0;
     225         [ +  + ]:         90 :   if (nbound) parse_interval(nbound,&T->nmin,&T->nmax);
     226                 :         60 :   else T->nmax = k;
     227                 :            : 
     228                 :            :   /* non empty if nmin*amin <= k <= amax*nmax */
     229 [ +  - ][ -  + ]:         90 :   if ( T->amin*T->nmin > k || k > T->amax * T->nmax )
     230                 :            :   {
     231                 :          0 :     T->nmin = T->nmax = 0;
     232                 :            :   }
     233                 :            :   else
     234                 :            :   {
     235                 :            :     /* to reach nmin one must have k <= nmin*amax, otherwise increase nmin */
     236         [ +  + ]:         90 :     if ( T->nmin * T->amax < k )
     237                 :         70 :       T->nmin = 1 + (k - 1) / T->amax; /* ceil( k/tmax ) */
     238                 :            :     /* decrease nmax (if strip): k <= amin*nmax */
     239 [ +  + ][ +  + ]:         90 :     if (T->strip && T->nmax > k/T->amin)
     240                 :         10 :       T->nmax = k / T->amin; /* strip implies amin>0 */ /* fixme: take ceil( ) */
     241                 :            :     /* no need to change amin */
     242                 :            :     /* decrease amax if amax + (nmin-1)*amin > k  */
     243         [ +  + ]:         90 :     if ( T->amax + (T->nmin-1)* T->amin > k )
     244                 :         10 :       T->amax = k - (T->nmin-1)* T->amin;
     245                 :            :   }
     246                 :            : 
     247         [ +  + ]:         90 :   if ( T->amax < T->amin )
     248                 :         15 :     T->nmin = T->nmax = 0;
     249                 :            : 
     250                 :         90 :   T->v = zero_zv(T->nmax); /* partitions will be of length <= nmax */
     251                 :         90 :   T->k = k;
     252                 :         90 : }
     253                 :            : 
     254                 :            : GEN
     255                 :    2257685 : forpart_next(forpart_t *T)
     256                 :            : {
     257                 :    2257685 :   GEN v = T->v;
     258                 :    2257685 :   long n = lg(v)-1;
     259                 :            :   long i, s, a, k, vi, vn;
     260                 :            : 
     261 [ +  + ][ +  + ]:    2257685 :   if (n>0 && v[n])
     262                 :            :   {
     263                 :            :     /* find index to increase: i s.t. v[i+1],...v[n] is central a,..a,a+1,..a+1
     264                 :            :        keep s = v[i] + v[i+1] + ... + v[n] */
     265                 :    2257590 :     s = a = v[n];
     266 [ +  + ][ +  + ]:    3311990 :     for(i = n-1; i>0 && v[i]+1 >= a; s += v[i--]);
     267         [ +  + ]:    4515120 :     if (i == 0) {
     268                 :            :       /* v is central [ a, a, .. a, a+1, .. a+1 ] */
     269 [ +  + ][ +  + ]:        570 :       if ((n+1) * T->amin > s || n == T->nmax) return NULL;
     270                 :        510 :       i = 1; n++;
     271                 :        510 :       setlg(v, n+1);
     272                 :        510 :       vi = T->amin;
     273                 :            :     } else {
     274                 :    2257020 :       s += v[i];
     275                 :    2257020 :       vi = v[i]+1;
     276                 :            :     }
     277                 :            :   } else {
     278                 :            :     /* init v */
     279                 :         95 :     s = T->k;
     280         [ +  + ]:         95 :     if (T->amin == 0) T->amin = 1;
     281         [ +  + ]:         95 :     if (T->strip) { n = T->nmin; setlg(T->v, n+1); }
     282         [ +  + ]:         95 :     if (s==0)
     283                 :            :     {
     284 [ +  + ][ +  - ]:         15 :       if (n==0 && T->nmin==0) {T->nmin++; return v;}
     285                 :          5 :       return NULL;
     286                 :            :     }
     287         [ +  + ]:         80 :     if (n==0) return NULL;
     288                 :         75 :     vi = T->amin;
     289         [ +  + ]:         75 :     i = T->strip ? 1 : n + 1 - T->nmin; /* first non-zero index */
     290                 :            :   }
     291                 :            :   /* now fill [ v[i],... v[n] ] with s, start at vi */
     292                 :    2257605 :   vn = s - (n-i)*vi; /* expected value for v[n] */
     293 [ +  - ][ +  + ]:    2257605 :   if (T->amax && vn > T->amax)
     294                 :        100 :   {
     295                 :            :     /* do not exceed amax */
     296                 :            :     long ai, q, r;
     297                 :        100 :     vn -= vi;
     298                 :        100 :     ai = T->amax - vi;
     299                 :        100 :     q = vn / ai; /* number of nmax */
     300                 :        100 :     r = vn % ai; /* value before nmax */
     301                 :            :     /* fill [ v[i],... v[n] ] as [ vi,... vi, vi+r, amax,... amax ] */
     302         [ +  + ]:        335 :     while ( q-- ) v[n--] = T->amax;
     303         [ +  + ]:        100 :     if ( n >= i ) v[n--] = vi + r;
     304         [ +  + ]:        265 :     while ( n >= i ) v[n--] = vi;
     305                 :            :   } else {
     306                 :            :     /* fill as [ v[i], ... v[i], vn ] */
     307         [ +  + ]:    5568585 :     for ( k=i; k<n; v[k++] = vi );
     308                 :    2257505 :     v[n] = vn;
     309                 :            :   }
     310                 :    2257685 :   return v;
     311                 :            : }
     312                 :            : 
     313                 :            : GEN
     314                 :          0 : forpart_prev(forpart_t *T)
     315                 :            : {
     316                 :          0 :   GEN v = T->v;
     317                 :          0 :   long n = lg(v)-1;
     318                 :            :   long j, ni, q, r;
     319                 :            :   long i, s;
     320 [ #  # ][ #  # ]:          0 :   if (n>0 && v[n])
     321                 :            :   {
     322                 :            :     /* find index to decrease: start of last constant sequence, excluding v[n] */
     323                 :          0 :     i = n-1; s = v[n];
     324 [ #  # ][ #  # ]:          0 :     while (i>1 && (v[i-1]==v[i] || v[i+1]==T->amax))
                 [ #  # ]
     325                 :          0 :       s+= v[i--];
     326         [ #  # ]:          0 :     if (!i) return NULL;
     327                 :            :     /* amax condition: cannot decrease i if maximal on the right */
     328         [ #  # ]:          0 :     if ( v[i+1] == T->amax ) return NULL;
     329                 :            :     /* amin condition: stop if below except if strip & try to remove */
     330         [ #  # ]:          0 :     if (v[i] == T->amin) {
     331         [ #  # ]:          0 :       if (!T->strip) return NULL;
     332                 :          0 :       s += v[i]; v[i] = 0;
     333                 :            :     } else {
     334                 :          0 :       v[i]--; s++;
     335                 :            :     }
     336                 :            :     /* zero case... */
     337         [ #  # ]:          0 :     if (v[i] == 0)
     338                 :            :     {
     339         [ #  # ]:          0 :       if (T->nmin > n-i) return NULL; /* need too many non zero coeffs */
     340                 :            :       /* reduce size of v ? */
     341         [ #  # ]:          0 :       if (T->strip) {
     342                 :          0 :         i = 0; n--;
     343                 :          0 :         setlg(v, n+1);
     344                 :            :       }
     345                 :            :     }
     346                 :            :   } else
     347                 :            :   {
     348                 :          0 :     s = T->k;
     349                 :          0 :     i = 0;
     350         [ #  # ]:          0 :     if (s==0)
     351                 :            :     {
     352 [ #  # ][ #  # ]:          0 :       if (n==0 && T->nmin==0) {T->nmin++; return v;}
     353                 :          0 :       return NULL;
     354                 :            :     }
     355 [ #  # ][ #  # ]:          0 :     if (n*T->amax < s || s < T->nmin*T->amin) return NULL;
     356                 :            :   }
     357                 :            :   /* set minimal partition of sum s starting from index i+1 */
     358                 :          0 :   ni = n-i;
     359                 :          0 :   q = s / ni;
     360                 :          0 :   r = s % ni;
     361         [ #  # ]:          0 :   for(j=i+1;   j<=n-r; j++) v[j]=q;
     362         [ #  # ]:          0 :   for(j=n-r+1; j<=n;   j++) v[j]=q + 1;
     363                 :          0 :   return v;
     364                 :            : }
     365                 :            : 
     366                 :            : static long
     367                 :         30 : countpart(long k, GEN abound, GEN nbound)
     368                 :            : {
     369                 :         30 :   pari_sp av = avma;
     370                 :            :   long n;
     371                 :            :   forpart_t T;
     372         [ +  + ]:         30 :   if (k<0) return 0;
     373                 :         25 :   forpart_init(&T, k, abound, nbound);
     374         [ +  + ]:        245 :   for (n=0; forpart_next(&T); n++)
     375                 :        220 :   avma = av;
     376                 :         30 :   return n;
     377                 :            : }
     378                 :            : 
     379                 :            : GEN
     380                 :         30 : partitions(long k, GEN abound, GEN nbound)
     381                 :            : {
     382                 :            :   GEN v;
     383                 :            :   forpart_t T;
     384                 :         30 :   long i, n = countpart(k,abound,nbound);
     385         [ +  + ]:         30 :   if (n==0) return cgetg(1, t_VEC);
     386                 :         20 :   forpart_init(&T, k, abound, nbound);
     387                 :         20 :   v = cgetg(n+1, t_VEC);
     388         [ +  + ]:        240 :   for (i=1; i<=n; i++)
     389                 :        220 :     gel(v,i)=zv_copy(forpart_next(&T));
     390                 :         30 :   return v;
     391                 :            : }
     392                 :            : 
     393                 :            : void
     394                 :         45 : forpart(void *E, long call(void*, GEN), long k, GEN abound, GEN nbound)
     395                 :            : {
     396                 :            :   GEN v;
     397                 :            :   forpart_t T;
     398                 :         45 :   forpart_init(&T, k, abound, nbound);
     399         [ +  + ]:    2257220 :   while ((v=forpart_next(&T)))
     400         [ -  + ]:    2257175 :     if (call(E, v)) break;
     401                 :         45 : }
     402                 :            : 
     403                 :            : void
     404                 :         50 : forpart0(GEN k, GEN code, GEN abound, GEN nbound)
     405                 :            : {
     406                 :         50 :   pari_sp av = avma;
     407         [ -  + ]:         50 :   if (typ(k) != t_INT) pari_err_TYPE("forpart",k);
     408         [ +  + ]:         95 :   if (signe(k)<0) return;
     409                 :         45 :   push_lex(gen_0, code);
     410                 :         45 :   forpart((void*)code, &gp_evalvoid, itos(k), abound, nbound);
     411                 :         45 :   pop_lex(1);
     412                 :         45 :   avma=av;
     413                 :            : }

Generated by: LCOV version 1.9