Catalogue of GP/PARI Functions: Programming under GP
Author: Nils-Peter Skoruppa
Keywords: PARI, GP, DOC

### Programming under GP

#### break({n = 1})

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

#### for(X = a,b,seq)

the formal variable X going from a to b, the seq is evaluated. Nothing is done if a > b. a and b must be in R.

#### fordiv(n,X,seq)

the formal variable X ranging through the positive divisors of n, the sequence seq is evaluated. n must be of type integer.

#### forprime(X = a,b,seq)

the formal variable X ranging over the prime numbers between a to b (including a and b if they are prime), the seq is evaluated. More precisely, the value of X is incremented to the smallest prime strictly larger than X at the end of each iteration. Nothing is done if a > b. Note that a and b must be in R.

    ? { forprime(p = 2, 12,
           print(p);
           if (p == 3, p = 6);
         )
       }
     2
     3
     7
     11

#### forstep(X = a,b,s,seq)

the formal variable X going from a to b, in increments of s, the seq is evaluated. Nothing is done if s > 0 and a > b or if s < 0 and a < b. s must be in R^* 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

#### forsubgroup(H = G,{B},seq)

executes seq for each subgroup H of the \emph{abelian} group G (given in SNF form or as a vector of elementary divisors), whose index is bounded by B. 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 = Z/2Z g_1 x Z/2Z 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 `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 `nfsubfields` applications to Galois theory.

Warning: the present implementation cannot treat a group G, if one of its p-Sylow subgroups has a cyclic factor with more than 2^{31}, resp.2^{63} elements on a 32-bit, resp.64-bit architecture.

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

v being an n-component vector (where n is arbitrary) of two-component vectors [a_i,b_i] for 1 `<=` i `<=` n, the seq is evaluated with the formal variable X[1] going from a_1 to b_1,...,X[n] going from a_n to b_n. The formal variable with the highest index moves the fastest. If flag = 1, generate only nondecreasing vectors X, and if flag = 2, generate only strictly increasing vectors X.

#### if(a,{seq1},{seq2})

if a is non-zero, the expression sequence seq1 is evaluated, otherwise the expression seq2 is evaluated. Of course, seq1 or seq2 may be empty, so `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, whereas `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)`.

Note that the boolean operators `&&` and `||` are evaluated according to operator precedence as explained in Section (??), but that, contrary to other operators, the evaluation of the arguments is stopped as soon as the final truth value has been determined. For instance

    if (reallydoit && longcomplicatedfunction(), ...)%

is a perfectly safe statement.

Recall that functions such as `break` and `next` operate on \emph{loops} (such as `forxxx`, `while`, `until`). The `if` statement is \emph{not} a loop (obviously!).

#### next({n = 1})

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})

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

#### until(a,seq)

evaluates expression sequence 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 \emph{after} execution of the seq, not before as in `while`).

#### while(a,seq)

while a is non-zero evaluate the expression sequence seq. The test is made \emph{before} evaluating the seq, hence in particular if a is initially equal to zero the seq will not be evaluated at all.

#### addhelp(S,str)

changes the help message for the symbol S. The string str is expanded on the spot and stored as the online help for S. If S is a function \emph{you} have defined, its definition will still be printed before the message str. It is recommended that you document global variables and user functions in this way. Of course `gp` won't protest if you don't do it.

There's nothing to prevent you from modifying the help of built-in PARI functions (but if you do, we'd like to hear why you needed to do it!).

#### alias(newkey,key)

defines the keyword newkey as an alias for keyword key. key must correspond to an existing \emph{function} name. This is different from the general user macros in that alias expansion takes place immediately upon execution, without having to look up any function code, and is thus much faster. A sample alias file `misc/gpalias` is provided with the standard distribution. Alias commands are meant to be read upon startup from the `.gprc` file, to cope with function names you are dissatisfied with, and should be useless in interactive usage.

#### allocatemem({x = 0})

this is a very special operation which allows the user to change the stack size \emph{after} initialization. x must be a non-negative integer. If x! = 0, a new stack of size 16*\lceil x/16\rceil bytes will be allocated, all the PARI data on the old stack will be moved to the new one, and the old stack will be discarded. If x = 0, the size of the new stack will be twice the size of the old one.

Although it is a function, this must be the \emph{last} instruction in any GP sequence. The technical reason is that this routine usually moves the stack, so objects from the current sequence might not be correct anymore. Hence, to prevent such problems, this routine terminates by a `longjmp` (just as an error would) and not by a return.

The library syntax is allocatemoremem(x), where x is an unsigned long, and the return type is void. `gp` uses a variant which ends by a `longjmp`.

#### default({key},{val},{flag})

