Calling PARI/GP from Python

删除回忆录丶 提交于 2021-02-07 03:27:31

问题


I would like to call PARI/GP from Python only to calculate the function nextprime(n) for different ns that I define. Unfortunately I can't get pari-python to install so I thought I would just call it using a command line via os.system in Python. I can't see in the man page how to do get PARI/GP to run in non-interactive mode, however. Is there a way to achieve this?


回答1:


You can pipe input into gp's stdin like so, using the -q flag to quash verbosity:

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

However, it's not much harder to create a simple python extension that allows you to pass strings to pari's internal parser and get results back (as strings). Here's a bare-bones version that I wrote some time ago so that I could call pari's implementation of the APRT test from python. You could extend this further to do appropriate conversions and so on.

//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_InitModule("pariparse", PariparseMethods);
}

And the setup file:

#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])

Then just type python setup.py build to build the extension. You can then call it like this:

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

I tested this just now and it compiled for me with the latest version of pari available via homebrew (on OS X). YMMV!




回答2:


You might want to try using the Sage math tool. Sage uses Python to glue together all sorts of math libraries, including PARI. Some of the math libraries are nicely integrated, others use hacks (passing strings in to the library and then parsing out the string results) but in all cases someone else did the integration work for you and you can just use it.

You can set up your own Sage system, or you can get a free account and try Sage on the University of Washington servers.




回答3:


I don't think it is a good idea to call os.system except for a quick and dirty workaround when you have a reliable C library behind it. It is very easy to call C functions from Python; here are two functions for calling nextprime. One is using long integers (despite the name, it will mean here that you are using small integer numbers); the other is using the string type (for longer integers).

First check that you have the libpari installed. The solution below is for Linux and assumes that your library is called libpari.so. Under Windows it will probably be called with a .dll suffix instead. You may have to type the whole path of the DLL file if it isn't found at first attempt:

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


来源:https://stackoverflow.com/questions/14943507/calling-pari-gp-from-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!