如何简化 SymPy 中冗长的符号表达式

How to simplify lengthy symbolic expressons in SymPy

我一直在进行一些集成工作,即使系统正在运行,它也需要比正常运行时间长得多的时间。

问题是表达式有很多页,即使它们只有 3 个变量,sy.simplify 也会在 4 小时左右后使内核崩溃。

有没有办法让这么长的表达式更紧凑?

编辑:

正在尝试使用 cse 重新创建测试表达式。我真的不能用符号代替最终表达式,等于第一个

sy.var('a:c x')
testexp = sp.log(x)+a*(0.5*x)**2+(b*(0.5*x)**2+b+sp.log(x))/c
r, e = sy.cse(testexp)
FinalFunction = sy.lambdify(r[0:][0]+(a,b,c,x),e[0])
Points = sy.lambdify((a,b,c,x),r[0:][1])
FinalFunction(Points(1,1,1,1),1,1,1,1)

>>>NameError: name 'x1' is not defined

cse(expr) 有时是一种获得更紧凑表示的方法,因为重复的子表达式可以用单个符号替换。 cse returns 重复表达式列表和表达式列表(如果只传递单个表达式,则为单例):

>>> from sympy import solve
>>> var('a:c x');solve(a*x**2+b*x+c, x)
(a, b, c, x)
[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]
>>> r, e = cse(_)
>>> for i in r: pprint(Eq(*i))
...
        _____________
       ╱           2
x₀ = ╲╱  -4⋅a⋅c + b
      1
x₁ = ───
     2⋅a
>>> for i in e: pprint(i)
...
x₁⋅(-b + x₀)
-x₁⋅(b + x₀)

你仍然会有很长的表达式,但如果 cse 能够识别重复的子表达式,它们将被更紧凑地表示(并且更有效地进行计算)。

要在 SymPy 中使用它,您可以创建两个 Lambda:一个将变量转换为替换值,另一个使用这些值:

>>> v = (a,b,c,x)
>>> Pts = Lambda(v, tuple([i[1] for i in r]+list(v)))
>>> Pts(1,2,3,4)
(2*sqrt(2)*I, 1/2, 1, 2, 3, 4)
>>> Func = Lambda(tuple([i[0] for i in r]+list(v)), tuple(e))
>>> Func(*Pts(1,2,3,4))
(-1 + sqrt(2)*I, -1 - sqrt(2)*I)