In addition to the general PARI functions, it is necessary to have some
functions which will be of use specifically for gp
, though a few of these
can be accessed under library mode. Before we start describing these, we recall
the difference between strings and keywords (see
Section se:strings): the latter don't get expanded at all, and you can type
them without any enclosing quotes. The former are dynamic objects, where
everything outside quotes gets immediately expanded.
Deprecated alias for strchr.
The library syntax is GEN pari_strchr(GEN x)
.
Deprecated alias for strexpand
The library syntax is GEN strexpand(GEN vecx)
.
Deprecated alias for strprintf.
The library syntax is GEN strprintf(const char *fmt, GEN vecx)
.
Deprecated alias for strtex.
The library syntax is GEN strtex(GEN vecx)
.
Changes the help message for the symbol sym
. The string str
is expanded on the spot and stored as the online help for sym
. It is
recommended to document global variables and user functions in this way,
although gp
will not protest if you don't.
You can attach a help text to an alias, but it will never be
shown: aliases are expanded by the ?
help operator and we get the help
of the symbol the alias points to. Nothing prevents you from modifying the
help of built-in PARI functions. But if you do, we would like to hear why you
needed it!
Without addhelp
, the standard help for user functions consists of its
name and definition.
gp> f(x) = x^2; gp> ?f f = (x)->x^2
Once addhelp is applied to f, the function code is no longer included. It can still be consulted by typing the function name:
gp> addhelp(f, "Square") gp> ?f Square gp> f %2 = (x)->x^2
The library syntax is void addhelp(const char *sym, const char *str)
.
If code is omitted, trigger an e_ALARM exception after s seconds (wall-clock time), cancelling any previously set alarm; stop a pending alarm if s = 0 or is omitted.
Otherwise, if s is positive, the function evaluates code,
aborting after s seconds. The return value is the value of code if
it ran to completion before the alarm timeout, and a t_ERROR
object
otherwise.
? p = nextprime(10^25); q = nextprime(10^26); N = p*q; ? E = alarm(1, factor(N)); ? type(E) %3 = "t_ERROR" ? print(E) %4 = error("alarm interrupt after 964 ms.") ? alarm(10, factor(N)); \\ enough time %5 = [ 10000000000000000000000013 1] [100000000000000000000000067 1]
Here is a more involved example: the function
timefact(N,sec)
below tries to factor N and gives up after sec
seconds, returning a partial factorization.
\\ Time-bounded partial factorization default(factor_add_primes,1); timefact(N,sec)= { F = alarm(sec, factor(N)); if (type(F) == "t_ERROR", factor(N, 2^24), F); }
We either return the factorization directly, or replace the
t_ERROR
result by a simple bounded factorization factor(N, 2^24)
.
Note the factor_add_primes
trick: any prime larger than 224
discovered while attempting the initial factorization is stored and
remembered. When the alarm rings, the subsequent bounded factorization finds
it right away.
Caveat. It is not possible to set a new alarm within
another alarm
code: the new timer erases the parent one.
Caveat2. In a parallel-enabled gp
, if the code
involves parallel subtasks, then alarm
may not return right away: il
will prevent new tasks from being launched but will not interrupt previously
launched secondary threads. This avoids leaving the system in an
inconsistent state.
The library syntax is GEN gp_alarm(long s, GEN code = NULL)
.
Defines the symbol newsym as an alias for the symbol sym:
? alias("det", "matdet"); ? det([1,2;3,4]) %1 = -2
You are not restricted to ordinary functions, as in the above example:
to alias (from/to) member functions, prefix them with `_.
';
to alias operators, use their internal name, obtained by writing
_
in lieu of the operators argument: for instance, _!
and
!_
are the internal names of the factorial and the
logical negation, respectively.
? alias("mod", "_.mod"); ? alias("add", "_+_"); ? alias("_.sin", "sin"); ? mod(Mod(x,x^4+1)) %2 = x^4 + 1 ? add(4,6) %3 = 10 ? Pi.sin %4 = 0.E-37
Alias expansion is performed directly by the internal GP compiler. Note that since alias is performed at compilation-time, it does not require any run-time processing, however it only affects GP code compiled after the alias command is evaluated. A slower but more flexible alternative is to use variables. Compare
? fun = sin; ? g(a,b) = intnum(t=a,b,fun(t)); ? g(0, Pi) %3 = 2.0000000000000000000000000000000000000 ? fun = cos; ? g(0, Pi) %5 = 1.8830410776607851098 E-39
with
? alias(fun, sin); ? g(a,b) = intnum(t=a,b,fun(t)); ? g(0,Pi) %2 = 2.0000000000000000000000000000000000000 ? alias(fun, cos); \\ Oops. Does not affect *previous* definition! ? g(0,Pi) %3 = 2.0000000000000000000000000000000000000 ? g(a,b) = intnum(t=a,b,fun(t)); \\ Redefine, taking new alias into account ? g(0,Pi) %5 = 1.8830410776607851098 E-39
A sample alias file misc/gpalias
is provided with
the standard distribution.
The library syntax is void alias0(const char *newsym, const char *sym)
.
This special operation changes the stack size after initialization. The argument s must be a nonnegative integer. If s > 0, a new stack of at least s bytes is allocated. We may allocate more than s bytes if s is way too small, or for alignment reasons: the current formula is max(16*ceil{s/16}, 500032) bytes.
If s = 0, the size of the new stack is twice the size of the old one.
This command is much more useful if parisizemax
is nonzero, and we
describe this case first. With parisizemax
enabled, there are three
sizes of interest:
* a virtual stack size, parisizemax
, which is an absolute upper
limit for the stack size; this is set by default(parisizemax, ...)
.
* the desired typical stack size, parisize
, that will grow as
needed, up to parisizemax
; this is set by default(parisize, ...)
.
* the current stack size, which is less that parisizemax
,
typically equal to parisize
but possibly larger and increasing
dynamically as needed; allocatemem
allows to change that one
explicitly.
The allocatemem
command forces stack
usage to increase temporarily (up to parisizemax
of course); for
instance if you notice using \gm2
that we seem to collect garbage a
lot, e.g.
? \gm2 debugmem = 2 ? default(parisize,"32M") *** Warning: new stack size = 32000000 (30.518 Mbytes). ? bnfinit('x^2+10^30-1) *** bnfinit: collecting garbage in hnffinal, i = 1. *** bnfinit: collecting garbage in hnffinal, i = 2. *** bnfinit: collecting garbage in hnffinal, i = 3.
and so on for hundred of lines. Then, provided the
breakloop
default is set, you can interrupt the computation, type
allocatemem(100*10^6)
at the break loop prompt, then let the
computation go on by typing <Enter>
. Back at the gp
prompt,
the desired stack size of parisize
is restored. Note that changing either
parisize
or parisizemax
at the break loop prompt would interrupt
the computation, contrary to the above.
In most cases, parisize
will increase automatically (up to
parisizemax
) and there is no need to perform the above maneuvers.
But that the garbage collector is sufficiently efficient that
a given computation can still run without increasing the stack size,
albeit very slowly due to the frequent garbage collections.
Deprecated: when parisizemax
is unset.
This is currently still the default behavior in order not to break backward
compatibility. The rest of this section documents the
behavior of allocatemem
in that (deprecated) situation: it becomes a
synonym for default(parisize,...)
. In that case, there is no
notion of a virtual stack, and the stack size is always equal to
parisize
. If more memory is needed, the PARI stack overflows, aborting
the computation.
Thus, increasing parisize
via allocatemem
or
default(parisize,...)
before a big computation is important.
Unfortunately, either must be typed at the gp
prompt in
interactive usage, or left by itself at the start of batch files.
They cannot be used meaningfully in loop-like constructs, or as part of a
larger expression sequence, e.g
allocatemem(); x = 1; \\ This will not set x
!
In fact, all loops are immediately exited, user functions terminated, and
the rest of the sequence following allocatemem()
is silently
discarded, as well as all pending sequences of instructions. We just go on
reading the next instruction sequence from the file we are in (or from the
user). In particular, we have the following possibly unexpected behavior: in
read("file.gp"); x = 1
were file.gp
contains an allocatemem
statement,
the x = 1
is never executed, since all pending instructions in the
current sequence are discarded.
The reason for these unfortunate side-effects is that, with
parisizemax
disabled, increasing the stack size physically
moves the stack, so temporary objects created during the current expression
evaluation are not correct anymore. (In particular byte-compiled expressions,
which are allocated on the stack.) To avoid accessing obsolete pointers to
the old stack, this routine ends by a longjmp
.
The library syntax is void gp_allocatemem(GEN s = NULL)
.
Apply the t_CLOSURE
f
to the entries of A
.
* If A
is a scalar, return f(A)
.
* If A
is a polynomial or power series ∑ ai xi (+
O(xN)), apply f
on all coefficients and return ∑ f(ai)
xi (+ O(xN)).
* If A
is a vector or list [a1,...,an], return the vector
or list [f(a1),..., f(an)]. If A
is a matrix, return the matrix
whose entries are the f(A[i,j]
).
? apply(x->x^2, [1,2,3,4]) %1 = [1, 4, 9, 16] ? apply(x->x^2, [1,2;3,4]) %2 = [1 4] [9 16] ? apply(x->x^2, 4*x^2 + 3*x+ 2) %3 = 16*x^2 + 9*x + 4 ? apply(sign, 2 - 3* x + 4*x^2 + O(x^3)) %4 = 1 - x + x^2 + O(x^3)
Note that many functions already act componentwise on
vectors or matrices, but they almost never act on lists; in this case,
apply
is a good solution:
? L = List([Mod(1,3), Mod(2,4)]); ? lift(L) *** at top-level: lift(L) *** ^ — — - *** lift: incorrect type in lift. ? apply(lift, L); %2 = List([1, 2])
Remark. For v a t_VEC
, t_COL
, t_VECSMALL
,
t_LIST
or t_MAT
, the alternative set-notations
[g(x) | x <- v, f(x)] [x | x <- v, f(x)] [g(x) | x <- v]
are available as shortcuts for
apply(g, select(f, Vec(v))) select(f, Vec(v)) apply(g, Vec(v))
respectively:
? L = List([Mod(1,3), Mod(2,4)]); ? [ lift(x) | x<-L ] %2 = [1, 2]
The library syntax is genapply(void *E, GEN (*fun)(void*,GEN), GEN a)
.
Return the arity of the closure C, i.e., the number of its arguments.
? f1(x,y=0)=x+y; ? arity(f1) %1 = 2 ? f2(t,s[..])=print(t,":",s); ? arity(f2) %2 = 2
Note that a variadic argument, such as s in f2
above,
is counted as a single argument.
The library syntax is GEN arity0(GEN C)
.
A = [a1,..., an] being a vector and f being a function,
returns the evaluation of f(a1,...,an).
f can also be the name of a built-in GP function.
If # A = 1, call
(f,A) = apply
(f,A)[1].
If f is variadic (has a variable number of arguments), then
the variadic arguments are grouped in a vector in the last component of A.
This function is useful
* when writing a variadic function, to call another one:
fprintf(file,format,args[..]) = write(file, call(strprintf,[format,args]))
* when dealing with function arguments with unspecified arity.
The function below implements a global memoization interface:
memo=Map(); memoize(f,A[..])= { my(res); if(!mapisdefined(memo, [f,A], &res), res = call(f,A); mapput(memo,[f,A],res)); res; }
for example:
? memoize(factor,2^128+1) %3 = [59649589127497217,1;5704689200685129054721,1] ? ## *** last result computed in 76 ms. ? memoize(factor,2^128+1) %4 = [59649589127497217,1;5704689200685129054721,1] ? ## *** last result computed in 0 ms. ? memoize(ffinit,3,3) %5 = Mod(1,3)*x^3+Mod(1,3)*x^2+Mod(1,3)*x+Mod(2,3) ? fibo(n)=if(n==0,0,n==1,1,memoize(fibo,n-2)+memoize(fibo,n-1)); ? fibo(100) %7 = 354224848179261915075
* to call operators through their internal names without using
alias
matnbelts(M) = call("_*_",matsize(M))
The library syntax is GEN call0(GEN f, GEN A)
.
Returns the default corresponding to keyword key. If val is
present, sets the default to val first (which is subject to string
expansion first). Typing default()
(or \d
) yields the complete
default list as well as their current values. See Section se:defaults for an
introduction to GP defaults, Section se:gp_defaults for a
list of available defaults, and Section se:meta for some shortcut
alternatives. Note that the shortcuts are meant for interactive use and
usually display more information than default
.
The library syntax is GEN default0(const char *key = NULL, const char *val = NULL)
.
Returns the type of the error message E
as a string.
? iferr(1 / 0, E, print(errname(E))) e_INV ? ?? e_INV [...] * "e_INV". Tried to invert a noninvertible object x in function s. [...]
The library syntax is GEN errname(GEN E)
.
Outputs its argument list (each of
them interpreted as a string), then interrupts the running gp
program,
returning to the input prompt. For instance
error("n = ", n, " is not squarefree!")
The library syntax is void error0(GEN vec_str)
.
The variadic version void pari_err(e_USER,...)
is usually preferable.
Export the variables x,..., z to the parallel world.
Such variables are visible inside parallel sections in place of global
variables, but cannot be modified inside a parallel section.
export(a)
set the variable a in the parallel world to current value of a.
export(a = z)
set the variable a in the parallel world to z, without
affecting the current value of a.
? fun(x)=x^2+1; ? parvector(10,i,fun(i)) *** mt: please use export(fun). ? export(fun) ? parvector(10,i,fun(i)) %4 = [2,5,10,17,26,37,50,65,82,101]
Declare all current dynamic variables as exported variables. Such variables are visible inside parallel sections in place of global variables.
? fun(x)=x^2+1; ? parvector(10,i,fun(i)) *** mt: please use export(fun). ? exportall() ? parvector(10,i,fun(i)) %4 = [2,5,10,17,26,37,50,65,82,101]
The library syntax is void exportall()
.
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 output fed into gp
, just as if read from a file.
The library syntax is GEN gpextern(const char *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 output is returned as a vector of GP strings, one component per output line.
The library syntax is GEN externstr(const char *str)
.
Close the file descriptor n, created via fileopen
or
fileextern
. Finitely many files can be opened at a given time,
closing them recycles file descriptors and avoids running out of them:
? n = 0; while(n++, fileopen("/tmp/test", "w")) *** at top-level: n=0;while(n++,fileopen("/tmp/test","w")) *** ^ — — — — — — — — -- *** fileopen: error opening requested file: `/tmp/test'. *** Break loop: type 'break' to go back to GP prompt break> n 65533
This is a limitation of the operating system and does not
depend on PARI: if you open too many files in gp
without closing them,
the operating system will also prevent unrelated applications from opening
files. Independently, your operating system (e.g. Windows) may prevent other
applications from accessing or deleting your file while it is opened by
gp
. Quitting gp
implicitly calls this function on all opened
file descriptors.
On files opened for writing, this function also forces a write of all
buffered data to the file system and completes all pending write operations.
This function is implicitly called for all open file descriptors when
exiting gp
but it is cleaner and safer to call it explicitly, for
instance in case of a gp
crash or general system failure, which could
cause data loss.
? n = fileopen("./here"); ? while(l = fileread(n), print(l)); ? fileclose(n); ? n = fileopen("./there", "w"); ? for (i = 1, 100, filewrite(n, i^2+1)) ? fileclose(n)
Until a fileclose
, there is no guarantee that the file on disk
contains all the expected data from previous filewrite
s. (And even
then the operating system may delay the actual write to hardware.)
Closing a file twice raises an exception:
? n = fileopen("/tmp/test"); ? fileclose(n) ? fileclose(n) *** at top-level: fileclose(n) *** ^ — — — — *** fileclose: invalid file descriptor 0
The library syntax is void gp_fileclose(long n)
.
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 the function returns a file descriptor attached to the command output as if it were read from a file.
? n = fileextern("ls -l"); ? while(l = filereadstr(n), print(l)) ? fileclose(n)
If the secure
default is set, this function will raise
en exception.
The library syntax is long gp_fileextern(const char *str)
.
Flushes the file descriptor n, created via fileopen
or
fileextern
. On files opened for writing, this function forces a write
of all buffered data to the file system and completes all pending write
operations. This function is implicitly called by fileclose
but you may
want to call it explicitly at synchronization points, for instance after
writing a large result to file and before printing diagnostics on screen.
(In order to be sure that the file contains the expected content on
inspection.)
If n is omitted, flush all descriptors to output streams.
? n = fileopen("./here", "w"); ? for (i = 1, 10^5, \ filewrite(n, i^2+1); \ if (i % 10000 == 0, fileflush(n)))
Until a fileflush
or fileclose
, there is no guarantee
that the file contains all the expected data from previous filewrite
s.
The library syntax is void gp_fileflush0(GEN n = NULL)
.
But the direct and more specific variant
void gp_fileflush(long n)
is also available.
Open the file pointed to by 'path' and return a file descriptor which can be used with other file functions.
The mode can be
* "r"
(default): open for reading; allow fileread
and
filereadstr
.
* "w"
: open for writing, discarding existing content; allow
filewrite
, filewrite1
.
* "a"
: open for writing, appending to existing content; same
operations allowed as "w"
.
Eventually, the file should be closed and the descriptor recycled using
fileclose
.
? n = fileopen("./here"); \\ "r" by default ? while (l = filereadstr(n), print(l)) \\ print successive lines ? fileclose(n) \\ done
In read mode, raise an exception if the file does not exist or the user does not have read permission. In write mode, raise an exception if the file cannot be written to. Trying to read or write to a file that was not opend with the right mode raises an exception.
? n = fileopen("./read", "r"); ? filewrite(n, "test") \\ not open for writing *** at top-level: filewrite(n,"test") *** ^ — — — — — — - *** filewrite: invalid file descriptor 0
The library syntax is long gp_fileopen(const char *path, const char *mode)
.
Read a logical line from the file attached to the descriptor n, opened
for reading with fileopen
. Return 0 at end of file.
A logical line is a full command as it is prepared by gp's
preprocessor (skipping blanks and comments or assembling multiline commands
between braces) before being fed to the interpreter. The function
filereadstr
would read a raw line exactly as input, up to the
next carriage return \n
.
Compare raw lines
? n = fileopen("examples/bench.gp"); ? while(l = filereadstr(n), print(l)); { u=v=p=q=1; for (k=1, 2000, [u,v] = [v,u+v]; p *= v; q = lcm(q,v); if (k%50 == 0, print(k, " ", log(p)/log(q)) ) ) }
and logical lines
? n = fileopen("examples/bench.gp"); ? while(l = fileread(n), print(l)); u=v=p=q=1;for(k=1,2000,[u,v]=[v,u+v];p*=v;q=lcm(q,v);[...]
The library syntax is GEN gp_fileread(long n)
.
Read a raw line from the file attached to the descriptor n, opened
for reading with fileopen
, discarding the terminating newline.
In other words the line is read exactly as input, up to the
next carriage return \n
. By comparison, fileread
would
read a logical line, as assembled by gp's preprocessor (skipping blanks
and comments for instance).
The library syntax is GEN gp_filereadstr(long n)
.
Write the string s to the file attached to descriptor n, ending with
a newline. The file must have been opened with fileopen
in
"w"
or "a"
mode. There is no guarantee that s is completely
written to disk until fileclose(n)
is executed, which is automatic
when quitting gp
.
If the newline is not desired, use filewrite1
.
Variant. The high-level function write
is expensive when many
consecutive writes are expected because it cannot use buffering. The low-level
interface fileopen
/ filewrite
/ fileclose
is more efficient:
? f = "/tmp/bigfile"; ? for (i = 1, 10^5, write(f, i^2+1)) time = 240 ms. ? v = vector(10^5, i, i^2+1); time = 10 ms. \\ computing the values is fast ? write("/tmp/bigfile2",v) time = 12 ms. \\ writing them in one operation is fast ? n = fileopen("/tmp/bigfile", "w"); ? for (i = 1, 10^5, filewrite(n, i^2+1)) time = 24 ms. \\ low-level write is ten times faster ? fileclose(n);
In the final example, the file needs not be in a consistent
state until the ending fileclose
is evaluated, e.g. some lines might be
half-written or not present at all even though the corresponding
filewrite
was executed already. Both a single high-level write
and a succession of low-level filewrite
s achieve the same efficiency,
but the latter is often more natural. In fact, concatenating naively
the entries to be written is quadratic in the number of entries, hence
much more expensive than the original write operations:
? v = []; for (i = 1, 10^5, v = concat(v,i)) time = 1min, 41,456 ms.
The library syntax is void gp_filewrite(long n, const char *s)
.
Write the string s to the file attached to descriptor n.
The file must have been opened with fileopen
in "w"
or "a"
mode.
If you want to append a newline at the end of s, you can use
Str(s,"\n")
or filewrite
.
The library syntax is void gp_filewrite1(long n, const char *s)
.
Apply the t_CLOSURE
f
of arity 2 to the entries of A
,
in order to return f(...f(f(A[1],A[2]),A[3])...,A[#A])
.
? fold((x,y)->x*y, [1,2,3,4]) %1 = 24 ? fold((x,y)->[x,y], [1,2,3,4]) %2 = [[[1, 2], 3], 4] ? fold((x,f)->f(x), [2,sqr,sqr,sqr]) %3 = 256 ? fold((x,y)->(x+y)/(1-x*y),[1..5]) %4 = -9/19 ? bestappr(tan(sum(i=1,5,atan(i)))) %5 = -9/19
The library syntax is GEN fold0(GEN f, GEN A)
.
Also available is
GEN genfold(void *E, GEN (*fun)(void*,GEN, GEN), GEN A)
.
Returns the CPU time (in milliseconds) elapsed since gp
startup.
This provides a reentrant version of gettime
:
my (t = getabstime()); ... print("Time: ", strtime(getabstime() - t));
For a version giving wall-clock time, see getwalltime
.
The library syntax is long getabstime()
.
Returns information about various auto-growing caches. For each resource, we report its name, its size, the number of cache misses (since the last extension), the largest cache miss and the size of the cache in bytes.
The caches are initially empty, then set automatically to a small inexpensive default value, then grow on demand up to some maximal value. Their size never decreases, they are only freed on exit.
The current caches are
* Hurwitz class numbers H(D) for |D| ≤ N, computed in time O(N3/2) using O(N) space.
* Factorizations of small integers up to N, computed in time O(N1+ϵ) using O(Nlog N) space.
* Divisors of small integers up to N, computed in time O(N1+ϵ) using O(Nlog N) space.
* Coredisc's of negative integers down to -N, computed in time O(N1+ϵ) using O(N) space.
* Primitive dihedral forms of weight 1 and level up to N, computed in time O(N2+ϵ) and space O(N2).
? getcache() \\ on startup, all caches are empty %1 = [ "Factors" 0 0 0 0] [ "Divisors" 0 0 0 0] [ "H" 0 0 0 0] ["CorediscF" 0 0 0 0] [ "Dihedral" 0 0 0 0] ? mfdim([500,1,0],0); \\ nontrivial computation time = 540 ms. ? getcache() %3 = [ "Factors" 50000 0 0 4479272] ["Divisors" 50000 1 100000 5189808] [ "H" 50000 0 0 400008] ["Dihedral" 1000 0 0 2278208]
The library syntax is GEN getcache()
.
Return the value of the environment variable s
if it is defined, otherwise return 0.
The library syntax is GEN gp_getenv(const char *s)
.
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 GEN getheap()
.
Returns the current dynamic bit precision.
Returns the current dynamic precision, in decimal digits.
Returns the current value of the seed used by the
pseudo-random number generator random
. Useful mainly for debugging
purposes, to reproduce a specific chain of computations. The returned value
is technical (reproduces an internal state array), and can only be used as an
argument to setrand
.
The library syntax is GEN getrand()
.
Returns the current value of top
-avma
, i.e. the number of
bytes used up to now on the stack. Useful mainly for debugging purposes.
The library syntax is long getstack()
.
Returns the CPU time (in milliseconds) used since either the last call to
gettime
, or to the beginning of the containing GP instruction (if
inside gp
), whichever came last.
For a reentrant version, see getabstime
.
For a version giving wall-clock time, see getwalltime
.
The library syntax is long gettime()
.
Returns the time (in milliseconds) elapsed since 00:00:00 UTC Thursday 1, January 1970 (the Unix epoch).
my (t = getwalltime()); ... print("Time: ", strtime(getwalltime() - t));
The library syntax is GEN getwalltime()
.
Obsolete. Scheduled for deletion.
Declare x,..., z as inline variables. Such variables
behave like lexically scoped variable (see my()) but with unlimited scope.
It is however possible to exit the scope by using uninline()
.
When used in a GP script, it is recommended to call uninline()
before
the script's end to avoid inline variables leaking outside the script.
DEPRECATED, use export
.
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 se:emacs) one 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).
The library syntax is GEN gp_input()
.
Loads from dynamic library lib the function name. Assigns to it
the name gpname in this gp
session, with prototype
code (see below). If gpname is omitted, uses name.
If lib is omitted, all symbols known to gp
are available: this
includes the whole of libpari.so
and possibly others (such as
libc.so
).
Most importantly, install
gives you access to all nonstatic 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 is eventually called by the +
operator of course):
? install("addii", "GG") ? addii(1, 2) %1 = 3
It also allows to add external functions to the gp
interpreter.
For instance, it makes the function system
obsolete:
? install(system, vs, sys,/*omitted*/) ? sys("ls gp*") gp.c gp.h gp_rl.c
This works because system
is part of libc.so
,
which is linked to gp
. It is also possible to compile a shared library
yourself and provide it to gp in this way: use gp2c
, or do it manually
(see the modules_build
variable in pari.cfg
for hints).
Re-installing a function will print a warning and update the prototype code if needed. However, it will not reload a symbol from the library, even if the latter has been recompiled.
Prototype. We only give a simplified description here, covering
most functions, but there are many more possibilities. The full documentation
is available in libpari.dvi
, see
??prototype
* First character i
, l
, u
, v
: return type
int
/ long
/ ulong
/ void
. (Default: GEN
)
* One letter for each mandatory argument, in the same order as they appear
in the argument list: G
(GEN
), &
(GEN*
), L
(long
), U
(ulong
),
s
(char *
), n
(variable).
* p
to supply realprecision
(usually long prec
in the
argument list), b
to supply realbitprecision
(usually long bitprec
), P
to supply seriesprecision
(usually long precdl
).
We also have special constructs for optional arguments and default values:
* DG
(optional GEN
, NULL
if omitted),
* D&
(optional GEN*
, NULL
if omitted),
* Dn
(optional variable, -1 if omitted),
For instance the prototype corresponding to
long issquareall(GEN x, GEN *n = NULL)
is lGD&
.
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 (this should never
happen with a dynamically linked executable). If you intend to use this
function, please check first on some harmless example such as the one above
that it works properly on your machine.
The library syntax is void gpinstall(const char *name, const char *code, const char *gpname, const char *lib)
.
Restores the symbol sym
to its "undefined" status, and deletes any
help messages attached to sym
using addhelp
. Variable names
remain known to the interpreter and keep their former priority: you cannot
make a variable "less important" by killing it!
? z = y = 1; y %1 = 1 ? kill(y) ? y \\ restored to ``undefined'' status %2 = y ? variable() %3 = [x, y, z] \\ but the variable name y is still known, with y > z !
For the same reason, killing a user function (which is an ordinary
variable holding a t_CLOSURE
) does not remove its name from the list of
variable names.
If the symbol is attached to a variable — user functions being an
important special case — , one may use the quote operator
a = 'a
to reset variables to their starting values. However, this
will not delete a help message attached to a
, and is also slightly
slower than kill(a)
.
? x = 1; addhelp(x, "foo"); x %1 = 1 ? x = 'x; x \\ same as 'kill', except we don't delete help. %2 = x ? ?x foo
On the other hand, kill
is the only way to remove aliases and installed
functions.
? alias(fun, sin); ? kill(fun); ? install(addii, GG); ? kill(addii);
The library syntax is void kill0(const char *sym)
.
This function is obsolete, use List
.
Creates an empty list. This routine used to have a mandatory argument, which is now ignored (for backward compatibility).
Inserts the object x at
position n in L (which must be of type t_LIST
).
This has complexity O(#L - n + 1): all the
remaining elements of list (from position n+1 onwards) are shifted
to the right. If n is greater than the list length, appends x.
? L = List([1,2,3]); ? listput(~L, 4); L \\ listput inserts at end %4 = List([1, 2, 3, 4]) ? listinsert(~L, 5, 1); L \ ∈ sert at position 1 %5 = List([5, 1, 2, 3, 4]) ? listinsert(~L, 6, 1000); L \\ trying to insert beyond position #L %6 = List([5, 1, 2, 3, 4, 6]) \\ ... inserts at the end
Note the ~ L
: this means that the function is
called with a reference to L
and changes L
in place.
The library syntax is GEN listinsert0(GEN L, GEN x, long n)
.
Obsolete, retained for backward compatibility. Just use L = List()
instead of listkill(L)
. In most cases, you won't even need that, e.g.
local variables are automatically cleared when a user function returns.
The library syntax is void listkill(GEN L)
.
Removes the n-th element of the list
list (which must be of type t_LIST
). If n is omitted,
or greater than the list current length, removes the last element.
If the list is already empty, do nothing. This runs in time O(#L - n + 1).
? L = List([1,2,3,4]); ? listpop(~L); L \\ remove last entry %2 = List([1, 2, 3]) ? listpop(~L, 1); L \\ remove first entry %3 = List([2, 3])
Note the ~ L
: this means that the function is
called with a reference to L
and changes L
in place.
The library syntax is void listpop0(GEN list, long n)
.
Sets the n-th element of the list
list (which must be of type t_LIST
) equal to x. If n is omitted,
or greater than the list length, appends x.
? L = List(); ? listput(~L, 1) ? listput(~L, 2) ? L %4 = List([1, 2])
Note the ~ L
: this means that the function is
called with a reference to L
and changes L
in place.
You may put an element into an occupied cell (not changing the
list length), but it is easier to use the standard list[n] = x
construct.
? listput(~L, 3, 1) \\ insert at position 1 ? L %6 = List([3, 2]) ? L[2] = 4 \\ simpler %7 = List([3, 4]) ? L[10] = 1 \\ can't insert beyond the end of the list *** at top-level: L[10]=1 *** ^ — — *** nonexistent component: index > 2 ? listput(L, 1, 10) \\ but listput can ? L %9 = List([3, 2, 1])
This function runs in time O(#L) in the worst case (when the list must
be reallocated), but in time O(1) on average: any number of successive
listput
s run in time O(#L), where #L denotes the list
final length.
The library syntax is GEN listput0(GEN list, GEN x, long n)
.
Sorts the t_LIST
list in place, with respect to the (somewhat
arbitrary) universal comparison function cmp
. In particular, the
ordering is the same as for sets and setsearch
can be used on a sorted
list. No value is returned. If flag is nonzero, suppresses all repeated
coefficients.
? L = List([1,2,4,1,3,-1]); listsort(~L); L %1 = List([-1, 1, 1, 2, 3, 4]) ? setsearch(L, 4) %2 = 6 ? setsearch(L, -2) %3 = 0 ? listsort(~L, 1); L \\ remove duplicates %4 = List([-1, 1, 2, 3, 4])
Note the ~ L
: this means that the function is
called with a reference to L
and changes L
in place:
this is faster than the vecsort
command since the list
is sorted in place and we avoid unnecessary copies.
? v = vector(100,i,random); L = List(v); ? for(i=1,10^4, vecsort(v)) time = 162 ms. ? for(i=1,10^4, vecsort(L)) time = 162 ms. ? for(i=1,10^4, listsort(~L)) time = 63 ms.
The library syntax is void listsort(GEN L, long flag)
.
Set the real precision to p bits in the dynamic scope.
All computations are performed as if realbitprecision
was p:
transcendental constants (e.g. Pi
) and
conversions from exact to floating point inexact data use p bits, as well as
iterative routines implicitly using a floating point
accuracy as a termination criterion (e.g. solve
or intnum
).
But realbitprecision
itself is unaffected
and is "unmasked" when we exit the dynamic (not lexical) scope.
In effect, this is similar to
my(bit = default(realbitprecision)); default(realbitprecision,p); ... default(realbitprecision, bit);
but is both less cumbersome, cleaner (no need to manipulate
a global variable, which in fact never changes and is only temporarily masked)
and more robust: if the above computation is interrupted or an exception
occurs, realbitprecision
will not be restored as intended.
Such localbitprec
statements can be nested, the innermost one taking
precedence as expected. Beware that localbitprec
follows the semantic of
local
, not my
: a subroutine called from localbitprec
scope
uses the local accuracy:
? f()=bitprecision(1.0); ? f() %2 = 128 ? localbitprec(1000); f() %3 = 1024
Note that the bit precision of data (1.0
in the
above example) increases by steps of 64 (32 on a 32-bit machine) so we get
1024 instead of the expected 1000; localbitprec
bounds the
relative error exactly as specified in functions that support that
granularity (e.g. lfun
), and rounded to the next multiple of 64
(resp. 32) everywhere else.
Warning. Changing realbitprecision
or realprecision
in programs is deprecated in favor of localbitprec
and
localprec
. Think about the realprecision
and
realbitprecision
defaults as interactive commands for the gp
interpreter, best left out of GP programs. Indeed, the above rules imply that
mixing both constructs yields surprising results:
? \p38 ? localprec(19); default(realprecision,1000); Pi %1 = 3.141592653589793239 ? \p realprecision = 1001 significant digits (1000 digits displayed)
Indeed, realprecision
itself is ignored within
localprec
scope, so Pi
is computed to a low accuracy. And when
we leave the localprec
scope, realprecision
only regains precedence,
it is not "restored" to the original value.
Set the real precision to p in the dynamic scope and return p.
All computations are performed as if realprecision
was p:
transcendental constants (e.g. Pi
) and
conversions from exact to floating point inexact data use p decimal
digits, as well as iterative routines implicitly using a floating point
accuracy as a termination criterion (e.g. solve
or intnum
).
But realprecision
itself is unaffected
and is "unmasked" when we exit the dynamic (not lexical) scope.
In effect, this is similar to
my(prec = default(realprecision)); default(realprecision,p); ... default(realprecision, prec);
but is both less cumbersome, cleaner (no need to manipulate
a global variable, which in fact never changes and is only temporarily masked)
and more robust: if the above computation is interrupted or an exception
occurs, realprecision
will not be restored as intended.
Such localprec
statements can be nested, the innermost one taking
precedence as expected. Beware that localprec
follows the semantic of
local
, not my
: a subroutine called from localprec
scope
uses the local accuracy:
? f()=precision(1.); ? f() %2 = 38 ? localprec(19); f() %3 = 19
Warning. Changing realprecision
itself in programs is
now deprecated in favor of localprec
. Think about the
realprecision
default as an interactive command for the gp
interpreter, best left out of GP programs. Indeed, the above rules
imply that mixing both constructs yields surprising results:
? \p38 ? localprec(19); default(realprecision,100); Pi %1 = 3.141592653589793239 ? \p realprecision = 115 significant digits (100 digits displayed)
Indeed, realprecision
itself is ignored within
localprec
scope, so Pi
is computed to a low accuracy. And when
we leave localprec
scope, realprecision
only regains precedence,
it is not "restored" to the original value.
Applies the closure f to the image y of x by the map M
and returns the evaluation f(y). The closure f is allowed to
modify the components of y in place. If M is not defined at x, and
the optional argument u
(for undefined) is present and is
a closure of arity 0, return the evaluation u().
To apply f to all entries (values) of M, use apply
(f, M)
instead. There are two main use-cases:
* performing a computation on a value directly, without using
mapget
, avoiding a copy:
? M = Map(); mapput(~M, "a", mathilbert(2000)); ? matsize(mapget(M, "a")) \\ Slow because mapget(M, "a") copies the value %2 = [2000, 2000] time = 101 ms. ? mapapply(~M, "a", matsize) \\ Fast time = 0 ms. %3 = [2000, 2000]
* modifying a value in place, for example to append an element to a value
in a map of lists. This requires to use ~
in the function
declaration. In the following maplistput
, M is a map of lists and we
append v to the list mapget(M,k)
, except this is done in place !
When the map is undefined at k, we use the u(ndefined) argument
()- > List(v)
to convert v to a list then insert it in the map:
? maplistput(~M, k, v) = mapapply(~M, k, (~y)->listput(~y,v), ()->List(v)); ? M = Map(); %2 = Map([;]) ? maplistput(~M, "a", 1); M %3 = Map(["a", List([1])]) ? maplistput(~M, "a", 2); M %4 = Map(["a", List([1, 2])]) ? maplistput(~M, "b", 3); M %5 = Map(["a", List([1, 2]); "b", List([3])]) ? maplistput(~M, "a", 4); M %6 = Map(["a", List([1, 2, 4]); "b", List([])])
The library syntax is GEN mapapply(GEN M, GEN x, GEN f, GEN u = NULL)
.
Removes x from the domain of the map M.
? M = Map(["a",1; "b",3; "c",7]); ? mapdelete(M,"b"); ? Mat(M) ["a" 1] ["c" 7]
The library syntax is void mapdelete(GEN M, GEN x)
.
Returns the image of x by the map M.
? M=Map(["a",23;"b",43]); ? mapget(M,"a") %2 = 23 ? mapget(M,"b") %3 = 43
Raises an exception when the key x is not present in M.
? mapget(M,"c") *** at top-level: mapget(M,"c") *** ^ — — — — - *** mapget: nonexistent component in mapget: index not in map
The library syntax is GEN mapget(GEN M, GEN x)
.
Returns true (1) if x has an image by the map M, false (0) otherwise. If z is present, set z to the image of x, if it exists.
? M1 = Map([1, 10; 2, 20]); ? mapisdefined(M1,3) %1 = 0 ? mapisdefined(M1, 1, &z) %2 = 1 ? z %3 = 10
? M2 = Map(); N = 19; ? for (a=0, N-1, mapput(M2, a^3%N, a)); ? {for (a=0, N-1, if (mapisdefined(M2, a, &b), printf("%d is the cube of %d mod %d\n",a,b,N)));} 0 is the cube of 0 mod 19 1 is the cube of 11 mod 19 7 is the cube of 9 mod 19 8 is the cube of 14 mod 19 11 is the cube of 17 mod 19 12 is the cube of 15 mod 19 18 is the cube of 18 mod 19
The library syntax is GEN mapisdefined(GEN M, GEN x, GEN *z = NULL)
.
Associates x to y in the map M. The value y can be retrieved
with mapget
.
? M = Map(); ? mapput(~M, "foo", 23); ? mapput(~M, 7718, "bill"); ? mapget(M, "foo") %4 = 23 ? mapget(M, 7718) %5 = "bill" ? Vec(M) \\ keys %6 = [7718, "foo"] ? Mat(M) %7 = [ 7718 "bill"] ["foo" 23]
The library syntax is void mapput(GEN M, GEN x, GEN y)
.
Outputs its arguments in raw format ending with a newline. The arguments are converted to strings following the rules in Section se:strings.
? m = matid(2); ? print(m) \\ raw format [1, 0; 0, 1] ? printp(m) \\ prettymatrix format [1 0] [0 1]
The library syntax is void print(GEN vec_str)
.
Outputs its arguments in raw
format, without ending with a newline. Note that you can still embed newlines
within your strings, using the \n
notation !
The arguments are converted to strings following the rules in
Section se:strings.
The library syntax is void print1(GEN vec_str)
.
This function is based on the C library command of the same name. It prints its arguments according to the format fmt, which specifies how subsequent arguments are converted for output. The format is a character string composed of zero or more directives:
* ordinary characters (not %
), printed unchanged,
* conversions specifications (%
followed by some characters)
which fetch one argument from the list and prints it according to the
specification.
More precisely, a conversion specification consists in a %
, one or more
optional flags (among #
, 0
, -
, +
, ` '), an optional
decimal digit string specifying a minimal field width, an optional precision
in the form of a period (`.
') followed by a decimal digit string, and
the conversion specifier (among d
,i
, o
, u
,
x
,X
, p
, e
,E
, f
, g
,G
, s
).
The flag characters. The character %
is followed by zero or
more of the following flags:
* #
: the value is converted to an "alternate form". For
o
conversion (octal), a 0
is prefixed to the string. For x
and X
conversions (hexa), respectively 0x
and 0X
are
prepended. For other conversions, the flag is ignored.
* 0
: the value should be zero padded. For
d
,
i
,
o
,
u
,
x
,
X
e
,
E
,
f
,
F
,
g
, and
G
conversions, the value is padded on the left with zeros rather than
blanks. (If the 0
and -
flags both appear, the 0
flag is
ignored.)
* -
: the value is left adjusted on the field boundary. (The
default is right justification.) The value is padded on the right with
blanks, rather than on the left with blanks or zeros. A -
overrides a
0
if both are given.
* ` '
(a space): a blank is left before a positive number
produced by a signed conversion.
* +
: a sign (+ or -) is placed before a number produced by a
signed conversion. A +
overrides a space if both are used.
The field width. An optional decimal digit string (whose first
digit is nonzero) specifying a minimum field width. If the value has
fewer characters than the field width, it is padded with spaces on the left
(or right, if the left-adjustment flag has been given). In no case does a
small field width cause truncation of a field; if the value is wider than
the field width, the field is expanded to contain the conversion result.
Instead of a decimal digit string, one may write *
to specify that the
field width is given in the next argument.
The precision. An optional precision in the form of a period
(`.
') followed by a decimal digit string. This gives
the number of digits to appear after the radix character for e
,
E
, f
, and F
conversions, the maximum number of significant
digits for g
and G
conversions, and the maximum number of
characters to be printed from an s
conversion.
Instead of a decimal digit string, one may write *
to specify that the
field width is given in the next argument.
The length modifier. This is ignored under gp
, but
necessary for libpari
programming. Description given here for
completeness:
* l
: argument is a long
integer.
* P
: argument is a GEN
.
The conversion specifier. A character that specifies the type of conversion to be applied.
* d
, i
: a signed integer.
* o
, u
, x
, X
: an unsigned integer, converted
to unsigned octal (o
), decimal (u
) or hexadecimal (x
or
X
) notation. The letters abcdef
are used for x
conversions; the letters ABCDEF
are used for X
conversions.
* e
, E
: the (real) argument is converted in the style
[ -]d.ddd e[ -]dd
, where there is one digit before the decimal point,
and the number of digits after it is equal to the precision; if the
precision is missing, use the current realprecision
for the total
number of printed digits. If the precision is explicitly 0, no decimal-point
character appears. An E
conversion uses the letter E
rather
than e
to introduce the exponent.
* f
, F
: the (real) argument is converted in the style
[ -]ddd.ddd
, where the number of digits after the decimal point
is equal to the precision; if the precision is missing, use the current
realprecision
for the total number of printed digits. If the precision
is explicitly 0, no decimal-point character appears. If a decimal point
appears, at least one digit appears before it.
* g
, G
: the (real) argument is converted in style
e
or f
(or E
or F
for G
conversions)
[ -]ddd.ddd
, where the total number of digits printed
is equal to the precision; if the precision is missing, use the current
realprecision
. If the precision is explicitly 0, it is treated as 1.
Style e
is used when
the decimal exponent is < -4, to print 0.
, or when the integer
part cannot be decided given the known significant digits, and the f
format otherwise.
* c
: the integer argument is converted to an unsigned char, and the
resulting character is written.
* s
: convert to a character string. If a precision is given, no
more than the specified number of characters are written.
* p
: print the address of the argument in hexadecimal (as if by
%#x
).
* %
: a %
is written. No argument is converted. The complete
conversion specification is %%
.
Examples:
? printf("floor: %d, field width 3: %3d, with sign: %+3d\n", Pi, 1, 2); floor: 3, field width 3: 1, with sign: +2 ? printf("%.5g %.5g %.5g\n",123,123/456,123456789); 123.00 0.26974 1.2346 e8 ? printf("%-2.5s:%2.5s:%2.5s\n", "P", "PARI", "PARIGP"); P :PARI:PARIG \\ min field width and precision given by arguments ? x = 23; y=-1/x; printf("x=%+06.2f y=%+0*.*f\n", x, 6, 2, y); x=+23.00 y=-00.04 \\ minimum fields width 5, pad left with zeroes ? for (i = 2, 5, printf("%05d\n", 10^i)) 00100 01000 10000 100000 \\ don't truncate fields whose length is larger than the minimum width ? printf("%.2f |%06.2f|", Pi,Pi) 3.14 | 3.14|
All numerical conversions apply recursively to the entries of complex numbers, vectors and matrices:
? printf("%4d", [1,2,3]); [ 1, 2, 3] ? printf("%5.2f", mathilbert(3)); [ 1.00 0.50 0.33] [ 0.50 0.33 0.25] [ 0.33 0.25 0.20] ? printf("%.3g", Pi+I) 3.14+1.00I
Technical note. Our implementation of printf
deviates from the C89 and C99 standards in a few places:
* whenever a precision is missing, the current realprecision
is
used to determine the number of printed digits (C89: use 6 decimals after
the radix character).
* in conversion style e
, we do not impose that the
exponent has at least two digits; we never write a +
sign in the
exponent; 0 is printed in a special way, always as 0.Eexp
.
* in conversion style f
, we switch to style e
if the
exponent is greater or equal to the precision.
* in conversion g
and G
, we do not remove trailing zeros
from the fractional part of the result; nor a trailing decimal point;
0 is printed in a special way, always as 0.Eexp
.
The library syntax is void printf0(const char *fmt, GEN vecx)
.
The variadic version void pari_printf(const char *fmt, ...)
is usually preferable.
Outputs its arguments in prettymatrix format, ending with a newline. The arguments are converted to strings following the rules in Section se:strings.
? m = matid(2); ? print(m) \\ raw format [1, 0; 0, 1] ? printp(m) \\ prettymatrix format [1 0] [0 1]
The library syntax is void printp(GEN vec_str)
.
Outputs its arguments in raw format, ending with a newline. The arguments are converted to strings following the rules in Section se:strings. Successive entries are separated by sep:
? printsep(":", 1,2,3,4) 1:2:3:4
The library syntax is void printsep(const char *sep, GEN vec_str)
.
Outputs its arguments in raw format, without ending with a newline. The arguments are converted to strings following the rules in Section se:strings. Successive entries are separated by sep:
? printsep1(":", 1,2,3,4);print("|") 1:2:3:4|
The library syntax is void printsep1(const char *sep, GEN vec_str)
.
Outputs its arguments in TeX format. This output can then be
used in a TeX manuscript, see strtex
for details. The arguments are
converted to strings following the rules in Section se:strings. 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
(see Section se:defaults).
You could for instance do:
default(logfile, "new.tex"); default(log, 1); printtex(result);
The library syntax is void printtex(GEN vec_str)
.
Exits gp
and return to the system with exit status
status
, a small integer. A nonzero exit status normally indicates
abnormal termination. (Note: the system actually sees only
status
mod 256, see your man pages for exit(3)
or wait(2)
).
Reads in the file
filename (subject to string expansion). If filename 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 se:writebin), the file is loaded and the last object in the file
is returned.
In case the file you read in contains an allocatemem
statement (to be
generally avoided), you should leave read
instructions by themselves,
and not part of larger instruction sequences.
Variants. readvec
allows to read a whole file at once;
fileopen
followed by either fileread
(evaluated lines) or
filereadstr
(lines as nonevaluated strings) allows to read a file
one line at a time.
The library syntax is GEN gp_read_file(const char *filename)
.
Reads in the file filename and return a vector of GP strings,
each component containing one line from the file. If filename is
omitted, re-reads the last file that was fed into gp
.
The library syntax is GEN readstr(const char *filename)
.
Reads in the file
filename (subject to string expansion). If filename is
omitted, re-reads the last file that was fed into gp
. The return
value is a vector whose components are the evaluation of all sequences
of instructions contained in the file. For instance, if file contains
1 2 3
then we will get:
? \r a %1 = 1 %2 = 2 %3 = 3 ? read(a) %4 = 3 ? readvec(a) %5 = [1, 2, 3]
In general a sequence is just a single line, but as usual braces and
\
may be used to enter multiline sequences.
The library syntax is GEN gp_readvec_file(const char *filename)
.
The underlying library function
GEN gp_readvec_stream(FILE *f)
is usually more flexible.
We first describe the default behavior, when flag is 0 or omitted.
Given a vector or list A
and a t_CLOSURE
f
, select
returns the elements x of A
such that f(x) is nonzero. In other
words, f
is seen as a selection function returning a boolean value.
? select(x->isprime(x), vector(50,i,i^2+1)) %1 = [2, 5, 17, 37, 101, 197, 257, 401, 577, 677, 1297, 1601] ? select(x->(x<100), %) %2 = [2, 5, 17, 37]
returns the primes of the form i2+1 for some i ≤ 50,
then the elements less than 100 in the preceding result. The select
function also applies to a matrix A
, seen as a vector of columns, i.e. it
selects columns instead of entries, and returns the matrix whose columns are
the selected ones.
Remark. For v a t_VEC
, t_COL
, t_VECSMALL
,
t_LIST
or t_MAT
, the alternative set-notations
[g(x) | x <- v, f(x)] [x | x <- v, f(x)] [g(x) | x <- v]
are available as shortcuts for
apply(g, select(f, Vec(v))) select(f, Vec(v)) apply(g, Vec(v))
respectively:
? [ x | x <- vector(50,i,i^2+1), isprime(x) ] %1 = [2, 5, 17, 37, 101, 197, 257, 401, 577, 677, 1297, 1601]
If flag = 1, this function returns instead the indices of the selected elements, and not the elements themselves (indirect selection):
? V = vector(50,i,i^2+1); ? select(x->isprime(x), V, 1) %2 = Vecsmall([1, 2, 4, 6, 10, 14, 16, 20, 24, 26, 36, 40]) ? vecextract(V, %) %3 = [2, 5, 17, 37, 101, 197, 257, 401, 577, 677, 1297, 1601]
The following function lists the elements in (ℤ/Nℤ)*:
? invertibles(N) = select(x->gcd(x,N) == 1, [1..N])
Finally
? select(x->x, M)
selects the nonzero entries in M
. If the latter is a
t_MAT
, we extract the matrix of nonzero columns. Note that removing
entries instead of selecting them just involves replacing the selection
function f
with its negation:
? select(x->!isprime(x), vector(50,i,i^2+1))
The library syntax is genselect(void *E, long (*fun)(void*,GEN), GEN a)
. Also available
is GEN genindexselect(void *E, long (*fun)(void*, GEN), GEN a)
,
corresponding to flag = 1.
Return the calling function or closure as a t_CLOSURE
object.
This is useful for defining anonymous recursive functions.
? (n -> if(n==0,1,n*self()(n-1)))(5) %1 = 120 \\ 5! ? (n -> if(n<=1, n, self()(n-1)+self()(n-2)))(20) %2 = 6765 \\ Fibonacci(20)
The library syntax is GEN pari_self()
.
Reseeds the random number generator using the seed n. No value is
returned. The seed is a small positive integer 0 < n < 264 used to
generate deterministically a suitable state array. All gp session start
by an implicit setrand(1)
, so resetting the seed to this value allows
to replay all computations since the session start. Alternatively,
running a randomized computation starting by setrand
(n)
twice with the same n will generate the exact same output.
In the other direction, including a call to setrand(getwalltime())
from your gprc will cause GP to produce different streams of random numbers
in each session. (Unix users may want to use /dev/urandom
instead
of getwalltime
.)
For debugging purposes, one can also record a particular random state
using getrand
(the value is encoded as a huge integer) and feed it to
setrand
:
? state = getrand(); \\ record seed ... ? setrand(state); \\ we can now replay the exact same computations
The library syntax is void setrand(GEN n)
.
Converts integer or vector of integers x to a string, translating each integer (in the range [1,255]) into a character using ASCII encoding.
? strchr(97) %1 = "a" ? Vecsmall("hello world") %2 = Vecsmall([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]) ? strchr(%) %3 = "hello world"
The library syntax is GEN pari_strchr(GEN x)
.
Converts its argument list into a
single character string (type t_STR
, the empty string if x is omitted).
Then perform environment expansion, see Section se:envir.
This feature can be used to read environment variable values.
? strexpand("$HOME/doc") %1 = "/home/pari/doc" ? module = "aprcl"; n = 10; ? strexpand("$HOME/doc/", module, n, ".tex") %3 = "/home/pari/doc/aprcl10.tex"
The individual arguments are read in string context, see Section se:strings.
The library syntax is GEN strexpand(GEN vecx)
.
Joins the strings in vector v, separating them with delimiter p.
The reverse operation is strsplit
.
? v = ["abc", "def", "ghi"] ? strjoin(v, "/") %2 = "abc/def/ghi" ? strjoin(v) %3 = "abcdefghi"
The library syntax is GEN strjoin(GEN v, GEN p = NULL)
.
Returns a string built from the remaining arguments according to the
format fmt. The format consists of ordinary characters (not %), printed
unchanged, and conversions specifications. See printf
.
? dir = "/home/pari"; file = "aprcl"; n = 10; ? strprintf("%s/%s%ld.tex", dir, file, n) %2 = "/home/pari/aprcl10.tex"
The library syntax is GEN strprintf(const char *fmt, GEN vecx)
.
The variadic version char * pari_sprintf(const char *fmt, ...)
is usually preferable.
Splits the string s into a vector of strings, with p acting as a delimiter. If p is empty or omitted, split the string into characters.
? strsplit("abc::def::ghi", "::") %1 = ["abc", "def", "ghi"] ? strsplit("abc", "") %2 = ["a", "b", "c"] ? strsplit("aba", "a")
If s starts (resp. ends) with the pattern p, then the first (resp. last) entry in the vector is the empty string:
? strsplit("aba", "a") %3 = ["", "b", ""]
The library syntax is GEN strsplit(GEN s, GEN p = NULL)
.
Translates its arguments to TeX format, and concatenates the results into a
single character string (type t_STR
, the empty string if x is omitted).
The individual arguments are read in string context, see Section se:strings.
? v = [1, 2, 3] %1 [1, 2, 3] ? strtex(v) %2 = "\\pmatrix{ 1&2&3\\cr}\n"
TeX-nical notes. The TeX output engine was originally written
for plain TeX and designed for maximal portability. Unfortunately later
LaTeX
packages have obsoleted valid TeX primitives, leading us
to replace TeX's \over
by LaTeX's \frac
in PARI's TeX
output. We have decided not to update further our TeX markup and let the
users of various LaTeX engines customize their preambles. The following
documents the precise changes you may need to include in your style files to
incorporate PARI TeX output verbatim:
* if you enabled bit 4 in TeXstyle
default, you must define
\PARIbreak
; see ??TeXstyle
;
* if you use plain TeX only: you must define \frac
as follows
\def\frac#1#2{{#1\over#2}}
* if you use LaTeX and amsmath
, \pmatrix
is
obsoleted in favor of the pmatrix
environment; see
examples/parigp.sty
for how to re-enable the deprecated construct.
The library syntax is GEN strtex(GEN vecx)
.
Return a string describing the time t in milliseconds in the format used by the GP timer.
? print(strtime(12345678)) 3h, 25min, 45,678 ms ? { my(t=getabstime()); F=factor(2^256+1);t=getabstime()-t; print("factor(2^256+1) took ",strtime(t)); } factor(2^256+1) took 1,320 ms
The library syntax is GEN strtime(long t)
.
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. Return the shell return value (which is system-dependent).
Beware that UNIX shell convention for boolean is opposite to GP, true is 0
and false is non-0.
? system("test -d /") \\ test if '/' is a directory (true) %1 = 0 ? system("test -f /") \\ test if '/' is a file (false) %2 = 1
The library syntax is long gpsystem(const char *str)
.
This function is obsolete, use iferr
, which has a nicer and much
more powerful interface. For compatibility's sake we now describe the
obsolete function trap
.
This function tries to
evaluate seq, trapping runtime 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. See Section se:errorrec for an introduction to error recovery
under gp
.
? \\ trap division by 0 ? inv(x) = trap (e_INV, INFINITY, 1/x) ? inv(2) %1 = 1/2 ? inv(0) %2 = INFINITY
Note that seq is effectively evaluated up to the point that produced the error, and the recovery sequence is evaluated starting from that same context, it does not "undo" whatever happened in the other branch (restore the evaluation context):
? x = 1; trap (, /* recover: */ x, /* try: */ x = 0; 1/x) %1 = 0
Note. The interface is currently not adequate for trapping
individual exceptions. In the current version 2.17.0, 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
):
e_ALARM
: alarm time-out
e_ARCH
: not available on this architecture or operating system
e_STACK
: the PARI stack overflows
e_INV
: impossible inverse
e_IMPL
: not yet implemented
e_OVERFLOW
: all forms of arithmetic overflow, including length
or exponent overflow (when a larger value is supplied than the
implementation can handle).
e_SYNTAX
: syntax error
e_MISC
: miscellaneous error
e_TYPE
: wrong type
e_USER
: user error (from the error
function)
The library syntax is GEN trap0(const char *e = NULL, GEN rec = NULL, GEN seq = NULL)
.
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 GEN type0(GEN x)
.
The macro typ
is usually simpler to use since it returns a
long
that can easily be matched with the symbols t_*
. The name
type
was avoided since it is a reserved identifier for some compilers.
Remove x,..., z from the list of variables exported to the parallel world. See export.
Empty the list of variables exported to the parallel world.
The library syntax is void unexportall()
.
Exit the scope of all current inline
variables. DEPRECATED, use
export
/ unexport
.
Returns the current version number as a t_VEC
with three integer
components (major version number, minor version number and patchlevel);
if your sources were obtained through our version control system, this will
be followed by further more precise arguments, including
e.g. a git
commit hash.
This function is present in all versions of PARI following releases 2.3.4 (stable) and 2.4.3 (testing).
Unless you are working with multiple development versions, you probably only
care about the 3 first numeric components. In any case, the lex
function
offers a clever way to check against a particular version number, since it will
compare each successive vector entry, numerically or as strings, and will not
mind if the vectors it compares have different lengths:
if (lex(version(), [2,3,5]) >= 0, \\ code to be executed if we are running 2.3.5 or more recent. , \\ compatibility code );
On a number of different machines, version()
could return either of
%1 = [2, 3, 4] \\ released version, stable branch %1 = [2, 4, 3] \\ released version, testing branch %1 = [2, 6, 1, 15174, ""505ab9b"] \\ development
In particular, if you are only working with released versions, the first line of the gp introductory message can be emulated by
[M,m,p] = version(); printf("GP/PARI CALCULATOR Version %s.%s.%s", M,m,p);
If you are working with many development versions of PARI/GP, the 4th and/or 5th components can be profitably included in the name of your logfiles, for instance.
Technical note. For development versions obtained via git
,
the 4th and 5th components are liable to change eventually, but we document
their current meaning for completeness. The 4th component counts the number
of reachable commits in the branch (analogous to svn
's revision
number), and the 5th is the git
commit hash. In particular, lex
comparison still orders correctly development versions with respect to each
others or to released versions (provided we stay within a given branch,
e.g. master
)!
The library syntax is GEN pari_version()
.
Outputs the message "user warning" and the argument list (each of them interpreted as a string). If colors are enabled, this warning will be in a different color, making it easy to distinguish.
warning(n, " is very large, this might take a while.")
The library syntax is void warning0(GEN vec_str)
.
If keyword key is the name of a function that was present in GP version 1.39.15, outputs the new function name and syntax, if it changed at all. Functions that where introduced since then, then modified are also recognized.
? whatnow("mu") New syntax: mu(n) ===> moebius(n) moebius(x): Moebius function of x. ? whatnow("sin") This function did not change
When a function was removed and the underlying functionality is not available under a compatible interface, no equivalent is mentioned:
? whatnow("buchfu") This function no longer exists
(The closest equivalent would be to set K = bnfinit(T)
then access K.fu
.)
Writes (appends) to filename the remaining arguments, and appends a
newline (same output as print
).
Variant. The high-level function write
is expensive when many
consecutive writes are expected because it cannot use buffering. The low-level
interface fileopen
/ filewrite
/ fileclose
is more efficient.
It also allows to truncate existing files and replace their contents.
The library syntax is void write0(const char *filename, GEN vec_str)
.
Writes (appends) to filename the remaining arguments without a
trailing newline (same output as print1
).
The library syntax is void write1(const char *filename, GEN vec_str)
.
Writes (appends) to
filename the object x in binary format. This format is not human
readable, but contains the exact internal structure of x, and is much
faster to save/load than a string expression, as would be produced by
write
. The binary file format includes a magic number, so that such a
file can be recognized and correctly input by the regular read
or \r
function. If saved objects refer to polynomial variables that are not
defined in the new session, they will be displayed as tn
for some
integer n (the attached variable number).
Installed functions and history objects can not be saved via this function.
If x is omitted, saves all user variables from the session, together with
their names. Reading such a "named object" back in a gp
session will set
the corresponding user variable to the saved value. E.g after
x = 1; writebin("log")
reading log
into a clean session will set x
to 1.
The relative variables priorities (see Section se:priority) of new variables
set in this way remain the same (preset variables retain their former
priority, but are set to the new value). In particular, reading such a
session log into a clean session will restore all variables exactly as they
were in the original one.
Just as a regular input file, a binary file can be compressed
using gzip
, provided the file name has the standard .gz
extension.
In the present implementation, the binary files are architecture dependent
and compatibility with future versions of gp
is not guaranteed. Hence
binary files should not be used for long term storage (also, they are
larger and harder to compress than text files).
The library syntax is void gpwritebin(const char *filename, GEN x = NULL)
.
As write
, in TeX format. See strtex
for details:
this function is essentially equivalent to calling strtex
on remaining
arguments and writing them to file.
The library syntax is void writetex(const char *filename, GEN vec_str)
.