pythonsympy

sympy.polys.polyerrors.PolynomialError: x2*x3 contains an element of the set of generators


I was confused with the sympy.sympify's option evaluate

I've test the following code and it works perfectly

import sympy as sp
def test(s1 = "x1 - x2*x3"):
    e1 = sp.sympify(s1)
    syms = sorted(e1.free_symbols, key=lambda s: s.name)
    p1 = sp.Poly(e1, *syms, expand=False)

if I add the evaluate option to sp.sympify, then error occurs

bug code

import sympy as sp
def test(s1 = "x1 - x2*x3"):
    e1 = sp.sympify(s1, evaluate=False)
    syms = sorted(e1.free_symbols, key=lambda s: s.name)
    p1 = sp.Poly(e1, *syms, expand=False)

main error message

sympy.polys.polyerrors.PolynomialError: x2*x3 contains an element of the set of generators.

I want to know why evaluate=False option caused an error in sp.Poly.


Solution

  • You have set evaluate=False which causes the expression to be not canonicalised:

    In [15]: e1 = parse_expr("x1 - x2*x3")
    
    In [16]: srepr(e1)
    Out[16]: "Add(Symbol('x1'), Mul(Integer(-1), Symbol('x2'), Symbol('x3')))"
    
    In [17]: e2 = parse_expr("x1 - x2*x3", evaluate=False)
    
    In [18]: srepr(e2)
    Out[18]: "Add(Symbol('x1'), Mul(Integer(-1), Mul(Symbol('x2'), Symbol('x3'))))"
    

    Notice the unflattened Mul inside a Mul.

    You have also set expand to False in the Poly constructor which prevents it from canonicalising the unflattened Mul:

    In [22]: Poly(e2, list(e2.free_symbols))
    Out[22]: Poly(-x2*x3 + x1, x2, x1, x3, domain='ZZ')
    
    In [23]: Poly(e2, list(e2.free_symbols), expand=False)
    ...
    PolynomialError: x2*x3 contains an element of the set of generators.
    

    To create the Poly something needs to canonicalise the expression so you cannot have both evaluate=False and expand=False (I have no idea why you would want to combine these options).