Вызов PARI/GP из Python
Я хотел бы вызвать PARI/GP из Python только для вычисления функции nextprime(n)
для разных n
с, что я определяю. К сожалению, я не могу установить pari-python для установки, поэтому я подумал, что просто вызову его с помощью командной строки через os.system
в Python. Однако на странице руководства я не вижу, как заставить PARI/GP работать в неинтерактивном режиме. Есть ли способ добиться этого?
3 ответа
Вы можете передать ввод в stpin gp, используя -q
признак отмены многословия:
senderle:~ $ echo "print(isprime(5))" | gp -q
1
Однако не так сложно создать простое расширение Python, которое позволит вам передавать строки во внутренний синтаксический анализатор pari и получать результаты обратно (в виде строк). Вот голая версия, которую я написал некоторое время назад, чтобы я мог вызвать реализацию pari теста APRT из python. Вы можете расширить это, чтобы сделать соответствующие преобразования и так далее.
//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);
}
И установочный файл:
#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'
Я только что проверил это, и он скомпилирован для меня с последней версией пари, доступной через homebrew (на OS X). YMMV!
Вы можете попробовать использовать математический инструмент Sage. Sage использует Python для склеивания всех видов математических библиотек, включая PARI. Некоторые из математических библиотек хорошо интегрированы, другие используют хаки (передача строк в библиотеку и затем анализ результатов строк), но во всех случаях кто-то другой сделал интеграцию за вас, и вы можете просто использовать ее.
Вы можете настроить свою собственную систему Sage или получить бесплатную учетную запись и попробовать Sage на серверах Университета Вашингтона.
Я не думаю, что это хорошая идея, чтобы позвонить os.system
за исключением быстрого и грязного обходного пути, когда за ним стоит надежная библиотека Си. Вызывать функции C из Python очень просто; Вот две функции для вызова 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) )