Ask Your Question

How do I truncate multivariate polynomials?

asked 2022-03-30 04:42:32 +0200

mcmug gravatar image

Say that I have a polynomial ring


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].

Thank you in advance!

edit retag flag offensive close merge delete


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

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

2 Answers

Sort by ยป oldest newest most voted

answered 2022-03-30 09:26:01 +0200

slelievre gravatar image

updated 2022-03-30 09:29:20 +0200

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):
    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)


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.

edit flag offensive delete link more

answered 2022-03-30 16:50:35 +0200

Max Alekseyev gravatar image

updated 2022-03-31 22:27:29 +0200

slelievre gravatar image

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 <= 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.

edit flag offensive delete link more


I turned your comment into an answer (and slightly edited it).

I think it should become the accepted answer.

slelievre gravatar imageslelievre ( 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.

Max Alekseyev gravatar imageMax Alekseyev ( 2022-04-02 20:54:56 +0200 )edit

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)
slelievre gravatar imageslelievre ( 2022-04-05 23:33:40 +0200 )edit

Good point!

Max Alekseyev gravatar imageMax Alekseyev ( 2022-04-06 00:31:15 +0200 )edit

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


Asked: 2022-03-30 04:42:32 +0200

Seen: 326 times

Last updated: Mar 31 '22