Pari/GP Reference Documentation | Contents - Global index - GP keyboard shortcuts |
break breakpoint dbg_down dbg_err dbg_up dbg_x for forcomposite fordiv forell forpart forprime forstep forsubgroup forvec if iferr next return 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
n = 5;
for (n = 1, 10,
if (something_nice(), break);
);
\\ at this point
If the sequence
? for (n = 1, 10, n += 2; print(n)) 3 6 9 12
| |
break | |
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 | |
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 | |
(In the break loop) go down n frames. This allows to cancel a previous call to
| |
dbg_err | |
In the break loop, return the error data of the current error, if any.
See
? 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 | |
(In the break loop) go up n frames. This allows to inspect data of the
parent function. To cancel a
| |
dbg_x | |
Print the inner structure of
| |
for | |
Evaluates seq, where
the formal variable X goes from a to b. Nothing is done if a > b.
a and b must be in ℝ. If b is set to
| |
forcomposite | |
Evaluates seq, where the formal variable n ranges over the composite numbers between the non-negative 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 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 | |
Evaluates seq, where
the formal variable X ranges through the divisors of n
(see
This routine uses To avoid storing all divisors, possibly using a lot of memory, the following (much slower) routine loops over the divisors using essentially constant space:
FORDIV(N)= { my(P, E); P = factor(N); E = P[,2]; P = P[,1]; forvec( v = vector(#E, i, [0,E[i]]), X = factorback(P, v) \\ ... ); } ? for(i=1,10^5, FORDIV(i)) time = 3,445 ms. ? for(i=1,10^5, fordiv(i, d, )) time = 490 ms.
| |
forell | |
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 non-zero, 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
The library syntax is
| |
forpart | |
Evaluate seq over the partitions X = [x_1,...x_n] of the
integer k, i.e. increasing sequences x_1 ≤ x_2... ≤ x_n of sum
x_1+...+ x_n = k. By convention, 0 admits only the empty partition and
negative numbers have no partitions. A partition is given by a
? forpart(X=3, print(X)) Vecsmall([3]) Vecsmall([1, 2]) Vecsmall([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 X is of constant length nmax.
\\ at most 3 non-zero 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] The behavior is unspecified if X is modified inside the loop.
The library syntax is
| |
forprime | |
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
? forprime(p = 4, 10, print(p)) 5 7
Setting b to 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 [].
| |
forstep | |
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. s must be in ℝ^* or a vector of steps [s_1,...,s_n]. In the latter case, the successive steps are used in the order they appear in s.
? forstep(x=5, 20, [2,4], print(x)) 5 7 11 13 17 19
Setting b to
| |
forsubgroup | |
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ℤ g_1 x ℤ/2ℤ g_2:
? 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 (g_1, g_1 + g_2). This
routine is intended to treat huge groups, when 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
The library syntax is
| |
forvec | |
Let v be an n-component
vector (where n is arbitrary) of two-component vectors [a_i,b_i]
for 1 ≤ i ≤ n, where all entries a_i, b_i are real numbers.
This routine lets X vary over the n-dimensional hyperrectangle
given by v, that is, X is an n-dimensional vector taking
successively its entries X[i] in the range [a_i,b_i] with lexicographic
ordering. (The component with the highest index moves the fastest.)
The type of X is the same as the type of v: The expression seq is evaluated with the successive values of X. 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]
| |
if | |
Evaluates the expression sequence seq1 if a is non-zero, otherwise the expression seq2. Of course, seq1 or seq2 may be empty:
The value of an
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 (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
if (x != 0 && f(1/x), ...) is a perfectly safe statement.
Remark. Functions such as
| |
iferr | |
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
? 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 Internal errors, "system" errors.
*
*
*
*
* Syntax errors, type errors.
*
*
*
*
*
*
*
* Overflows.
*
*
*
*
*
*
* Errors triggered intentionally.
*
* Mathematical errors.
*
*
*
*
*
*
nfalgtobasis(nfinit(t^3-2), Mod(t,t^2+1)
E has three component, 1 (
*
*
*
| |
next | |
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 | |
Returns from current subroutine, with
result x. If x is omitted, return the
| |
until | |
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 is non-zero, 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.
| |