如何将 sympy codegen 与包含已实现函数的表达式一起使用

Pet*_*erE 5 python sympy codegen

我正在尝试编译一个包含 UndefinedFunction 的表达式,该函数提供了一个实现。(或者:包含符号的表达式,表示对外部数值函数的调用)

有没有办法做到这一点?使用 autowrap 或 codegen 或者对生成的文件进行一些手动编辑?

以下简单的示例不起作用:

import sympy as sp
import numpy as np
from sympy.abc import *
from sympy.utilities.lambdify import implemented_function
from sympy.utilities.autowrap import autowrap, ufuncify

def g_implementation(a):
    """represents some numerical function"""
    return a*5

# sympy wrapper around the above function
g = implemented_function('g', g_implementation)

# some random expression using the above function
e = (x+g(a))**2+100

# try to compile said expression
f = autowrap(e, backend='cython')
# fails with "undefined reference to `g'"
Run Code Online (Sandbox Code Playgroud)

编辑:

我有几个大的 Sympy 表达式

表达式是自动生成的(通过微分等)

这些表达式包含一些“已实现的未定义函数”,它们调用一些数值函数(即 NOT Sympy 表达式)

必须评估某些输入的表达式的最终脚本/程序将经常被调用。这意味着在 Sympy 中评估表达式(通过 evalf)绝对是不可行的。即使及时编译(lambdify、autowrap、ufuncify、numba.jit)也会产生过多的开销。

基本上,我想为这些表达式创建一个二进制 python 扩展,而不必在 C 中手动实现它们,我认为这太容易出错。

操作系统是Windows 7 64位

小智 0

好吧,我希望这可以解决问题,如果不让我知道,我会再试一次。

\n\n

我将表达式的编译版本Cython与using 进行比较lambdified

\n\n
from sympy.utilities.autowrap import autowrap\nfrom sympy import symbols, lambdify\n\ndef wraping(expression):\n    return autowrap(expression, backend='cython')\n\ndef lamFunc(expression, x, y):\n    return lambdify([x,y], expr)\n\nx, y = symbols('x y')\nexpr = ((x - y)**(25)).expand()\nprint expr\n\n\nbinary_callable = wraping(expr)\nprint binary_callable(1, 2)\n\nlamb = lamFunc(expr, x, y)\nprint lamb(1,2)\n
Run Code Online (Sandbox Code Playgroud)\n\n

其输出:

\n\n
x**25 - 25*x**24*y + 300*x**23*y**2 - 2300*x**22*y**3 + 12650*x**21*y**4 - 53130*x**20*y**5 + 177100*x**19*y**6 - 480700*x**18*y**7 + 1081575*x**17*y**8 - 2042975*x**16*y**9 + 3268760*x**15*y**10 - 4457400*x**14*y**11 + 5200300*x**13*y**12 - 5200300*x**12*y**13 + 4457400*x**11*y**14 - 3268760*x**10*y**15 + 2042975*x**9*y**16 - 1081575*x**8*y**17 + 480700*x**7*y**18 - 177100*x**6*y**19 + 53130*x**5*y**20 - 12650*x**4*y**21 + 2300*x**3*y**22 - 300*x**2*y**23 + 25*x*y**24 - y**25\n\n-1.0\n-1\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我计算执行时间,自动包装函数的速度会快 10 倍(根据问题,我还观察到因子只有 2 的情况):

\n\n
%timeit binary_callable(12, 21)\n100000 loops, best of 3: 2.87 \xc2\xb5s per loop\n\n%timeit lamb(12, 21)\n100000  loops, best of 3: 28.7 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以这里wraping(expr)包装你的表达式expr并返回一个包装的对象binary_callable。您可以随时使用它进行数值评估。

\n\n

编辑:我已经在 Linux/Ubuntu 和 Windows 操作系统上完成了此操作,两者似乎都工作正常!

\n