在lambdify的sympy表达式上使用numba.autojit

3 投票
2 回答
2013 浏览
提问于 2025-04-18 00:54

我以前用过numpy,对它还算比较熟悉,但有时候我想要更快的速度,就会用到numba.autojit这个装饰器,挺简单的。不过现在我在处理一系列sympy表达式时,发现numba(无论是jit还是autojit)对从lambdify出来的函数有点搞不清楚。看起来sympy并没有保持一个固定的参数列表。

我在想,我可以看看sympy.lamdify是怎么工作的,然后自己做一个结合numba的版本,但我想先问问大家。

2 个回答

1

我自己没有用过numba,但我对lambdify比较熟悉,可以告诉你,它不能直接使用。所以如果你有能力自己实现一个将'numba'模块转为lambdify的功能,大家肯定会很感激你在https://github.com/sympy/sympy上提交一个“拉取请求”。

我自己在一个项目中实现了类似lambdify的功能,因为默认的sympy版本太慢了。如果你觉得有帮助,可以看看我的源代码,地址在这里: https://github.com/bjodah/symvarsub/

4

关于你第二个问题,lambdify的工作原理是,它会把表达式转换成一个字符串形式的lambda表达式,然后在一个包含数值函数的命名空间中执行这个字符串。

举个例子,对于 lambdify(x, sin(x), 'numpy')sin(x) 会被转换成 'sin(x)'(这里的字符串形式和普通字符串形式是一样的,但有时可能会不同,比如SymPy和NumPy之间的函数名称差异。负责这个转换的函数是 sympy.printing.lambdarepr.lambdarepr。不过你想用的函数是 sympy.utilities.lambdify.lambdastr,它还会进行下一步处理。

接着,它会把这个字符串加上 lambda,变成 'lambda x: sin(x)'

然后,大致上它会执行

g = {}
exec 'from numpy import *' in g # or exec('from numpy import *', g) in Python 3
l = eval('lambda x: sin(x)', g)

这样 l 就会成为这个lambdify生成的函数。

换句话说,它会在一个 sin 被定义为 numpy.sin 的命名空间中执行 'lambda x: sin(x)'

据我所知,numba.jit 和 numba.autojit 只是翻译字节码,所以它们在lambda表达式上应该也能正常工作。

撰写回答