Получение массива / вектора из PARI / GP в Python с использованием Ctypes - PullRequest
0 голосов
/ 26 марта 2020

Я написал код для сравнения решения sympy и PARI/GP, но когда я сталкиваюсь с проблемой получения массива / вектора из PARI / GP.

Когда я пытаюсь вернуться вектор res из функции PARI / GP nfroots, я получаю такой адрес (см. последнюю строку) -

    [3, 4]
elements as long (only if of type t_INT): 
3
4
<__main__.LP_LP_c_long object at 0x00000000056166C8>

как мне получить res как вектор / массив из nfroots чтобы я мог использовать этот массив как обычный python вектор / массив?

Код приведен ниже , чтобы загрузить файл libpari.dll, нажмите здесь -

from ctypes import *
from sympy.solvers import solve
from sympy import Symbol

pari = cdll.LoadLibrary("libpari.dll")
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
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):
        #Changed c_long to c_float, but got no output
        p1[i] = pari.stoi(c_long(numbers[i - 1]))
    return p1


def Quartic_Comparison():
    x = Symbol('x')
    #a=0;A=0;B=1;C=-7;D=13/12 #PROBLEM 1
    a=0;A=0;B=1;C=-7;D=12
    #a=0;A=0;B=-1;C=-2;D=1
    solution=solve(a*x**4+A*x**3+B*x**2+ C*x + D, x)
    print(solution)
    V=(A,B,C,D)
    P = pari.gtopoly(t_vec(V), c_long(-1))
    res = pari.nfroots(None, P)

    print("elements as long (only if of type t_INT): ")
    for i in range(1, pari.glength(res) + 1):        
         print(pari.itos(res[i]))
    return res               #PROBLEM 2

f=Quartic_Comparison()
print(f)

1 Ответ

1 голос
/ 26 марта 2020

res - это элемент из мира PARI / C. Это вектор PARI целых чисел PARI (t_VE C из t_INTs). Python не знает этого.

Если его необходимо обработать на стороне Python, его необходимо преобразовать. Это обычно необходимо, если требуется обмен данными между Python и миром PARI / C.

Так что, если у вас есть t_VE C с t_INTs на стороне PARI / C, как в этом случае, вы, скорее всего, захотите преобразовать его в список Python.

Один из возможных подходов может выглядеть следующим образом:

...
roots = pari.nfroots(None, P)

result = []
for i in range(1, pari.glength(roots) + 1):
    result.append(pari.itos(roots[i]))
return result
...