# Reduce multivariate polynomial coefficients to 1

Hi all,

I'm new to Python and SAGE and would like to ask a question: I have a multivariate polynomial, of a degree 3, i.e:

g.<x1,x2,x3>=x1^2 + 2x1x2 + x2^2 + 2x1x3 + 2x2x3 + x3^2 + 2x1 + 2x2 + 2*x3 + 1 Its type is <type 'sage.rings.polynomial.multi_polynomial_libsingular.mpolynomial_libsingu\="" lar'="">

The question is how can I reduce all its leading coefficients to 1, i.e. transform ig to:

g.<x1,x2,x3>=x1^2 + x1x2 + x2^2 + x1x3 + x2x3 + x3^2 + *x1 + *x2 + *x3 + 1

I tried to get the coefficients of the polynomial (which is a list), iterate through its items, and set the values of the items to 1, i.e.

for s in g.coefficients(): if s==2: s=1

I think that the problem is that list items can't be cast to integer (TypeError).

How could I solve this? Is there a more efficient way to do this? Thank you for your responses! Regards, Natassa

edit retag close merge delete

If speed matters, see compared timings in my answer.

( 2016-12-22 07:29:26 -0500 )edit

To display blocks of code, separate them by a blank line from the rest of the text, and either indent them with 4 spaces, or select the corresponding lines and click the "code" button (the icon with '101 010').

Can you edit your question to do that?

( 2016-12-22 07:33:04 -0500 )edit

Sort by » oldest newest most voted

The shortest way i could think of is to sum its nonzero monomials:

Setup:

sage: R = PolynomialRing(ZZ,'x',4)
sage: R.inject_variables()
Defining x0, x1, x2, x3
sage: g = x1^2 + 2*x1*x2 + x2^2 + 2*x1*x3 + 2*x2*x3 + x3^2 + 2*x1 + 2*x2 + 2*x3 + 1
sage: g
x1^2 + 2*x1*x2 + x2^2 + 2*x1*x3 + 2*x2*x3 + x3^2 + 2*x1 + 2*x2 + 2*x3 + 1


Then:

sage: sum(g.monomials())
x1^2 + x1*x2 + x2^2 + x1*x3 + x2*x3 + x3^2 + x1 + x2 + x3 + 1

more

## Reducing coefficients to one for multivariate polynomials

Taking the sum of monomials as suggested in the other answers works fine.

It is however faster to map all coefficients to one using map_coefficients.

### Context

sage: R.<x1, x2, x3> = QQbar[]
sage: P = x1^2 + 2*x1*x2 + x2^2 + 2*x1*x3 + 2*x2*x3 + x3^2 + 2*x1 + 2*x2 + 2*x3 + 1


### First approach: summing monomials

Summing monomials using the monomials method:

sage: sum(P.monomials())
x1^2 + x1*x2 + x2^2 + x1*x3 + x2*x3 + x3^2 + x1 + x2 + x3 + 1


Summing monomials iterating through the polynomial's coefficients and monomials:

sage: sum(m for c, m in P)
x1^2 + x1*x2 + x2^2 + x1*x3 + x2*x3 + x3^2 + x1 + x2 + x3 + 1


### Second approach: applying a map to coefficients

Using map_coefficients and plain 1:

sage: P.map_coefficients(lambda _: 1)
x1^2 + x1*x2 + x2^2 + x1*x3 + x2*x3 + x3^2 + x1 + x2 + x3 + 1


Using map_coefficients and QQbar's version of 1.

sage: QQbar_one = QQbar.one()
sage: to_QQbar_one = lambda _: QQbar_one
sage: P.map_coefficients(to_QQbar_one)
x1^2 + x1*x2 + x2^2 + x1*x3 + x2*x3 + x3^2 + x1 + x2 + x3 + 1


### Timings

Summing the monomials one way or another takes on the order of 700 µs.

sage: timeit('sum(P.monomials())')
625 loops, best of 3: 678 µs per loop

sage: timeit('sum(m for c, m in P)')
625 loops, best of 3: 682 µs per loop


Using map_coefficients is roughly ten times faster.

sage: QQbar_one = QQbar.one()
sage: to_QQbar_one = lambda _: QQbar_one
sage: timeit('P.map_coefficients(to_QQbar_one)')
625 loops, best of 3: 68.1 µs per loop


Note that the more naïve version wastes time since 1 gets converted to QQbar's 1 for each coefficient.

sage: timeit('P.map_coefficients(lambda _: 1)')
625 loops, best of 3: 139 µs per loop


### Further remarks

Depending on how the reduced polynomials are used later on, it might make more sense to change their base ring to some version of the boolean ring.

more

The code you provide is not valid, so I don't think this is what you have... The example below show the definition of a polynomial ring, a random polynomial from this ring, and then the polynomial with all coefficients replaced by $1$. The idea is to get the list of monomials, and then simply sum this list.

sage: R.<x1, x2, x3> = QQ[] # polynomial ring over QQ
sage: g = R.random_element(10) # random polynomial of degree 10
sage: g
3*x1^4*x2^5*x3 - 4*x1^7*x2*x3 + 8*x1*x2^7*x3 + 1/3*x1^4*x3^5 - 5*x1^6*x3
sage: g.monomials() # the monomials of g
[x1^4*x2^5*x3, x1^7*x2*x3, x1*x2^7*x3, x1^4*x3^5, x1^6*x3]
sage: sum(g.monomials()) # their sum
x1^4*x2^5*x3 + x1^7*x2*x3 + x1*x2^7*x3 + x1^4*x3^5 + x1^6*x3


Note that the use of sum(...) is equivalent to the following:

sage: g0 = R.zero() # the polynomial equal to zero
sage: for m in g.monomials():
....:     g0 += m

more

Thank you all,

Indeed, considering sum of all monomials does the trick! As a reference, a slightly tweaked solution below that worked for me:

g # the polynomial
list(g) # convert polynomial to list
g1=sum(mon for coeff, mon in g) # get the sum of all monomials

more