The extern routine allows gp to call an arbitrary program, and
feed its result to the interpreter. This mechanism passes arguments
to the external program as character strings, and reads its output as if it
had been typed directly into gp. It is powerful, and simpler than the tight
integration provided by install, which is more appropriate for
heavy-duty usage of low level routines.
Unfortunately, using extern involves a number of interface
problems which will vary from one application to the next. In this page, we
shall use John Cremona's
mwrank package as a moderately complicated case study. Given
an elliptic curve E over Q, mwrank returns the rank of the free
part of the group of its rational points, and a set of points generating a
subgroup of finite index in this group.
We assume henceforth that you have a working version of mwrank
installed on your computer.
mwrank)ellrank calling the shellscriptgpmwrank. This file must be executable
and in your shell path, e.g. $HOME/bin. Put the following lines
in this file:
#!/bin/sh
res=`echo "$1 0 0 0 0 0" | mwrank -q -v 0 -o | grep '^\['`
if test -z "$res"; then
echo 'error("An error occured in mwrank")'
else
echo "$res"
fi
This passes on its arguments to mwrank (in non-interactive mode,
mwrank expects five 0 in a row to signal that input is over), and stores in
the variable res the lines beginning with [. In fact, there will
be a single such line: mwrank's result. If res is non-empty,
mwrank produced a result and we output it.
Otherwise an error occured, and we act accordingly: remember that the output of this file will be read by gp's interpreter, so we do not trigger an error here, we print a command that will trigger it when read by gp.
Make sure this script is executable (chmod 755 gpmwrank), then put it somewhere in your PATH. (This is a list of directories where your shell looks for executable files.)
Note: The time ellapsed in commands called via extern is not taken into account by gp's timer. You may want to use extern("time cmd") instead of extern("cmd").ellrank, create a file
ellrank.gp containing the following lines:
ellrank(e) =
{ local(l = length(e));
if (type(e) != "t_VEC" || (l != 5 && l != 13 && l != 19),
error("incorrect type in ellrank")
);
extern( Str("gpmwrank ["e[1]","e[2]","e[3]","e[4]","e[5]"]") )
}
This does some rudimentary error checking then calls gpmwrank
and returns its output.
Put this file somewhere in your GP path. (See the path default in the manual.)
.gprc file:
read "ellrank.gp"
This causes the ellrank.gp file to be read into gp upon startup,
thereby defining ellrank() routine in all gp sessions!
Of course, the names of the file and function do not have to coincide. They
were chosen as above for consistency and self-documentation:
ellrank.gp tells about its content, whereas lib.gp
or extra.gp would not.
path = "$HOME/pari/gpscripts"
in your .gprc, if for instance ellrank.gp went there.
? ellrank([0,-1,1,-10,-20])
%1 = [[0], []]
? ellrank([0,0,1,-1,0])
%2 = [[1], [[0, 0]]]
? ellrank([1,0,0,0,1])
%3 = [[2], [[1, 1], [3/4, 7/8]]]
[To main
| To resources page ]
| Karim Belabas |
|
| Tue Sep 7 12:03:12 MEST 2004 |