从Python调用PARI / GP

我只想从Python中调用PARI / GP来计算我定义的不同n的函数nextprime(n) 。 不幸的是,我不能安装pari-python ,所以我想用Python中的os.system命令行来调用它。 但是,在man page中我看不到如何让PARI / GP以非交互模式运行。 有没有办法做到这一点?

你可以像这样管道输入到gp的stdin,使用-q标志来消除冗长:

 senderle:~ $ echo "print(isprime(5))" | gp -q 1 

但是,创建一个简单的python扩展并不难,因为它允许将字符串传递给pari的内部分析器,并返回结果(以字符串形式)。 这是我刚才写的一个简单的版本,以便我可以从python调用pari的APRT测试实现。 您可以进一步扩展以进行适当的转换等等。

 //pariparse.c #include<Python.h> #include<pari/pari.h> static PyObject * pariparse_run(PyObject *self, PyObject *args) { pari_init(40000000, 2); const char *pari_code; char *outstr; if (!PyArg_ParseTuple(args, "s", &pari_code)) { return NULL; } outstr = GENtostr(gp_read_str(pari_code)); pari_close(); return Py_BuildValue("s", outstr); } static PyMethodDef PariparseMethods[] = { {"run", pariparse_run, METH_VARARGS, "Run a pari command."}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initpariparse(void) { (void) Py_Initmodulee("pariparse", PariparseMethods); } 

和安装文件:

 #setup.py from distutils.core import setup, Extension module1 = Extension('pariparse', include_dirs = ['/usr/include', '/usr/local/include'], libraries = ['pari'], library_dirs = ['/usr/lib', '/usr/local/lib'], sources = ['pariparse.c']) setup (name = 'pariparse', version = '0.01a', description = 'A super tiny python-pari interface', ext_modules = [module1]) 

然后只需输入python setup.py build来构建扩展。 你可以这样称呼它:

 >>> pariparse.run('nextprime(5280)') '5281' 

我刚刚测试了这个,它为我编译了最新版本的可用的自制软件(在OS X上)。 因人而异!

您可能想尝试使用Sage数学工具。 Sage使用Python将各种数学库(包括PARI)粘合在一起。 有些数学库很好地集成在一起,有些则使用黑客(将字符串传递到库中,然后解析出字符串结果),但是在所有情况下,其他人都可以使用集成工作,只需使用它即可。

你可以建立你自己的Sage系统,或者你可以得到一个免费的账户,并在华盛顿大学服务器上尝试Sage。

我不认为调用os.system不是一个好主意,除非你有一个可靠的C库。 从Python调用C函数是很容易的, 这里有两个调用nextprime的函数。 一个是使用long整数(尽管名称,这意味着你在使用小整数); 另一个是使用string类型(对于更长的整数)。

首先检查你是否安装了libpari 。 下面的解决方案适用于Linux,并假定您的库名为libpari.so 。 在Windows下,它可能会被调用.dll后缀。 如果在第一次尝试时找不到,则可能必须键入DLL文件的整个路径:

 import ctypes # load the library pari=ctypes.cdll.LoadLibrary("libpari.so") # set the right return type of the functions pari.stoi.restype = ctypes.POINTER(ctypes.c_long) pari.nextprime.restype = ctypes.POINTER(ctypes.c_long) pari.strtoGENstr.restype = ctypes.POINTER(ctypes.c_long) pari.geval.restype = ctypes.POINTER(ctypes.c_long) pari.itostr.restype = ctypes.c_char_p # initialize the library pari.pari_init(2**19,0) def nextprime(v): g = pari.nextprime(pari.stoi(ctypes.c_long(v))) return pari.itos(g) def nextprime2(v): g = pari.nextprime(pari.geval(pari.strtoGENstr(str(v)))) return int(pari.itostr(g)) print( nextprime(456) ) print( nextprime2(456) )