Getting an Array/Vector from PARI/GP in Python using Ctypes

Question:

I have written a code to compare the solution of sympy and PARI/GP, how ever I am facing a problem to get an array/vector from PARI/GP.

When I try to return the vector res from PARI/GP function nfroots, I get a address like this (see the last line) –

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

how can I get the res as vector/array from nfroots so I can use that array like normal python vector/array?

The code is given below to download the libpari.dll file, click here

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)

Answers:

res is an element from the PARI/C world. It is a PARI vector of PARI integers (t_VEC of t_INTs). Python does not know it.

If it is to be processed further on the Python side, it must be converted. This is generally necessary if data needs to be exchanged between Python and the PARI/C world.

So if you have a t_VEC with t_INTs on the PARI/C side, as in this case, you most likely want to convert it to a Python list.

One possible approach might look like this:

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

result = []
for i in range(1, pari.glength(roots) + 1):
    result.append(pari.itos(roots[i]))
return result
Answered By: Stephan Schlecht
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.