sets the default corresponding to keyword key to value val. val is a string (which of course accepts numeric arguments without adverse effects, due to the expansion mechanism). See Section (??) for a list of available defaults, and Section (??) for some shortcut alternatives. Typing `default()` (or `\d`) yields the complete default list as well as their current values.

If val is omitted, prints the current value of default key. If flag is set, returns the result instead of printing it.

#### error({str}*)

outputs its argument list (each of them interpreted as a string), then interrupts the running `gp` program, returning to the input prompt.

Example: `error("n = ", n, " is not squarefree !")`.

Note that, due to the automatic concatenation of strings, you could in fact use only one argument, just by suppressing the commas.

#### extern(str)

the string str is the name of an external command (i.e.one you would type from your UNIX shell prompt). This command is immediately run and its input fed into `gp`, just as if read from a file.

#### getheap()

returns a two-component row vector giving the number of objects on the heap and the amount of memory they occupy in long words. Useful mainly for debugging purposes.

The library syntax is getheap().

#### getrand()

returns the current value of the random number seed. Useful mainly for debugging purposes.

The library syntax is getrand(), returns a C long.

#### getstack()

returns the current value of `top`-`avma`, i.e.the number of bytes used up to now on the stack. Should be equal to 0 in between commands. Useful mainly for debugging purposes.

The library syntax is getstack(), returns a C long.

#### gettime()

returns the time (in milliseconds) elapsed since either the last call to `gettime`, or to the beginning of the containing GP instruction (if inside `gp`), whichever came last.

The library syntax is gettime(), returns a C long.

#### global(list of variables)

declares the corresponding variables to be global. From now on, you will be forbidden to use them as formal parameters for function definitions or as loop indexes. This is especially useful when patching together various scripts, possibly written with different naming conventions. For instance the following situation is dangerous:

    p = 3   \\ fix characteristic
     ...
     forprime(p = 2, N, ...)
     f(p) = ...

since within the loop or within the function's body (even worse: in the subroutines called in that scope), the true global value of `p` will be hidden. If the statement `global(p = 3)` appears at the beginning of the script, then both expressions will trigger syntax errors.

Calling `global` without arguments prints the list of global variables in use. In particular, `eval(global)` will output the values of all global variables.

#### input()

reads a string, interpreted as a GP expression, from the input file, usually standard input (i.e.the keyboard). If a sequence of expressions is given, the result is the result of the last expression of the sequence. When using this instruction, it is useful to prompt for the string by using the `print1` function. Note that in the present version 2.19 of `pari.el`, when using `gp` under GNU Emacs (see Section (??)) one \emph{must} prompt for the string, with a string which ends with the same prompt as any of the previous ones (a `"? "` will do for instance).

#### install(name,code,{gpname},{lib})

loads from dynamic library lib the function name. Assigns to it the name gpname in this `gp` session, with argument code code (see Section (??) for an explanation of those). If lib is omitted, uses `libpari.so`. If gpname is omitted, uses name.

This function is useful for adding custom functions to the `gp` interpreter, or picking useful functions from unrelated libraries. For instance, it makes the function `system` obsolete:

    ? install(system, vs, sys, "libc.so")
     ? sys("ls gp*")
     gp.c            gp.h            gp_rl.c

