ASKSAGE: Sage Q&A Forum - Individual question feedhttp://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Mon, 16 Oct 2017 10:16:17 -0500Is there a way to get the homogeneous part of certain degree of a (multivariate) polynomial?http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/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.Sun, 15 Oct 2017 12:37:26 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/Comment by descudero for <p>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 <strong>homogeneous</strong> polynomial of degree $i$. Is there a <em>direct</em> 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$.</p>
<p>Is there a cleaner (and more efficient) way to do this? </p>
<p>Thanks for the help!</p>
<p><strong>EDIT:</strong></p>
<p>This is the code I'm using to obtain $f_d$ from $f$</p>
<pre><code>fd = R( f.homogenize()(h=0) )
</code></pre>
<p>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.</p>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39183#post-id-39183@slelievre Ok! I'm new in this forum, thanks for pointing that out! I've edited my answer, hopefully that helps :)Sun, 15 Oct 2017 16:56:12 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39183#post-id-39183Comment by slelievre for <p>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 <strong>homogeneous</strong> polynomial of degree $i$. Is there a <em>direct</em> 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$.</p>
<p>Is there a cleaner (and more efficient) way to do this? </p>
<p>Thanks for the help!</p>
<p><strong>EDIT:</strong></p>
<p>This is the code I'm using to obtain $f_d$ from $f$</p>
<pre><code>fd = R( f.homogenize()(h=0) )
</code></pre>
<p>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.</p>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39181#post-id-39181Hint: if you provide your code, the collective wisdom of Ask Sage answerers may help improve it!Sun, 15 Oct 2017 14:14:19 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39181#post-id-39181Answer by tmonteil for <p>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 <strong>homogeneous</strong> polynomial of degree $i$. Is there a <em>direct</em> 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$.</p>
<p>Is there a cleaner (and more efficient) way to do this? </p>
<p>Thanks for the help!</p>
<p><strong>EDIT:</strong></p>
<p>This is the code I'm using to obtain $f_d$ from $f$</p>
<pre><code>fd = R( f.homogenize()(h=0) )
</code></pre>
<p>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.</p>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?answer=39184#post-id-39184Here 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
Sun, 15 Oct 2017 17:12:16 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?answer=39184#post-id-39184Comment by tmonteil for <p>Here is a possible way:</p>
<p>Landscape (a concrete example to fix ideas):</p>
<pre><code>sage: R.<x,y> = QQ[]
sage: P = x^2+x*y+x+2
</code></pre>
<p>Instead of a list (with possibly lot of zeroes), let me use a <code>defaultdict</code> to collect the polynomials:</p>
<pre><code>sage: from collections import defaultdict
sage: d = defaultdict(P.parent())
</code></pre>
<p>Then we can feed it by iterating over the polynomial:</p>
<pre><code>sage: for coeff,monom in P:
....: d[monom.degree()] += coeff * monom
</code></pre>
<p>So we have:</p>
<pre><code>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
</code></pre>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39190#post-id-39190The problem is that the `__iter__` method is hidden, but you can get its documentation as follows:
sage: P.__iter__?Mon, 16 Oct 2017 10:16:17 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39190#post-id-39190Comment by descudero for <p>Here is a possible way:</p>
<p>Landscape (a concrete example to fix ideas):</p>
<pre><code>sage: R.<x,y> = QQ[]
sage: P = x^2+x*y+x+2
</code></pre>
<p>Instead of a list (with possibly lot of zeroes), let me use a <code>defaultdict</code> to collect the polynomials:</p>
<pre><code>sage: from collections import defaultdict
sage: d = defaultdict(P.parent())
</code></pre>
<p>Then we can feed it by iterating over the polynomial:</p>
<pre><code>sage: for coeff,monom in P:
....: d[monom.degree()] += coeff * monom
</code></pre>
<p>So we have:</p>
<pre><code>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
</code></pre>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39188#post-id-39188Thanks 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.Mon, 16 Oct 2017 07:35:04 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39188#post-id-39188Answer by Ant for <p>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 <strong>homogeneous</strong> polynomial of degree $i$. Is there a <em>direct</em> 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$.</p>
<p>Is there a cleaner (and more efficient) way to do this? </p>
<p>Thanks for the help!</p>
<p><strong>EDIT:</strong></p>
<p>This is the code I'm using to obtain $f_d$ from $f$</p>
<pre><code>fd = R( f.homogenize()(h=0) )
</code></pre>
<p>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.</p>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?answer=39189#post-id-39189If 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 Mon, 16 Oct 2017 09:26:59 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?answer=39189#post-id-39189Answer by dan_fulea for <p>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 <strong>homogeneous</strong> polynomial of degree $i$. Is there a <em>direct</em> 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$.</p>
<p>Is there a cleaner (and more efficient) way to do this? </p>
<p>Thanks for the help!</p>
<p><strong>EDIT:</strong></p>
<p>This is the code I'm using to obtain $f_d$ from $f$</p>
<pre><code>fd = R( f.homogenize()(h=0) )
</code></pre>
<p>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.</p>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?answer=39185#post-id-39185Just 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 ] )
Sun, 15 Oct 2017 22:07:23 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?answer=39185#post-id-39185Comment by descudero for <p>Just an other way, extract a version of <code>dPart</code> below adapted for the own needs...</p>
<p>Let us fix some test data.</p>
<pre><code>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 )
</code></pre>
<p>(1)</p>
<pre><code>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
</code></pre>
<p>(2) "Same", but not so easy to digest:</p>
<pre><code>dPart = lambda F, d: sum( [ c*m for c,m in F if m.total_degree() == d ] )
</code></pre>
<p>(3)
Or parse correspondingly the information in <code>F.dict()</code>, but this would be the too explicit solution:</p>
<pre><code>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 ] )
</code></pre>
http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39187#post-id-39187Thanks 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)Mon, 16 Oct 2017 07:34:56 -0500http://ask.sagemath.org/question/39177/is-there-a-way-to-get-the-homogeneous-part-of-certain-degree-of-a-multivariate-polynomial/?comment=39187#post-id-39187