Ask Your Question
3

Is there a way to get the homogeneous part of certain degree of a (multivariate) polynomial?

asked 2017-10-15 12:37:26 -0600

descudero gravatar image

updated 2017-10-15 16:55:28 -0600

Every multivariate polynomial $f\in\Bbb F[x_1,\ldots,x_n]$ of degree $d$ can be written as $f = f_0+f_1+\cdots+f_d$, where $f_i$ is a homogeneous polynomial of degree $i$. Is there a direct way to get each $f_i$ given $f$ in SageMath? For a specific application I have where I only need $f_d$ I am homogenizing and then setting $h=0$, and based on this I wrote an ugly script that recursively finds $f_i$.

Is there a cleaner (and more efficient) way to do this?

Thanks for the help!

EDIT:

This is the code I'm using to obtain $f_d$ from $f$

fd = R( f.homogenize()(h=0) )

where R is the multivariate polynomial ring (parent of $f$). If I want $f_{d-1}$ for example, I can define $g$ as $f - f_d$ and apply the line to $g$. This recursive definition is not satisfactory since to get $f_i$ I need to have all $f_{i+1},\ldots,f_d$ first, which is inefficient. Also, that trick of homogenizing, evaluating $h=0$ and coercing the result back to the original polynomial ring is not very neat.

edit retag flag offensive close merge delete

Comments

Hint: if you provide your code, the collective wisdom of Ask Sage answerers may help improve it!

slelievre gravatar imageslelievre ( 2017-10-15 14:14:19 -0600 )edit

@slelievre Ok! I'm new in this forum, thanks for pointing that out! I've edited my answer, hopefully that helps :)

descudero gravatar imagedescudero ( 2017-10-15 16:56:12 -0600 )edit

3 answers

Sort by ยป oldest newest most voted
2

answered 2017-10-15 17:12:16 -0600

tmonteil gravatar image

Here is a possible way:

Landscape (a concrete example to fix ideas):

sage: R.<x,y> = QQ[]
sage: P = x^2+x*y+x+2

Instead of a list (with possibly lot of zeroes), let me use a defaultdict to collect the polynomials:

sage: from collections import defaultdict
sage: d = defaultdict(P.parent())

Then we can feed it by iterating over the polynomial:

sage: for coeff,monom in P:
....:     d[monom.degree()] += coeff * monom

So we have:

sage: d
defaultdict(Multivariate Polynomial Ring in x, y over Rational Field, {0: 2, 1: x, 2: x^2 + x*y})
sage: d[0]
2
sage: d[1]
x
sage: d[2]
x^2 + x*y
sage: d[3]
0
sage: d[123]
0
sage: d[123].parent()
Multivariate Polynomial Ring in x, y over Rational Field
sage: sum(d[i] for i in d)
x^2 + x*y + x + 2
sage: sum(d[i] for i in d) == P
True
edit flag offensive delete link more

Comments

Thanks a lot for the reply! Something I didn't know is that I could iterate over coefficients and monomials of a polynomial like you did (where is that stated in the documentation?), that makes the work much easier.

descudero gravatar imagedescudero ( 2017-10-16 07:35:04 -0600 )edit

The problem is that the __iter__ method is hidden, but you can get its documentation as follows:

 sage: P.__iter__?
tmonteil gravatar imagetmonteil ( 2017-10-16 10:16:17 -0600 )edit
1

answered 2017-10-15 22:07:23 -0600

dan_fulea gravatar image

Just an other way, extract a version of dPart below adapted for the own needs...

Let us fix some test data.

sage: var( 'x,y,z' );
sage: F = 27*x^5 + x^2*y^2 + 19*z^4 + 55*x*y*z + 6
sage: F = F.polynomial( QQ )

(1)

sage: def dPart( F, d ):
....:     return sum( [ F.monomial_coefficient(m) * m
....:                   for m in F.monomials() 
....:                   if  m.total_degree() == d ] )
....: 

sage: for d in range(6):
....:     print "total degree %s -> %s" % ( d, dPart( F, d ) )
....:     
total degree 0 -> 6
total degree 1 -> 0
total degree 2 -> 0
total degree 3 -> 55*x*y*z
total degree 4 -> x^2*y^2 + 19*z^4
total degree 5 -> 27*x^5

(2) "Same", but not so easy to digest:

dPart = lambda F, d: sum( [ c*m for c,m in F if m.total_degree() == d ] )

(3) Or parse correspondingly the information in F.dict(), but this would be the too explicit solution:

sage: def dPart( F, d ):
....:     vars = F.variables()
....:     return sum( [ coeff * prod( [ vars[k]^degrees[k] for k in range(len(vars)) ] )
....:                   for degrees, coeff in F.dict().items()
....:                   if  sum(degrees) == d ] )
edit flag offensive delete link more

Comments

Thanks for your answer! I like this approach. However, every time you need the same polynimial you need to do the same iteration over and over again, which is avoided in the solution in the other answer by using the dictionary. What I like about this one though is how concise it is (specially the lambda one)

descudero gravatar imagedescudero ( 2017-10-16 07:34:56 -0600 )edit
0

answered 2017-10-16 09:26:59 -0600

Ant gravatar image

If you don't want to write your own functions, you can also try adding O(d+1) in the corresponding power series ring to kill all higher order terms, then extract the polynomial back using .polynomial(), and then using your homogenize idea

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-10-15 12:37:26 -0600

Seen: 46 times

Last updated: Oct 16