Getting the monomials of a polynomial

jocaps
Messages : 118
Inscription : lun. avr. 17, 2017 4:32 pm

Getting the monomials of a polynomial

Message par jocaps » mer. déc. 27, 2017 10:20 am

Hi,

What is the easiest (and not very slow) way to get a list of monomials of a polynomial. For instance if I have 3x*y+3x^2+y
I want the list [3x*y,3x^2,y]. I can write a code that takes the total degree and walks through all possible monomial not exceeding this degree, but this will not be efficient. I can also convert the polynomial into string and then use python string manipulators that delimit all "+" and "-" and get the monomials, but I think giac has something more efficient.

Edit: I think I found a way that i think would be relatively fast.

Code : Tout sélectionner

from giacpy import giac,part
f=giac("3x*y+3*x**2+y")
monomials=[]
for i in xrange(len(f)):
  monomials.append(part(f,i+1))
This will yield [3*x*y,3x**2,y]

Jose

frederic han
Messages : 1113
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: Getting the monomials of a polynomial

Message par frederic han » mer. déc. 27, 2017 11:23 am

In giac your formula is a tree, you want the operands when sommet is +
but with symbolic coefficients it won't work.

related tools but different:
coeff(P,[x,y,z],[1,2,3]) to have the coeff of x^1*y^2*z^3 in P
or symb2poly(P,x,y,z)

Code : Tout sélectionner

from giacpy import *
x,y,z=giac('x,y,z')
P=(x+2*y-z+'1/2')**55
from time import time
Q=(P.ratnormal())  # here sommet is * (numerator/denominator)
t=time()
L=(Q.op(0)).op() # a giac list
L0=list(L)  # a python list of Pygen elements
print(time()-t)
#A=((sum(L)/Q).simplify())  # sum is long
monomials=[]
t=time()
for i in xrange(len(Q)):
  monomials.append(part(part(Q,1),i+1))  # here I need the numerator
print(time()-t)  

jocaps
Messages : 118
Inscription : lun. avr. 17, 2017 4:32 pm

Re: Getting the monomials of a polynomial

Message par jocaps » dim. nov. 25, 2018 4:10 pm

I know this is an old thread, but I want to point out on something in the last answer of frederic. The proposed method does not necessarily give me the correct list. Consider the following for instance

Code : Tout sélectionner

from giacpy import giac
x,y,z=giac('x,y,z')
P=x**2 + x +y
Q=(P.ratnormal())  # here sommet is * (numerator/denominator)
L=(Q.op(0)).op() # a giac list
L0=list(L)  # a python list of Pygen elements
print L0 #this gives me [x,2] , it should give me [x**2,x,y]

frederic han
Messages : 1113
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: Getting the monomials of a polynomial

Message par frederic han » lun. nov. 26, 2018 3:29 pm

The problem is that ratnormal can output a symbol with sommet * or +
So if the sommet is + you just have to do Q.op()

Code : Tout sélectionner

>>> P=x**2+3*x+y
>>> Q=P.ratnormal()
>>> Q.sommet()
'+'
>>> Q.op()
x**2,3*x,y
>>> P2=x**2+3*x/2+y  # warning 3/2*x is x in python2 but '3/2'*x or 3*x/2 are OK
>>> Q2=P2.ratnormal()
>>> Q2
(2*x**2+3*x+2*y)/2
>>> Q2.op(-1)
'*'
>>> Q2.op(0).op()
2*x**2,3*x,2*y
>>> Q3=P2.expand()  # expand is slower but output a sommet +
>>> Q3
x**2+3/2*x+y
>>> Q3.op(-1)
'+'
>>> Q3.op()
x**2,3/2*x,y


jocaps
Messages : 118
Inscription : lun. avr. 17, 2017 4:32 pm

Re: Getting the monomials of a polynomial

Message par jocaps » ven. nov. 30, 2018 10:51 am

Thanks fréderic. Though it seems to be a lot of work just for a list of monomials. I guess I will use it if the number of such monomials are rather long otherwise it will not be too expensive to just use "part".

Répondre