本文介绍了从Python(ctypes)将多项式发送到PARI / GP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想调用nfroots({nf}; x)函数python中的dochtml / gpman.html rel = nofollow noreferrer> PARI / GP 。 ,但是问题是,我无法发送需要发送的代数表达式或多项式,例如, x ^ 2-7x + 12 ,这是 gp 可以处理四次多项式的一个非常简单的示例:

I would like to call nfroots({nf}; x) function of PARI/GP from Python. (see function no 3.13.135.on page 371 in this link:), but the probllem is, I couldn't send the algebraic expression or the polynomial, that need to be send, for example, x^2-7x+12, here is a very simple example of what gp can do with a quartic polynomial:

> 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代码?

Note that there is specific process to create of PARI objects (see the answer of Stephan Schlecht), I changed the value for t_POL = 10 , but the code didn't work, How can I execute the above PARI/GP code from python?

推荐答案

一种解决方案可能是:


  • 使用gtopoly,返回类型为 POINTER(c_long)

  • nfroots的返回类型为 POINTER(POINTER(c_long))

  • 具有 .pari_printf

  • use gtopoly, return type is POINTER(c_long)
  • return type of nfroots is POINTER(POINTER(c_long))
  • output of result with .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()

测试

如果您运行该程序,则会得到在调试控制台中所需的输出:

If you run the program you get the desired output in the debug console:

[3, 4]

转化

长度 可以确定向量的长度,请参见

With glength one can determine the length of a vector, seehttps://pari.math.u-bordeaux.fr/dochtml/html/Conversions_and_similar_elementary_functions_or_commands.html#length

如果参数的类型为t_INT,则使用 itos 可以返回长整数,请参见。

With itos a long can be returned if the parameter is of type t_INT, see section 4.4.6 of https://pari.math.u-bordeaux.fr/pub/pari/manuals/2.7.6/libpari.pdf.

在代码中看起来像这样:

In code it would look like this:

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 给出参数的字符串表示形式。可以这样使用:

To GENtostr gives a string representation of the argument. It could be used like so:

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

还有更多转换选项,请参见上面的两个链接。

There are many more conversion options, see the two links above.

这篇关于从Python(ctypes)将多项式发送到PARI / GP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 20:53