Ask Your Question

Revision history [back]

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.