在函数作用域内定义一个未使用的新符号

问题描述 投票:0回答:1

我发现在编写

sympy
代码时很难以可重用的方式真正封装大量逻辑

我想用以下方式编写一个函数:

def compute_integral(fn):
  s = symbols_new() # do not apply lexicographic identity, this symbol identity is unique
  return integrate( fn(s), (s, 0, 1))

如果我只是使用通常的

symbols()
来实例化
s
,我就有可能在定义表达式中的某处使用
fn
相同的符号,例如可能会发生以下情况:

def compute_integral(fn):
  s = symbols("s")
  return integrate(fn(s), (s, 0, 1))

...

import sympy as sp
from sympy.abc import *

t = sp.sin(3 + s)
f = sp.lambdify([x], x**2 + t * s * x)
compute_integral(f) #< ---- symbol s is already present in the function, now the integral will produce the wrong result

我现在为尽量减少这个问题所做的事情并不理想:

compute_integral_local_var = 0

def compute_integral(fn):
  global compute_integral_local_var
  compute_integral_local_var += 1
  s = symbols("local_{}".format(compute_integral_local_var))
  return integrate(fn(s), (s, 0, 1))

我想避免此类冲突,而不必添加特殊的全局变量。有没有更好的方法可以在

sympy
API 中实现这种类型的封装?

python sympy
1个回答
0
投票

我正在使用最新的 sympy,版本 1.13.2,并且您提供的代码块无法运行:它会引发错误。

似乎有一些误解,我想澄清一下。考虑这个代码块:

import sympy as sp
from sympy.abc import s, x

t = sp.sin(3 + s)
print("t:", t)
e = x**2 + t * s * x
print("e:", e)
# t: sin(s + 3)
# e: s*x*sin(s + 3) + x**2

在这里,我创建了两个符号表达式,

t
e
t
包含符号函数
sin
e
t
组成。您可以将
e
视为一个函数,但在 sympy 术语中,
e
是一个符号表达式。

接下来,在您的示例中,您执行了如下操作:

f = sp.lambdify([x], e)

创建一个由 NumPy 计算的数值函数。然后,您尝试对这个数值函数进行符号积分,这是绝对错误的。使用 SymPy,您只能执行符号表达式的符号积分。

如果您尝试执行的只是符号积分,那么此命令就足够了:

sp.integrate(e, (x, 0, 1))
# s*sin(s + 3)/2 + 1/3

如果您想集成同一范围内的多个符号表达式,那么您可以创建自定义函数:

def compute_integral(expr, sym):
    return sp.integrate(expr, (sym, 0, 1))

print(compute_integral(e, x))
# s*sin(s + 3)/2 + 1/3

print(compute_integral(t, x))
# sin(s + 3)
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.