Pari/GP Reference Documentation HOME Contents - Global index - GP keyboard shortcuts

Programming in GP: control statements


break   breakpoint   dbg_down   dbg_err   dbg_up   dbg_x   for   forcomposite   fordiv   fordivfactored   foreach   forell   forfactored   forpart   forperm   forprime   forprimestep   forsquarefree   forstep   forsubgroup   forsubset   forvec   if   iferr   next   return   setdebug   until   while  
 

A number of control statements are available in GP. They are simpler and have a syntax slightly different from their C counterparts, but are quite powerful enough to write any kind of program. Some of them are specific to GP, since they are made for number theorists. As usual, X will denote any simple variable name, and seq will always denote a sequence of expressions, including the empty sequence.

Caveat. In constructs like

      for (X = a,b, seq)

the variable X is lexically scoped to the loop, leading to possibly unexpected behavior:

      n = 5;
      for (n = 1, 10,
        if (something_nice(), break);
      );
      \\   at this point n is 5 !

If the sequence seq modifies the loop index, then the loop is modified accordingly:

      ? for (n = 1, 10, n += 2; print(n))
      3
      6
      9
      12

break({n = 1}) HOME   TOP

Interrupts execution of current seq, and immediately exits from the n innermost enclosing loops, within the current function call (or the top level loop); the integer n must be positive. If n is greater than the number of enclosing loops, all enclosing loops are exited.

breakpoint() HOME   TOP

