仅对实数进行 Lambdifying Sympy 函数

Lambdifying Sympy function for only real numbers

为了性能,我正在尝试将三次方程的输出转换为 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(), u, 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(), u, 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 没有任何实现 IntersectionFiniteSet 的函数。 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, u, domain=sp.S.Reals).subs(y, i) for i in np.arange(5000).tolist()]