【发布时间】:2021-11-24 02:44:51
【问题描述】:
我正在尝试使用 NumbaLSODA 来优化我的模型,这实质上是在解决初始值 ODE 问题(可能非常僵硬)。我的原始模型基于 scipy/solve_ivp,它工作得非常好,只是有点慢,即使提供了雅可比矩阵。想不出任何其他方法来优化可调用导数函数,所以我开始寻找其他选项,例如 NumbaLSODA。
我实现了 NumbaLSODA,我的衍生函数看起来像这样:
@cfunc(lsoda_sig)
def deriv(t,y,ydot,coeff):
ydot[0] = <very long math expression>
ydot[1] = <very long math expression>
ydot[2] = <very long math expression>
...
其中 coeff 是作为 arg 传递给 deriv() 的数组。数学表达式可能如下所示:
coeff[0]*y[0]*y[1] + coeff[1]*y[2] - coeff[2]*y[3] ...
再次,这很好用,模型比 scipy/solve_ivp 版本快得多,非常有前途!
这里有一个问题。导数函数中的 ydot 数组可能非常长且复杂。因此,在我的基于 scipy/solve_ivp 的模型中,我有另一个 sn-p 来生成字符串列表,编译,然后在导函数中进行 eval。它可能比直接提供 ydot 数组要慢一些,但极大地改善了用户体验。
但是,eval() 函数似乎不适用于基于 NumbaLSODA 的模型:
@cfunc(lsoda_sig)
def deriv(t,y,ydot,coeff):
ydot[0] = eval(<very long math expression>)
ydot[1] = eval(<very long math expression>)
ydot[2] = eval(<very long math expression>)
...
我最终得到以下错误消息:
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'eval': cannot determine Numba type of <class 'builtin_function_or_method'>
我对 numba 并不完全熟悉。我想知道是否有办法让 eval() 工作
我知道某些功能/操作在 numba 中不起作用。如果 eval() 确实是这种情况,有没有办法在导函数中输入代码生成的 ydot 数组?
非常感谢您!
【问题讨论】: