将多项式从 Python 发送到 PARI/GP (ctypes)
Sending a Polynomial to PARI/GP from Python (ctypes)
我想调用PARI/GP from Python. (see function no 3.13.135.on page 371 in this link:)的nfroots({nf}; x)
函数,但问题是,我无法发送需要发送的代数表达式或多项式,例如,x^2-7x+12
,这是一个非常简单的例子,说明 gp
可以用四次多项式做什么:
> V = readvec("coeff.txt");
> print(V)
[1,-7,12]
> P = Pol(V); # I get following error when I use Pol in my code: func=self._FuncPtr((name_or_ordinal, self)) AttributeError: function 'pol' not found
> print(P)
x^2 -7*x +12
> print(nfroots(,P))
>4, 3
根据 的回答,我设法写了 -
from ctypes import *
pari = cdll.LoadLibrary("C:\Program Files\Pari64-2-11-3\libpari.dll")
pari.stoi.restype = POINTER(c_long)
pari.cgetg.restype = POINTER(POINTER(c_long))
pari.nfroots.restype = POINTER(POINTER(c_long))
pari.pari_init(2 ** 19, 0)
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(10)) #t_POL = 10,
for i in range(1, l):
p1[i] = pari.stoi(c_long(numbers[i - 1]))
return p1
def main():
h = "x^2-7x+12"
res = pari.nfroots(t_vec(h))
for i in range(1, len(res)):
print(pari.itos(res[i]))
if __name__ == '__main__':
main()
请注意,创建 PARI 对象有特定的过程(请参阅 的答案),我更改了 t_POL = 10
的值,但代码不起作用,我怎么能从 python?
执行上面的 PARI/GP 代码
一个解决方案可能是:
- 使用gtopoly,return类型是
POINTER(c_long)
- return nfroots 的类型是
POINTER(POINTER(c_long))
.pari_printf
的结果输出
代码
from ctypes import *
pari = cdll.LoadLibrary("libpari.so")
pari.stoi.restype = POINTER(c_long)
pari.cgetg.restype = POINTER(POINTER(c_long))
pari.gtopoly.restype = POINTER(c_long)
pari.nfroots.restype = POINTER(POINTER(c_long))
(t_VEC, t_COL, t_MAT) = (17, 18, 19) # incomplete
precision = c_long(38)
pari.pari_init(2 ** 19, 0)
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(t_VEC))
for i in range(1, l):
p1[i] = pari.stoi(c_long(numbers[i - 1]))
return p1
def main():
V = (1, -7, 12)
P = pari.gtopoly(t_vec(V), c_long(-1))
res = pari.nfroots(None, P)
pari.pari_printf(bytes("%Ps\n", "utf8"), res)
if __name__ == '__main__':
main()
测试
如果您 运行 程序,您将在调试控制台中获得所需的输出:
[3, 4]
转化次数
用glength
可以确定向量的长度,见
https://pari.math.u-bordeaux.fr/dochtml/html/Conversions_and_similar_elementary_functions_or_commands.html#length
使用 itos
如果参数的类型为 t_INT,则 long 可以 returned,请参阅 https://pari.math.u-bordeaux.fr/pub/pari/manuals/2.7.6/libpari.pdf 的第 4.4.6 节。
在代码中它看起来像这样:
pari.glength.restype = c_long
pari.itos.restype = c_long
...
print("elements as long (only if of type t_INT): ")
for i in range(1, pari.glength(res) + 1):
print(pari.itos(res[i]))
To GENtostr
给出参数的字符串表示。它可以像这样使用:
pari.GENtostr.restype = c_char_p
...
print("elements as generic strings: ")
for i in range(1, pari.glength(res) + 1):
print(pari.GENtostr(res[i]).decode("utf-8"))
还有更多转换选项,请参阅上面的两个链接。
我想调用PARI/GP from Python. (see function no 3.13.135.on page 371 in this link:)的nfroots({nf}; x)
函数,但问题是,我无法发送需要发送的代数表达式或多项式,例如,x^2-7x+12
,这是一个非常简单的例子,说明 gp
可以用四次多项式做什么:
> V = readvec("coeff.txt");
> print(V)
[1,-7,12]
> P = Pol(V); # I get following error when I use Pol in my code: func=self._FuncPtr((name_or_ordinal, self)) AttributeError: function 'pol' not found
> print(P)
x^2 -7*x +12
> print(nfroots(,P))
>4, 3
根据
from ctypes import *
pari = cdll.LoadLibrary("C:\Program Files\Pari64-2-11-3\libpari.dll")
pari.stoi.restype = POINTER(c_long)
pari.cgetg.restype = POINTER(POINTER(c_long))
pari.nfroots.restype = POINTER(POINTER(c_long))
pari.pari_init(2 ** 19, 0)
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(10)) #t_POL = 10,
for i in range(1, l):
p1[i] = pari.stoi(c_long(numbers[i - 1]))
return p1
def main():
h = "x^2-7x+12"
res = pari.nfroots(t_vec(h))
for i in range(1, len(res)):
print(pari.itos(res[i]))
if __name__ == '__main__':
main()
请注意,创建 PARI 对象有特定的过程(请参阅 t_POL = 10
的值,但代码不起作用,我怎么能从 python?
一个解决方案可能是:
- 使用gtopoly,return类型是
POINTER(c_long)
- return nfroots 的类型是
POINTER(POINTER(c_long))
.pari_printf
的结果输出
代码
from ctypes import *
pari = cdll.LoadLibrary("libpari.so")
pari.stoi.restype = POINTER(c_long)
pari.cgetg.restype = POINTER(POINTER(c_long))
pari.gtopoly.restype = POINTER(c_long)
pari.nfroots.restype = POINTER(POINTER(c_long))
(t_VEC, t_COL, t_MAT) = (17, 18, 19) # incomplete
precision = c_long(38)
pari.pari_init(2 ** 19, 0)
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(t_VEC))
for i in range(1, l):
p1[i] = pari.stoi(c_long(numbers[i - 1]))
return p1
def main():
V = (1, -7, 12)
P = pari.gtopoly(t_vec(V), c_long(-1))
res = pari.nfroots(None, P)
pari.pari_printf(bytes("%Ps\n", "utf8"), res)
if __name__ == '__main__':
main()
测试
如果您 运行 程序,您将在调试控制台中获得所需的输出:
[3, 4]
转化次数
用glength
可以确定向量的长度,见
https://pari.math.u-bordeaux.fr/dochtml/html/Conversions_and_similar_elementary_functions_or_commands.html#length
使用 itos
如果参数的类型为 t_INT,则 long 可以 returned,请参阅 https://pari.math.u-bordeaux.fr/pub/pari/manuals/2.7.6/libpari.pdf 的第 4.4.6 节。
在代码中它看起来像这样:
pari.glength.restype = c_long
pari.itos.restype = c_long
...
print("elements as long (only if of type t_INT): ")
for i in range(1, pari.glength(res) + 1):
print(pari.itos(res[i]))
To GENtostr
给出参数的字符串表示。它可以像这样使用:
pari.GENtostr.restype = c_char_p
...
print("elements as generic strings: ")
for i in range(1, pari.glength(res) + 1):
print(pari.GENtostr(res[i]).decode("utf-8"))
还有更多转换选项,请参阅上面的两个链接。