如何简化 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)
我一直在进行一些集成工作,即使系统正在运行,它也需要比正常运行时间长得多的时间。
问题是表达式有很多页,即使它们只有 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)