Search code examples
pythonsympypolynomials

How to set all polynomial coefficients to 1, in a multivariate sympy expression


Suppose I have a multivariate polynomial in sympy, for example:

import sympy as sp
from sympy.abc import x,y,z

expr = 2*x**2*y*z - x*z + 5*y**4*z

Ok, I know that we can extract all the monomial coefficients in a list by using Poly constructor:

pol = sp.Poly(expr)

>> pol.coeffs()
   [2, -1, 5]

But how can I proceed if I'd just want to normalize all the coefficients of the polynom, by setting all of them to 1? The final answer would be, following the previous example, something like:

x**2*y*z + x*z + y**4*z

Solution

  • You can do this using Expr manipulation like:

    In [17]: Add.make_args(expr)
    Out[17]: 
    ⎛         4       2    ⎞
    ⎝-x⋅z, 5⋅y ⋅z, 2⋅x ⋅y⋅z⎠
    
    In [18]: terms = Add.make_args(expr)
    
    In [19]: expr
    Out[19]: 
       2                4  
    2⋅x ⋅y⋅z - x⋅z + 5⋅y ⋅z
    
    In [20]: terms = Add.make_args(expr)
    
    In [21]: terms
    Out[21]: 
    ⎛         4       2    ⎞
    ⎝-x⋅z, 5⋅y ⋅z, 2⋅x ⋅y⋅z⎠
    
    In [22]: monoms = [t.as_coeff_Mul()[1] for t in terms]
    
    In [23]: monoms
    Out[23]: 
    ⎡      4     2    ⎤
    ⎣x⋅z, y ⋅z, x ⋅y⋅z⎦
    
    In [24]: monpoly = Add(*monoms)
    
    In [25]: monpoly
    Out[25]: 
     2              4  
    x ⋅y⋅z + x⋅z + y ⋅z
    

    In one line that's:

    In [26]: Add(*(t.as_coeff_Mul()[1] for t in Add.make_args(expr)))
    Out[26]: 
     2              4  
    x ⋅y⋅z + x⋅z + y ⋅z
    

    You can also do this with Poly and using monoms:

    In [27]: p = Poly(expr, [x, y, z])
    
    In [28]: p
    Out[28]: Poly(2*x**2*y*z - x*z + 5*y**4*z, x, y, z, domain='ZZ')
    
    In [29]: p.monoms()
    Out[29]: [(2, 1, 1), (1, 0, 1), (0, 4, 1)]
    
    In [30]: sum(prod(s**i for s, i in zip([x, y, z], indices)) for indices in p.monoms())
    Out[30]: 
     2              4  
    x ⋅y⋅z + x⋅z + y ⋅z
    

    If you wanted to do similar manipulation to this but actually use the coefficients then you could use as_coeff_Mul()[0] for the coefficients or p.coeffs() in the Poly case.