Interrupt the program and enter the breakloop. The program continues when the breakloop is exited.

  ? f(N,x)=my(z=x^2+1);breakpoint();gcd(N,z^2+1-z);
  ? f(221,3)
    ***   at top-level: f(221,3)
    ***                 ^ —  — --
    ***   in function f: my(z=x^2+1);breakpoint();gcd(N,z
    ***                              ^ —  —  —  —  —  — --
    ***   Break loop: type <Return> to continue; 'break' to go back to GP
  break> z
  10
  break>
  %2 = 13

dbg_down({n = 1}) HOME   TOP

(In the break loop) go down n frames. This allows to cancel a previous call to dbg_up.

  ? x = 0;
  ? g(x) = x-3;
  ? f(x) = 1 / g(x+1);
  ? for (x = 1, 5, f(x+1))
     ***   at top-level: for(x=1,5,f(x+1))
     ***                           ^ —  — -
     ***   in function f: 1/g(x+1)
     ***                   ^ —  — -
     *** _/_: impossible inverse in gdiv: 0.
     ***   Break loop: type 'break' to go back to GP prompt
  break> dbg_up(3) \\ go up 3 frames
    ***   at top-level: for(x=1,5,f(x+1))
    ***                 ^ —  —  —  —  — --
  break> x
  0
  break> dbg_down()
    ***   at top-level: for(x=1,5,f(x+1))
    ***                           ^ —  — -
  break> x
  1
  break> dbg_down()
    ***   at top-level: for(x=1,5,f(x+1))
    ***                           ^ —  — -
  break> x
  1
  break> dbg_down()
    ***   at top-level: for(x=1,5,f(x+1))
    ***                           ^ —  — -
    ***   in function f: 1/g(x+1)
    ***                   ^ —  — -
  break> x
  2

The above example shows that the notion of GP frame is finer than the usual stack of function calls (as given for instance by the GDB backtrace command): GP frames are attached to variable scopes and there are frames attached to control flow instructions such as a for loop above.

dbg_err() HOME   TOP

In the break loop, return the error data of the current error, if any. See iferr for details about error data. Compare:

  ? iferr(1/(Mod(2,12019)^(6!)-1),E,Vec(E))
  %1 = ["e_INV", "Fp_inv", Mod(119, 12019)]
  ? 1/(Mod(2,12019)^(6!)-1)
    ***   at top-level: 1/(Mod(2,12019)^(6!)-
    ***                  ^ —  —  —  —  —  — --
    *** _/_: impossible inverse in Fp_inv: Mod(119, 12019).
    ***   Break loop: type 'break' to go back to GP prompt
  break> Vec(dbg_err())
  ["e_INV", "Fp_inv", Mod(119, 12019)]

dbg_up({n = 1}) HOME   TOP

(In the break loop) go up n frames, which allows to inspect data of the parent function. To cancel a dbg_up call, use dbg_down.

  ? x = 0;
  ? g(x) = x-3;
  ? f(x) = 1 / g(x+1);
  ? for (x = 1, 5, f(x+1))
     ***   at top-level: for(x=1,5,f(x+1))
     ***                           ^ —  — -
     ***   in function f: 1/g(x+1)
     ***                   ^ —  — -
     *** _/_: impossible inverse in gdiv: 0.
     ***   Break loop: type 'break' to go back to GP prompt
   break> x
   2
   break> dbg_up()
     ***   at top-level: for(x=1,5,f(x+1))
     ***                           ^ —  — -
   break> x
   1
   break> dbg_up()
     ***   at top-level: for(x=1,5,f(x+1))
     ***                           ^ —  — -
   break> x
   1
   break> dbg_up()
     ***   at top-level: for(x=1,5,f(x+1))
     ***                 ^ —  —  —  —  — --
   break> x
   0
   break> dbg_down()    \\ back up once
     ***   at top-level: for(x=1,5,f(x+1))
     ***                           ^ —  — -
   break> x
   1

The above example shows that the notion of GP frame is finer than the usual stack of function calls (as given for instance by the GDB backtrace command): GP frames are attached to variable scopes and there are frames attached to control flow instructions such as a for loop above.

dbgx(A, {n}) HOME   TOP

Print the inner structure of A, complete if n is omitted, up to level n otherwise. This function is useful for debugging. It is similar to \x but does not require A to be a history entry. In particular, it can be used in the break loop.

for(X = a, b, seq) HOME   TOP

Evaluates seq, where the formal variable X goes from a to b, where a and b must be in ℝ. Nothing is done if a > b. If b is set to +oo, the loop will not stop; it is expected that the caller will break out of the loop itself at some point, using break or return.

forcomposite(n = a, {b}, seq) HOME   TOP

Evaluates seq, where the formal variable n ranges over the composite numbers between the nonnegative real numbers a to b, including a and b if they are composite. Nothing is done if a > b.

  ? forcomposite(n = 0, 10, print(n))
  4
  6
  8
  9
  10

Omitting b means we will run through all composites ≥ a, starting an infinite loop; it is expected that the user will break out of the loop himself at some point, using break or return.

Note that the value of n cannot be modified within seq:

  ? forcomposite(n = 2, 10, n = [])
   ***   at top-level: forcomposite(n=2,10,n=[])
   ***                                      ^ — 
   ***   index read-only: was changed to [].

fordiv(n, X, seq) HOME   TOP

Evaluates seq, where the formal variable X ranges through the divisors of n (see divisors, which is used as a subroutine). It is assumed that factor can handle n, without negative exponents. Instead of n, it is possible to input a factorization matrix, i.e. the output of factor(n).

This routine uses divisors as a subroutine, then loops over the divisors. In particular, if n is an integer, divisors are sorted by increasing size.

To avoid storing all divisors, possibly using a lot of memory, the following (slower) routine loops over the divisors using essentially constant space:

  FORDIV(N)=
  { my(F = factor(N), P = F[,1], E = F[,2]);
  
    forvec(v = vector(#E, i, [0,E[i]]), X = factorback(P, v));
  }
  ? for(i=1, 10^6, FORDIV(i))
  time = 11,180 ms.
  ? for(i=1, 10^6, fordiv(i, d, ))
  time = 2,667 ms.

Of course, the divisors are no longer sorted by inreasing size.

fordivfactored(n, X, seq) HOME   TOP

Evaluates seq, where the formal variable X ranges through [d, factor(d)], where d is a divisors of n (see divisors, which is used as a subroutine). Note that such a pair is accepted as argument to all multiplicative functions.

It is assumed that factor can handle n, without negative exponents. Instead of n, it is possible to input a factorization matrix, i.e. the output of factor(n). This routine uses divisors(,1) as a subroutine, then loops over the divisors. In particular, if n is an integer, divisors are sorted by increasing size.

This function is particularly useful when n is hard to factor and one must evaluate multiplicative function on its divisors: we avoid refactoring each divisor in turn. It also provides a small speedup when n is easy to factor; compare

  ? A = 10^8; B = A + 10^5;
  ? for (n = A, B, fordiv(n, d, eulerphi(d)));
  time = 2,091 ms.
  ? for (n = A, B, fordivfactored(n, d, eulerphi(d)));
  time = 1,298 ms. \\ avoid refactoring the divisors
  ? forfactored (n = A, B, fordivfactored(n, d, eulerphi(d)));
  time = 1,270 ms. \\ also avoid factoring the consecutive n's !

foreach(V, X, seq) HOME   TOP

Evaluates seq, where the formal variable X ranges through the components of V (t_VEC, t_COL, t_LIST or t_MAT). A matrix argument is interpreted as a vector containing column vectors, as in Vec(V).

forell(E, a, b, seq, {flag = 0}) HOME   TOP

Evaluates seq, where the formal variable E = [name, M, G] ranges through all elliptic curves of conductors from a to b. In this notation name is the curve name in Cremona's elliptic curve database, M is the minimal model, G is a ℤ-basis of the free part of the Mordell-Weil group E(ℚ). If flag is nonzero, select only the first curve in each isogeny class.

  ? forell(E, 1, 500, my([name,M,G] = E); \
      if (#G > 1, print(name)))
  389a1
  433a1
  446d1
  ? c = 0; forell(E, 1, 500, c++); c   \\ number of curves
  %2 = 2214
  ? c = 0; forell(E, 1, 500, c++, 1); c \\ number of isogeny classes
  %3 = 971

The elldata database must be installed and contain data for the specified conductors.

The library syntax is forell(void *data, long (*f)(void*,GEN), long a, long b, long flag).

forfactored(N = a, b, seq) HOME   TOP

Evaluates seq, where the formal variable N is [n, factor(n)] and n goes from a to b; a and b must be integers. Nothing is done if a > b.

This function is only implemented for |a|, |b| < 264 (232 on a 32-bit machine). It uses a sieve and runs in time O(sqrt{b} + b-a). It should be at least 3 times faster than regular factorization as long as the interval length b-a is much larger than sqrt{b} and get relatively faster as the bounds increase. The function slows down dramatically if primelimit < sqrt{b}.

  ? B = 10^9;
  ? for (N = B, B+10^6, factor(N))
  time = 4,538 ms.
  ? forfactored (N = B, B+10^6, [n,fan] = N)
  time = 1,031 ms.
  
  ? B = 10^11;
  ? for (N = B, B+10^6, factor(N))
  time = 15,575 ms.
  ? forfactored (N = B, B+10^6, [n,fan] = N)
  time = 2,375 ms.
  
  ? B = 10^14;
  ? for (N = B, B+10^6, factor(N))
  time = 1min, 4,948 ms.
  ? forfactored (N = B, B+10^6, [n,fan] = N)
  time = 58,601 ms.

The last timing is with the default primelimit (500000) which is much less than sqrt{B+106}; it goes down to 26,750ms if primelimit gets bigger than that bound. In any case sqrt{B+106} is much larger than the interval length 106 so forfactored gets relatively slower for that reason as well.

Note that all PARI multiplicative functions accept the [n,fan] argument natively:

  ? s = 0; forfactored(N = 1, 10^7, s += moebius(N)*eulerphi(N)); s
  time = 6,001 ms.
  %1 = 6393738650
  ? s = 0; for(N = 1, 10^7, s += moebius(N)*eulerphi(N)); s
  time = 28,398 ms. \\ slower, we must factor N. Twice.
  %2 = 6393738650

The following loops over the fundamental dicriminants less than X:

  ? X = 10^8;
  ? forfactored(d=1,X, if (isfundamental(d),));
  time = 34,030 ms.
  ? for(d=1,X, if (isfundamental(d),))
  time = 1min, 24,225 ms.

forpart(X = k, seq, {a = k}, {n = k}) HOME   TOP

Evaluate seq over the partitions X = [x1,...xn] of the integer k, i.e. increasing sequences x1 ≤ x2... ≤ xn of sum x1+...+ xn = k. By convention, 0 admits only the empty partition and negative numbers have no partitions. A partition is given by a t_VECSMALL, where parts are sorted in nondecreasing order. The partitions are listed by increasing size and in lexicographic order when sizes are equal:

  ? forpart(X=4, print(X))
  Vecsmall([4])
  Vecsmall([1, 3])
  Vecsmall([2, 2])
  Vecsmall([1, 1, 2])
  Vecsmall([1, 1, 1, 1])

Optional parameters n and a are as follows:

* n = nmax (resp. n = [nmin,nmax]) restricts partitions to length less than nmax (resp. length between nmin and nmax), where the length is the number of nonzero entries.

* a = amax (resp. a = [amin,amax]) restricts the parts to integers less than amax (resp. between amin and amax).

By default, parts are positive and we remove zero entries unless amin ≤ 0, in which case we fix the size #X = nmax:

  \\ at most 3 nonzero parts, all <= 4
  ? forpart(v=5,print(Vec(v)), 4, 3)
  [1, 4]
  [2, 3]
  [1, 1, 3]
  [1, 2, 2]
  
  \\ between 2 and 4 parts less than 5, fill with zeros
  ? forpart(v=5,print(Vec(v)),[0,5],[2,4])
  [0, 0, 1, 4]
  [0, 0, 2, 3]
  [0, 1, 1, 3]
  [0, 1, 2, 2]
  [1, 1, 1, 2]
  
  \\ no partitions of 1 with 2 to 4 nonzero parts
  ? forpart(v=1,print(v),[0,5],[2,4])
  ?

The behavior is unspecified if X is modified inside the loop.

The library syntax is forpart(void *data, long (*call)(void*,GEN), long k, GEN a, GEN n).

forperm(a, p, seq) HOME   TOP

Evaluates seq, where the formal variable p goes through some permutations given by a t_VECSMALL. If a is a positive integer then P goes through the permutations of {1, 2, ..., a} in lexicographic order and if a is a small vector then p goes through the (multi)permutations lexicographically larger than or equal to a.

  ? forperm(3, p, print(p))
  Vecsmall([1, 2, 3])
  Vecsmall([1, 3, 2])
  Vecsmall([2, 1, 3])
  Vecsmall([2, 3, 1])
  Vecsmall([3, 1, 2])
  Vecsmall([3, 2, 1])

When a is itself a t_VECSMALL or a t_VEC then p iterates through multipermutations

  ? forperm([2,1,1,3], p, print(p))
  Vecsmall([2, 1, 1, 3])
  Vecsmall([2, 1, 3, 1])
  Vecsmall([2, 3, 1, 1])
  Vecsmall([3, 1, 1, 2])
  Vecsmall([3, 1, 2, 1])
  Vecsmall([3, 2, 1, 1])

forprime(p = a, {b}, seq) HOME   TOP

Evaluates seq, where the formal variable p ranges over the prime numbers between the real numbers a to b, including a and b if they are prime. More precisely, the value of p is incremented to nextprime(p + 1), the smallest prime strictly larger than p, at the end of each iteration. Nothing is done if a > b.

  ? forprime(p = 4, 10, print(p))
  5
  7

Setting b to +oo means we will run through all primes ≥ a, starting an infinite loop; it is expected that the caller will break out of the loop itself at some point, using break or return.

Note that the value of p cannot be modified within seq:

  ? forprime(p = 2, 10, p = [])
   ***   at top-level: forprime(p=2,10,p=[])
   ***                                   ^ — 
   ***   prime index read-only: was changed to [].

forprimestep(p = a, b, q, seq) HOME   TOP

Evaluates seq, where the formal variable p ranges over the prime numbers in an arithmetic progression in [a,b]: q is either an integer (p = a (mod q)) or an intmod Mod(c,N) and we restrict to that congruence class. Nothing is done if a > b.

  ? forprimestep(p = 4, 30, 5, print(p))
  19
  29
  ? forprimestep(p = 4, 30, Mod(1,5), print(p))
  11

Setting b to +oo means we will run through all primes ≥ a, starting an infinite loop; it is expected that the caller will break out of the loop itself at some point, using break or return.

Note that the value of p cannot be modified within seq:

  ? forprimestep(p = 2, 10, 3, p = [])
   ***   at top-level: forprimestep(p=2,10,3,p=[])
   ***                                         ^ — 
   ***   prime index read-only: was changed to [].

forsquarefree(N = a, b, seq) HOME   TOP

Evaluates seq, where the formal variable N is [n, factor(n)] and n goes through squarefree integers from a to b; a and b must be integers. Nothing is done if a > b.

  ? forsquarefree(N=-3,9,print(N))
  [-3, [-1, 1; 3, 1]]
  [-2, [-1, 1; 2, 1]]
  [-1, Mat([-1, 1])]
  [1, matrix(0,2)]
  [2, Mat([2, 1])]
  [3, Mat([3, 1])]
  [5, Mat([5, 1])]
  [6, [2, 1; 3, 1]]
  [7, Mat([7, 1])]

This function is only implemented for |a|, |b| < 264 (232 on a 32-bit machine). It uses a sieve and runs in time O(sqrt{b} + b-a). It should be at least 5 times faster than regular factorization as long as the interval length b-a is much larger than sqrt{b} and get relatively faster as the bounds increase. The function slows down dramatically if primelimit < sqrt{b}. It is comparable to forfactored, but about ζ(2) = π2/6 times faster due to the relative density of squarefree integers.

  ? B = 10^9;
  ? for (N = B, B+10^6, factor(N))
  time = 2,463 ms.
  ? forfactored (N = B, B+10^6, [n,fan] = N)
  time = 567 ms.
  ? forsquarefree (N = B, B+10^6, [n,fan] = N)
  time = 343 ms.
  
  ? B = 10^11;
  ? for (N = B, B+10^6, factor(N))
  time = 8,012 ms.
  ? forfactored (N = B, B+10^6, [n,fan] = N)
  time = 1,293 ms.
  ? forsquarefree (N = B, B+10^6, [n,fan] = N)
  time = 713 ms.
  
  ? B = 10^14;
  ? for (N = B, B+10^6, factor(N))
  time = 41,283 ms.
  ? forsquarefree (N = B, B+10^6, [n,fan] = N)
  time = 33,399 ms.

The last timing is with the default primelimit (500000) which is much less than sqrt{B+106}; it goes down to 29,253ms if primelimit gets bigger than that bound. In any case sqrt{B+106} is much larger than the interval length 106 so forsquarefree gets relatively slower for that reason as well.

Note that all PARI multiplicative functions accept the [n,fan] argument natively:

  ? s = 0; forsquarefree(N = 1, 10^7, s += moebius(N)*eulerphi(N)); s
  time = 2,003 ms.
  %1 = 6393738650
  ? s = 0; for(N = 1, 10^7, s += moebius(N)*eulerphi(N)); s
  time = 18,024 ms. \\ slower, we must factor N. Twice.
  %2 = 6393738650

The following loops over the fundamental dicriminants less than X:

  ? X = 10^8;
  ? for(d=1,X, if (isfundamental(d),))
  time = 53,387 ms.
  ? forfactored(d=1,X, if (isfundamental(d),));
  time = 13,861 ms.
  ? forsquarefree(d=1,X, D = quaddisc(d); if (D <= X, ));
  time = 14,341 ms.

Note that in the last loop, the fundamental discriminants D are not evaluated in order (since quaddisc(d) for squarefree d is either d or 4d) but the set of numbers we run through is the same. Not worth the complication since it's slower than testing isfundamental. A faster, more complicated approach uses two loops. For simplicity, assume X is divisible by 4:

  ? forsquarefree(d=1,X/4, D = quaddisc(d));
  time = 3,642 ms.
  ? forsquarefree(d=X/4+1,X, if (d[1] % 4 == 1,));
  time = 7,772 ms.

This is the price we pay for a faster evaluation,

We can run through negative fundamental discriminants in the same way:

  ? forfactored(d=-X,-1, if (isfundamental(d),));

forstep(X = a, b, s, seq) HOME   TOP

Evaluates seq, where the formal variable X goes from a to b in increments of s. Nothing is done if s > 0 and a > b or if s < 0 and a < b. The s can be

* a positive real number, preferably an integer: X = a, a+s, a+2s...

* an intmod Mod(c,N) (restrict to the corresponding arithmetic progression starting at the smallest integer A ≥ a and congruent to c modulo N): X = A, A + N,...

* a vector of steps [s1,...,sn] (the successive steps in ℝ* are used in the order they appear in s): X = a, a+s1, a+s1+s2, ...

  ? forstep(x=5, 10, 2, print(x))
  5
  7
  9
  ? forstep(x=5, 10, Mod(1,3), print(x))
  7
  10
  ? forstep(x=5, 10, [1,2], print(x))
  5
  6
  8
  9

Setting b to +oo will start an infinite loop; it is expected that the caller will break out of the loop itself at some point, using break or return.

forsubgroup(H = G, {bound}, seq) HOME   TOP

Evaluates seq for each subgroup H of the abelian group G (given in SNF form or as a vector of elementary divisors).

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

The subgroups are not ordered in any obvious way, unless G is a p-group in which case Birkhoff's algorithm produces them by decreasing index. A subgroup is given as a matrix whose columns give its generators on the implicit generators of G. For example, the following prints all subgroups of index less than 2 in G = ℤ/2ℤ g1 x ℤ/2ℤ g2:

  ? G = [2,2]; forsubgroup(H=G, 2, print(H))
  [1; 1]
  [1; 2]
  [2; 1]
  [1, 0; 1, 1]

The last one, for instance is generated by (g1, g1 + g2). This routine is intended to treat huge groups, when subgrouplist is not an option due to the sheer size of the output.

For maximal speed the subgroups have been left as produced by the algorithm. To print them in canonical form (as left divisors of G in HNF form), one can for instance use

  ? G = matdiagonal([2,2]); forsubgroup(H=G, 2, print(mathnf(concat(G,H))))
  [2, 1; 0, 1]
  [1, 0; 0, 2]
  [2, 0; 0, 1]
  [1, 0; 0, 1]

Note that in this last representation, the index [G:H] is given by the determinant. See galoissubcyclo and galoisfixedfield for applications to Galois theory.

The library syntax is forsubgroup(void *data, long (*call)(void*,GEN), GEN G, GEN bound).

forsubset(nk, s, seq) HOME   TOP

If nk is a nonnegative integer n, evaluates seq, where the formal variable s goes through all subsets of {1, 2,..., n}; if nk is a pair [n,k] of integers, s goes through subsets of size k of {1, 2,..., n}. In both cases s goes through subsets in lexicographic order among subsets of the same size and smaller subsets come first.

  ? forsubset([5,3], s, print(s))
  Vecsmall([1, 2, 3])
  Vecsmall([1, 2, 4])
  Vecsmall([1, 2, 5])
  Vecsmall([1, 3, 4])
  Vecsmall([1, 3, 5])
  Vecsmall([1, 4, 5])
  Vecsmall([2, 3, 4])
  Vecsmall([2, 3, 5])
  Vecsmall([2, 4, 5])
  Vecsmall([3, 4, 5])

  ? forsubset(3, s, print(s))
  Vecsmall([])
  Vecsmall([1])
  Vecsmall([2])
  Vecsmall([3])
  Vecsmall([1, 2])
  Vecsmall([1, 3])
  Vecsmall([2, 3])
  Vecsmall([1, 2, 3])

The running time is proportional to the number of subsets enumerated, respectively 2n and binomial(n,k):

  ? c = 0; forsubset([40,35],s,c++); c
  time = 128 ms.
  %4 = 658008
  ? binomial(40,35)
  %5 = 658008

forvec(X = v, seq, {flag = 0}) HOME   TOP

Let v be an n-component vector (where n is arbitrary) of two-component vectors [ai,bi] for 1 ≤ i ≤ n, where all entries ai, bi are real numbers. This routine lets X vary over the n-dimensional box given by v with unit steps: X is an n-dimensional vector whose i-th entry X[i] runs through ai, ai+1, ai+2,... stopping with the first value greater than bi (note that neither ai nor bi - ai are required to be integers). The values of X are ordered lexicographically, like embedded for loops, and the expression seq is evaluated with the successive values of X. The type of X is the same as the type of v: t_VEC or t_COL.

If flag = 1, generate only nondecreasing vectors X, and if flag = 2, generate only strictly increasing vectors X.

  ? forvec (X=[[0,1],[-1,1]], print(X));
  [0, -1]
  [0, 0]
  [0, 1]
  [1, -1]
  [1, 0]
  [1, 1]
  ? forvec (X=[[0,1],[-1,1]], print(X), 1);
  [0, 0]
  [0, 1]
  [1, 1]
  ? forvec (X=[[0,1],[-1,1]], print(X), 2)
  [0, 1]

As a shortcut, a vector of the form v = [[0,c1-1],...[0,cn-1]] can be abbreviated as v = [c1,...cn] and flag is ignored in this case. More generally, if v is a vector of nonnegative integers ci the loop runs over representatives of ℤn/vℤn; and flag is again ignored. The vector v may contain zero entries, in which case the loop spans an infinite lattice. The values are ordered lexicographically, graded by increasing L1-norm on free (ci = 0) components.

This allows to iterate over elements of abelian groups using their .cyc vector.

  ? forvec (X=[2,3], print(X));
  [0, 0]
  [0, 1]
  [0, 2]
  [1, 0]
  [1, 1]
  [1, 2]
  ? my(i);forvec (X=[0,0], print(X); if (i++ > 10, break));
  [0, 0]
  [-1, 0]
  [0, -1]
  [0, 1]
  [1, 0]
  [-2, 0]
  [-1, -1]
  [-1, 1]
  [0, -2]
  [0, 2]
  [1, -1]
  ? zn = znstar(36,1);
  ? forvec (chi = zn.cyc, if (chareval(zn,chi,5) == 5/6, print(chi)));
  [1, 0]
  [1, 1]
  ? bnrchar(zn, [5], [5/6]) \\ much more efficient in general
  %5 = [[1, 1], [1, 0]]
  

if(a, {seq1}, {seq2}) HOME   TOP

Evaluates the expression sequence seq1 if a is nonzero, otherwise the expression seq2. Of course, seq1 or seq2 may be empty:

if (a,seq) evaluates seq if a is not equal to zero (you don't have to write the second comma), and does nothing otherwise,

if (a,,seq) evaluates seq if a is equal to zero, and does nothing otherwise. You could get the same result using the ! (not) operator: if (!a,seq).

The value of an if statement is the value of the branch that gets evaluated: for instance

  x = if(n % 4 == 1, y, z);

sets x to y if n is 1 modulo 4, and to z otherwise.

Successive 'else' blocks can be abbreviated in a single compound if as follows:

  if (test1, seq1,
      test2, seq2,
      ...
      testn, seqn,
      seqdefault);

is equivalent to

  if (test1, seq1
           , if (test2, seq2
                      , ...
                        if (testn, seqn, seqdefault)...));

For instance, this allows to write traditional switch / case constructions:

  if (x == 0, do0(),
      x == 1, do1(),
      x == 2, do2(),
      dodefault());

Remark. The boolean operators && and || are evaluated according to operator precedence as explained in Section se:operators, but, contrary to other operators, the evaluation of the arguments is stopped as soon as the final truth value has been determined. For instance

  if (x != 0 && f(1/x), ...)

is a perfectly safe statement.

Remark. Functions such as break and next operate on loops, such as forxxx, while, until. The if statement is not a loop. (Obviously!)

iferr(seq1, E, seq2, {pred}) HOME   TOP

Evaluates the expression sequence seq1. If an error occurs, set the formal parameter E set to the error data. If pred is not present or evaluates to true, catch the error and evaluate seq2. Both pred and seq2 can reference E. The error type is given by errname(E), and other data can be accessed using the component function. The code seq2 should check whether the error is the one expected. In the negative the error can be rethrown using error(E) (and possibly caught by an higher iferr instance). The following uses iferr to implement Lenstra's ECM factoring method

  ? ecm(N, B = 1000!, nb = 100)=
    {
      for(a = 1, nb,
        iferr(ellmul(ellinit([a,1]*Mod(1,N)), [0,1]*Mod(1,N), B),
          E, return(gcd(lift(component(E,2)),N)),
          errname(E)=="e_INV" && type(component(E,2)) == "t_INTMOD"))
    }
  ? ecm(2^101-1)
  %2 = 7432339208719

The return value of iferr itself is the value of seq2 if an error occurs, and the value of seq1 otherwise. We now describe the list of valid error types, and the attached error data E; in each case, we list in order the components of E, accessed via component(E,1), component(E,2), etc.

Internal errors, "system" errors.

* "e_ARCH". A requested feature s is not available on this architecture or operating system. E has one component (t_STR): the missing feature name s.

* "e_BUG". A bug in the PARI library, in function s. E has one component (t_STR): the function name s.

* "e_FILE". Error while trying to open a file. E has two components, 1 (t_STR): the file type (input, output, etc.), 2 (t_STR): the file name.

* "e_IMPL". A requested feature s is not implemented. E has one component, 1 (t_STR): the feature name s.

* "e_PACKAGE". Missing optional package s. E has one component, 1 (t_STR): the package name s.

Syntax errors, type errors.

* "e_DIM". The dimensions of arguments x and y submitted to function s does not match up. E.g., multiplying matrices of inconsistent dimension, adding vectors of different lengths,... E has three component, 1 (t_STR): the function name s, 2: the argument x, 3: the argument y.

* "e_FLAG". A flag argument is out of bounds in function s. E has one component, 1 (t_STR): the function name s.

* "e_NOTFUNC". Generated by the PARI evaluator; tried to use a GEN x which is not a t_CLOSURE in a function call syntax (as in f = 1; f(2);). E has one component, 1: the offending GEN x.

* "e_OP". Impossible operation between two objects than cannot be typecast to a sensible common domain for deeper reasons than a type mismatch, usually for arithmetic reasons. As in O(2) + O(3): it is valid to add two t_PADICs, provided the underlying prime is the same; so the addition is not forbidden a priori for type reasons, it only becomes so when inspecting the objects and trying to perform the operation. E has three components, 1 (t_STR): the operator name op, 2: first argument, 3: second argument.

* "e_TYPE". An argument x of function s had an unexpected type. (As in factor("blah").) E has two components, 1 (t_STR): the function name s, 2: the offending argument x.

* "e_TYPE2". Forbidden operation between two objects than cannot be typecast to a sensible common domain, because their types do not match up. (As in Mod(1,2) + Pi.) E has three components, 1 (t_STR): the operator name op, 2: first argument, 3: second argument.

* "e_PRIORITY". Object o in function s contains variables whose priority is incompatible with the expected operation. E.g. Pol([x,1], 'y): this raises an error because it's not possible to create a polynomial whose coefficients involve variables with higher priority than the main variable. E has four components: 1 (t_STR): the function name s, 2: the offending argument o, 3 (t_STR): an operator op describing the priority error, 4 (t_POL): the variable v describing the priority error. The argument satisfies variable(x) op variable(v).

* "e_VAR". The variables of arguments x and y submitted to function s does not match up. E.g., considering the algebraic number Mod(t,t^2+1) in nfinit(x^2+1). E has three component, 1 (t_STR): the function name s, 2 (t_POL): the argument x, 3 (t_POL): the argument y.

Overflows.

* "e_COMPONENT". Trying to access an inexistent component in a vector/matrix/list in a function: the index is less than 1 or greater than the allowed length. E has four components, 1 (t_STR): the function name 2 (t_STR): an operator op ( < or > ), 2 (t_GEN): a numerical limit l bounding the allowed range, 3 (GEN): the index x. It satisfies x op l.

* "e_DOMAIN". An argument is not in the function's domain. E has five components, 1 (t_STR): the function name, 2 (t_STR): the mathematical name of the out-of-domain argument 3 (t_STR): an operator op describing the domain error, 4 (t_GEN): the numerical limit l describing the domain error, 5 (GEN): the out-of-domain argument x. The argument satisfies x op l, which prevents it from belonging to the function's domain.

* "e_MAXPRIME". A function using the precomputed list of prime numbers ran out of primes. E has one component, 1 (t_INT): the requested prime bound, which overflowed primelimit or 0 (bound is unknown).

* "e_MEM". A call to pari_malloc or pari_realloc failed. E has no component.

* "e_OVERFLOW". An object in function s becomes too large to be represented within PARI's hardcoded limits. (As in 2^2^2^10 or exp(1e100), which overflow in lg and expo.) E has one component, 1 (t_STR): the function name s.

* "e_PREC". Function s fails because input accuracy is too low. (As in floor(1e100) at default accuracy.) E has one component, 1 (t_STR): the function name s.

* "e_STACK". The PARI stack overflows. E has no component.

Errors triggered intentionally.

* "e_ALARM". A timeout, generated by the alarm function. E has one component (t_STR): the error message to print.

* "e_USER". A user error, as triggered by error(g1,...,gn). E has one component, 1 (t_VEC): the vector of n arguments given to error.

Mathematical errors.

* "e_CONSTPOL". An argument of function s is a constant polynomial, which does not make sense. (As in galoisinit(Pol(1)).) E has one component, 1 (t_STR): the function name s.

* "e_COPRIME". Function s expected coprime arguments, and did receive x,y, which were not. E has three component, 1 (t_STR): the function name s, 2: the argument x, 3: the argument y.

* "e_INV". Tried to invert a noninvertible object x in function s. E has two components, 1 (t_STR): the function name s, 2: the noninvertible x. If x = Mod(a,b) is a t_INTMOD and a is not 0 mod b, this allows to factor the modulus, as gcd(a,b) is a nontrivial divisor of b.

* "e_IRREDPOL". Function s expected an irreducible polynomial, and did receive T, which was not. (As in nfinit(x^2-1).) E has two component, 1 (t_STR): the function name s, 2 (t_POL): the polynomial x.

* "e_MISC". Generic uncategorized error. E has one component (t_STR): the error message to print.

* "e_MODULUS". moduli x and y submitted to function s are inconsistent. As in

     nfalgtobasis(nfinit(t^3-2), Mod(t,t^2+1))

E has three component, 1 (t_STR): the function s, 2: the argument x, 3: the argument y.

* "e_PRIME". Function s expected a prime number, and did receive p, which was not. (As in idealprimedec(nf, 4).) E has two component, 1 (t_STR): the function name s, 2: the argument p.

* "e_ROOTS0". An argument of function s is a zero polynomial, and we need to consider its roots. (As in polroots(0).) E has one component, 1 (t_STR): the function name s.

* "e_SQRTN". Trying to compute an n-th root of x, which does not exist, in function s. (As in sqrt(Mod(-1,3)).) E has two components, 1 (t_STR): the function name s, 2: the argument x.

next({n = 1}) HOME   TOP

Interrupts execution of current seq, resume the next iteration of the innermost enclosing loop, within the current function call (or top level loop). If n is specified, resume at the n-th enclosing loop. If n is bigger than the number of enclosing loops, all enclosing loops are exited.

return({x = 0}) HOME   TOP

Returns from current subroutine, with result x. If x is omitted, return the (void) value (return no result, like print).

setdebug({D}, {n}) HOME   TOP

Sets debug level for domain D to n (0 ≤ n ≤ 20). The domain D is a character string describing a Pari feature or code module, such as "bnf", "qflll" or "polgalois". This allows to selectively increase or decrease the diagnostics attached to a particular feature. If n is omitted, returns the current level for domain D. If D is omitted, returns a two-column matrix which lists the available domains with their levels. The debug default allows to reset all debug levels to a given value.

  ? setdebug()[,1] \\ list of all domains
  ["alg", "arith", "bern", "bnf", "bnr", "bnrclassfield", ..., "zetamult"]
  
  ? \g 1   \\ sets all debug levels to 1
    debug = 1
  ? setdebug("bnf", 0); \\ kills messages related to bnfinit and bnfisrincipal

until(a, seq) HOME   TOP

Evaluates seq until a is not equal to 0 (i.e. until a is true). If a is initially not equal to 0, seq is evaluated once (more generally, the condition on a is tested after execution of the seq, not before as in while).

while(a, seq) HOME   TOP

While a is nonzero, evaluates the expression sequence seq. The test is made before evaluating the seq, hence in particular if a is initially equal to zero the seq will not be evaluated at all.