python-非可交换的表示(或简化)
作者:互联网
我希望能够简化Python中字符串的数学表达式.
有几种“可交换”的方式来做到这一点.
有非交换功能吗?
我知道sympy的sympify可以做一些非交换的工作,这里有一个例子:
from sympy import *
x=Symbol('x',commutative=False)
y=Symbol('y',commutative=False)
print sympify(3*x*y - y*x - 2*x*y)
它将显示xy -yx,但是,如果我们将sympify应用于字符串,即,
print sympify('3*x*y - y*x - 2*x*y')
结果为0.
有没有一种方法可以简化上述字符串以保持x和y的不可交换性?
我发现有人已经在这里http://osdir.com/ml/python-sympy/2012-02/msg00250.html询问了该问题,有人已经回答了http://osdir.com/ml/python-sympy/2012-02/msg00255.html,但是该解决方案似乎总体上不起作用.
我倾向于先问一下,如果没有即时解决方案,我想我必须自己编写代码.
解决方法:
您仍然需要告诉Sympy,符号x和y受到约束.为此,仍然为它们创建Symbol实例,然后只需将这些参数作为本地变量传入即可进行表示:
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
为此,SymPy提供了一些不错的解析工具,用于从字符串表达式中提取符号.关键思想是您必须抑制评估,因为正常评估会做出可交换性假设,从而破坏您提取所需内容的能力:
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}
不幸的是,似乎没有直接的方法可以改变已经创建的符号的假设状态.但是,您可以遍历这些符号,并使用相同的名称和非可交换的假设来创建符号的新集合,并将其用于本地化.
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)
这给出了例如:
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
标签:python-2-7,sympy,mathematical-expressions,commutativity,python 来源: https://codeday.me/bug/20191119/2039205.html