# How do I truncate multivariate polynomials?

Say that I have a polynomial ring

R.<a,b,c>=PolynomialRing(QQ)

How do a get the part of a polynomial P where the sum of degree in a,b, and c are less than a given number N? If P were a univariate polynomial, this could be done with P[:N].

edit retag close merge delete

( 2022-03-30 04:48:29 +0200 )edit

Thank you Max. What if I want to truncate each polynomial to different precision? Is it possible in sage?

( 2022-03-30 07:35:43 +0200 )edit

Sort by » oldest newest most voted

Each polynomial can be seen as a dictionary whose items encode the monomials.

The keys are tuple of degrees and the values are the corresponding coefficients.

We can filter that dictionary, keeping only monomials of bounded total degree.

Then we can build the polynomial corresponding to that filtered dictionary.

Here is a function to do that:

def truncate(P, N):
r"""
Return this polynomial truncated to total degree N.
"""
trunc = {dd: c for dd, c in P.dict().items() if sum(dd) <= N}
return P.parent()(trunc)


Usage:

sage: R.<a, b, c> = PolynomialRing(QQ)

sage: PP = [R.random_element(5) for _ in range(3)]
sage: PP
[a*b^4 + 1/2*b^4*c + 2/3*b^3*c - 4/9*b^2*c - b^2,
5*b^5 - 3/2*a^3*c^2 + 3/5*b^2*c - 1,
-1/6*b^3*c^2 - 3*a*c^3 + b^2 - 3*b*c]

sage: [truncate(P, 3) for P in PP]
[-4/9*b^2*c - b^2, 3/5*b^2*c - 1, b^2 - 3*b*c]


The multivariate polynomials method truncate only allows to truncate with respect to the degree in one of the variables. It could be improved to perform truncation by total degree.

more

Here is a condensed version of @slelievre's answer.

We can iterate over the dictionary items for P in a simpler way.

For example:

 sage: sum((c*t for c, t in P if t.degree() <= N), P.parent().zero())


Note how we start the sum at the zero polynomial.

With this, polynomials without terms of degree <= N give the zero polynomial, not the integer zero.

more

I think it should become the accepted answer.

( 2022-03-31 22:24:50 +0200 )edit

Thanks! I believe 0 is coerced to P.parent().zero() automatically and specifying it isn't required. The only case when this may make a difference is when the sum is zero and we want to get P.parent().zero() rather than integer 0. Also, the parentheses around the first argument of sum are not strictly required either - it understands that it's a generator without them anyway. But I agree that the current form does not allow any misinterpretation.

( 2022-04-02 20:54:56 +0200 )edit
1

As you guessed,

• the optional starting point is so you get a polynomial even if the sum is empty
• one can use sum(a for b in c if d) without extra parentheses, except in one case:
• specifying the starting point requires extra parentheses: sum((a for b in c if d), start)
( 2022-04-05 23:33:40 +0200 )edit

Good point!

( 2022-04-06 00:31:15 +0200 )edit