But it also gives you access to all (non static) functions defined in the PARI library. For instance, the function `GEN addii(GEN x, GEN y)` adds two PARI integers, and is not directly accessible under `gp` (it's eventually called by the `+` operator of course):

    ? install("addii", "GG")
     ? addii(1, 2)
     %1 = 3

Re-installing a function will print a Warning, and update the prototype code if needed, but will reload a symbol from the library, even it the latter has been recompiled.

Caution: This function may not work on all systems, especially when `gp` has been compiled statically. In that case, the first use of an installed function will provoke a Segmentation Fault, i.e.a major internal blunder (this should never happen with a dynamically linked executable). Hence, if you intend to use this function, please check first on some harmless example such as the ones above that it works properly on your machine.

#### kill(s)

kills the present value of the variable, alias or user-defined function s. The corresponding identifier can now be used to name any GP object (variable or function). This is the only way to replace a variable by a function having the same name (or the other way round), as in the following example:

    ? f = 1
     %1 = 1
     ? f(x) = 0
       ***   unused characters: f(x)=0
                                 ^----
     ? kill(f)
     ? f(x) = 0
     ? f()
     %2 = 0

When you kill a variable, all objects that used it become invalid. You can still display them, even though the killed variable will be printed in a funny way (following the same convention as used by the library function `fetch_var`, seeSection (??)). For example:

    ? a^2 + 1
     %1 = a^2 + 1
     ? kill(a)
     ? %1
     %2 = #<1>^2 + 1

If you simply want to restore a variable to its "undefined" value (monomial of degree one), use the quote operator: `a = 'a`. Predefined symbols (`x` and GP function names) cannot be killed.

#### print({str}*)

outputs its (string) arguments in raw format, ending with a newline.

#### print1({str}*)

outputs its (string) arguments in raw format, without ending with a newline (note that you can still embed newlines within your strings, using the `\n` notation!).

#### printp({str}*)

outputs its (string) arguments in prettyprint (beautified) format, ending with a newline.

#### printp1({str}*)

outputs its (string) arguments in prettyprint (beautified) format, without ending with a newline.

#### printtex({str}*)

outputs its (string) arguments in TeX format. This output can then be used in a TeX manuscript. The printing is done on the standard output. If you want to print it to a file you should use `writetex` (see there).

Another possibility is to enable the `log` default (seeSection (??)). You could for instance do:

    default(logfile, "new.tex");
     default(log, 1);
     printtex(result);

(You can use the automatic string expansion/concatenation process to have dynamic file names if you wish).

#### quit()

exits `gp`.

#### read({str})

reads in the file whose name results from the expansion of the string str. If str is omitted, re-reads the last file that was fed into `gp`. The return value is the result of the last expression evaluated. If a GP `binary file` is read using this command (see Section (??)), the file is loaded and the last object in the file is returned.

#### reorder({x = []})

x must be a vector. If x is the empty vector, this gives the vector whose components are the existing variables in increasing order (i.e.in decreasing importance). Killed variables (see `kill`) will be shown as `0`. If x is non-empty, it must be a permutation of variable names, and this permutation gives a new order of importance of the variables, \emph{for output only}. For example, if the existing order is `[x,y,z]`, then after `reorder([z,x])` the order of importance of the variables, with respect to output, will be `[z,y,x]`. The internal representation is unaffected.

#### setrand(n)

reseeds the random number generator to the value n. The initial seed is n = 1.

The library syntax is setrand(n), where n is a `long`. Returns n.

#### system(str)

str is a string representing a system command. This command is executed, its output written to the standard output (this won't get into your logfile), and control returns to the PARI system. This simply calls the C `system` command.

#### trap({e}, {rec}, {seq})

tries to execute seq, trapping error e, that is effectively preventing it from aborting computations in the usual way; the recovery sequence rec is executed if the error occurs and the evaluation of rec becomes the result of the command. If e is omitted, all exceptions are trapped. Note in particular that hitting `^C` (Control-C) raises an exception. See Section (??) for an introduction to error recovery under `gp`.

    ? \\ trap division by 0
     ? inv(x) = trap (gdiver, INFINITY, 1/x)
     ? inv(2)
     %1 = 1/2
     ? inv(0)
     %2 = INFINITY

If seq is omitted, defines rec as a default action when catching exception e, provided no other trap as above intercepts it first. The error message is printed, as well as the result of the evaluation of rec, and control is given back to the `gp` prompt. In particular, current computation is then lost.

The following error handler prints the list of all user variables, then stores in a file their name and their values:

    ? { trap( ,
           print(reorder);
           writebin("crash")) }

If no recovery code is given (rec is omitted) a break loop will be started (see Section (??)). In particular

    ? trap()

by itself installs a default error handler, that will start a break loop whenever an exception is raised.

If rec is the empty string `""` the default handler (for that error if e is present) is disabled.

Note: The interface is currently not adequate for trapping individual exceptions. In the current version 2.1.6, the following keywords are recognized, but the name list will be expanded and changed in the future (all library mode errors can be trapped: it's a matter of defining the keywords to `gp`, and there are currently far too many useless ones):

`accurer`: accuracy problem

`archer`: not available on this architecture or operating system

`errpile`: the PARI stack overflows

`gdiver`: division by 0

`invmoder`: impossible inverse modulo

`siginter`: SIGINT received (usually from Control-C)

`talker`: miscellaneous error

`typeer`: wrong type

`user`: user error (from the `error` function)

#### type(x)

this is useful only under `gp`. Returns the internal type name of the PARI object x as a string. Check out existing type names with the metacommand `\t`. For example `type(1)` will return "`t_INT`".

The library syntax is type0(x), though the macro `typ` is usually simpler to use since it return an integer that can easily be matched with the symbols `t_*`. The name `type` was avoided due to the fact that `type` is a reserved identifier for some C(++) compilers.

#### whatnow(key)

if keyword key is the name of a function that was present in GP version 1.39.15 or lower, outputs the new function name and syntax, if it changed at all (387 out of 560 did).

#### write(filename,{str}*)

writes (appends) to filename the remaining arguments, and appends a newline (same output as `print`).

#### write1(filename,{str}*)

writes (appends) to filename the remaining arguments without a trailing newline (same output as `print1`).

#### writetex(filename,{str}*)

as `write`, in TeX format.