sympypolynomials

Is there any all_coeffs() for multivariable polynomials in sympy?


I want to extract all coefficients (INCLUDING ZEROS) of a multariable polynomial using sympy.

Sympy offers all_coeffs() but it only works for univariate. Otherwise I get this error PolynomialError: multivariate polynomials not supported

For example for a polynomial x^3+y^3+x*y+1 I woud like the output to be [3,3,0,0,0,0,1,0,0,1]


Solution

  • If you make the monomials of interest then you can see what their coefficients are in your expression. You have to watch out for requesting a monomial coefficient of x*y in an expression with terms like x*y*z, however. The following routine handles that by zeroing out any variables in the coefficient that is obtained. It also has a routine to create monomials of interest.

    def all_coeffs(expr,*free):
        x = IndexedBase('x')
        expr = expr.expand()
        f = expr.free_symbols
        free = set(free) & f if free else f
        if not free:
            return {1: expr} # XXX {S(1): expr} might be needed?
        pows = [p.as_base_exp() for p in expr.atoms(Pow,Symbol)]
        P = {}
        for p,e in pows:
            if p not in free:
                continue
            elif p not in P:
                P[p]=e
            elif e>P[p]:
                P[p] = e
        reps = dict([(f, x[i]) for i,f in enumerate(free)])
        xzero = dict([(v,0) for k,v in reps.items()])
        e = expr.xreplace(reps); reps = {v:k for k,v in reps.items()}
        return dict([(m.xreplace(reps), e.coeff(m).xreplace(xzero) if m!=1 else e.xreplace(xzero)) for m in monoms(*[P[f] for f in free])])
    
    def monoms(*o):
        x = IndexedBase('x')
        f = []
        for i,o in enumerate(o):
            f.append(Poly([1]*(o+1),x[i]).as_expr())
        return Mul(*f).expand().args
    
    >>> eq = x**2 + x*y - 3
    >>> all_coeffs(eq)
    {1: -3, x**2: 1, x**2*y: 0, x*y: 1, y: 0, x: 0}
    >>> all_coeffs(eq, x)
    {1: -3, x**2: 1, x: y}
    >>> all_coeffs(eq, z)
    {1: x**2 + x*y - 3}