Non-commutative sympify (or simplify)

前端 未结 2 1506
故里飘歌
故里飘歌 2021-02-06 15:40

I would like to be able to simplify mathematical expressions from a string in Python. There are several \"commutative\" ways of doing it. Is there a non-commutative function f

2条回答
  •  说谎
    说谎 (楼主)
    2021-02-06 16:12

    You still need to tell Sympy that there are constraints on the symbols x and y. To do this, still create Symbol instances for them, and then just pass those parameters in as locals to sympify:

    In [120]: x = sympy.Symbol('x', commutative=False)
    
    In [121]: y = sympy.Symbol('y', commutative=False)
    
    In [122]: sympy.sympify('3*x*y - y*x - 2*x*y', locals={'x':x, 'y':y})
    Out[122]: x*y - y*x
    

    To do it programmatically, SymPy provides some nice parsing tools for extracting symbols from a string expression. The key idea is that you have to suppress evaluation since normal evaluation will make commutativity assumptions that ruin your ability to extract what you need:

    In [155]: s = sympy.parsing.sympy_parser.parse_expr('3*x*y - y*x - 2*x*y', evaluate=False)
    
    In [156]: s.atoms(sympy.Symbol)
    Out[156]: {x, y}
    

    It does not appear that there is a direct way to mutate the assumption state of an already-created Symbol, which is unfortunate. But you can iterate through these symbols, and make a new collection of symbols with the same names and the non-commutative assumption, and use that for locals in sympify.

    def non_commutative_sympify(expr_string):
        parsed_expr = sympy.parsing.sympy_parser.parse_expr(
            expr_string, 
            evaluate=False
        )
    
        new_locals = {sym.name:sympy.Symbol(sym.name, commutative=False)
                      for sym in parsed_expr.atoms(sympy.Symbol)}
    
        return sympy.sympify(expr_string, locals=new_locals)
    

    Which gives, e.g.:

    In [184]: non_commutative_sympify('3*x*y - y*x - 2*x*y')
    Out[184]: x*y - y*x
    
    In [185]: non_commutative_sympify('x*y*z - y*z*x - 2*x*y*z + z*y*x')
    Out[185]: -x*y*z - y*z*x + z*y*x
    

提交回复
热议问题