如何解决仅适用于实数的 Lambdifying Sympy 函数
为了性能,我试图将三次方程的输出转换为 sympy 之外的函数。
import sympy as sp
u,x,y = sp.symbols('u x y')
eq = - y - sp.Integral(x**2,(x,1,u))
solved = sp.solveset(eq.doit(),u,domain=sp.S.Reals)
lam = sp.lambdify(y,sp.solveset(eq.doit(),domain=sp.S.Reals))
将任意数字放入 lam
抛出
NameError: name 'Intersection' is not defined
,即使在专门导入 Intersection
时也是如此。
这似乎有点多,考虑到开销,我不希望这能工作,但是有没有办法让这个输出,用 y
作为输入,作为一个外部函数,我不需要依靠 sympy 来进行计算吗?我尝试将值列表作为 Matrix
对象输入,但这使得输出更加复杂,而且似乎在任何地方都没有正确答案。
解决方法
运行您的代码并回答我的问题:
In [21]:
...: u,x,y = symbols('u x y')
...:
...: eq = - y - Integral(x**2,(x,1,u))
...:
...: solved = solveset(eq.doit(),u,domain=S.Reals)
...:
...: lam = lambdify(y,solveset(eq.doit(),domain=S.Reals))
In [22]: solved
Out[22]:
⎧3 ___________ ⎫
ℝ ∩ ⎨╲╱ │3⋅y - 1│ ⋅sign(1 - 3⋅y)⎬
⎩ ⎭
In [23]: print(lam.__doc__)
Created with lambdify. Signature:
func(y)
Expression:
Intersection(FiniteSet(Abs(3*y - 1)**(1/3)*sign(1 - 3*y)),Reals)
Source code:
def _lambdifygenerated(y):
return ( # Not supported in Python with SciPy:
# FiniteSet
Intersection(FiniteSet(Abs(3*y - 1)**(1/3)*sign(1 - 3*y)),Reals))
numpy/scipy
没有任何实现 Intersection
或 FiniteSet
的函数。 sympy
无法翻译这些函数。
===
随着你的改变:
In [25]: ed=eq.doit()
In [26]: ed
Out[26]:
3
u 1
- ── - y + ─
3 3
In [27]:
In [27]: lam = lambdify(y,ed)
In [28]: print(lam.__doc__)
Created with lambdify. Signature:
func(y)
Expression:
-u**3/3 - y + 1/3
Source code:
def _lambdifygenerated(y):
return (-1/3*u**3 - y + 1/3)
Imported modules:
In [29]: vals = lam(np.arange(10))
In [30]: vals
Out[30]:
array([0.333333333333333 - 0.333333333333333*u**3,-0.333333333333333*u**3 - 0.666666666666667,-0.333333333333333*u**3 - 1.66666666666667,-0.333333333333333*u**3 - 2.66666666666667,-0.333333333333333*u**3 - 3.66666666666667,-0.333333333333333*u**3 - 4.66666666666667,-0.333333333333333*u**3 - 5.66666666666667,-0.333333333333333*u**3 - 6.66666666666667,-0.333333333333333*u**3 - 7.66666666666667,-0.333333333333333*u**3 - 8.66666666666667],dtype=object)
,
因此,我无法将整个事物放入外部函数中,但通过将其分解为两个独立的位,使其可在更大范围内使用,我能够显着提高速度:
ed = eq.doit()
lam = sp.lambdify(y,ed)
vals = lam(np.arange(5000)).tolist()
output = [float(sp.solveset(i,domain=sp.S.Reals).args[0]) for i in vals]
这最终比下面的替代方案提高了 2 倍
longtime = [sp.solveset(ed,domain=sp.S.Reals).subs(y,i) for i in np.arange(5000).tolist()]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。