回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我试图用数值方法求解一个允许离散跳跃的颂歌。我使用的是Euler方法,希望Numba的jit可以帮助我加快这个过程(现在脚本需要运行300秒,我需要它运行200次)。在</p>
<p>以下是我的第一次简化尝试:</p>
<pre><code>import numpy as np
from numba import jit
dt = 1e-5
T = 1
x0 = 1
noiter = int(T / dt)
res = np.zeros(noiter)
def fdot(x, t):
return -x + t / (x + 1) ** 2
def solve_my_ODE(res, fdot, x0, T, dt):
res[0] = x0
noiter = int(T / dt)
for i in range(noiter - 1):
res[i + 1] = res[i] + dt * fdot(res[i], i * dt)
if res[i + 1] >= 2:
res[i + 1] -= 2
return res
%timeit fdot(x0, T)
%timeit solve_my_ODE(res, fdot, x0, T, dt)
->The slowest run took 8.38 times longer than the fastest. This could mean that an intermediate result is being cached
->1000000 loops, best of 3: 465 ns per loop
->10 loops, best of 3: 122 ms per loop
@jit(nopython=True)
def fdot(x, t):
return -x + t / (x + 1) ** 2
%timeit fdot(x0, T)
%timeit solve_my_ODE(res, fdot, x0, T, dt)
->The slowest run took 106695.67 times longer than the fastest. This could mean that an intermediate result is being cached
->1000000 loops, best of 3: 240 ns per loop
->10 loops, best of 3: 99.3 ms per loop
@jit(nopython=True)
def solve_my_ODE(res, fdot, x0, T, dt):
res[0] = x0
noiter = int(T / dt)
for i in range(noiter - 1):
res[i + 1] = res[i] + dt * fdot(res[i], i * dt)
if res[i + 1] >= 2:
res[i + 1] -= 2
return res
%timeit fdot(x0, T)
%timeit solve_my_ODE(res, fdot, x0, T, dt)
->The slowest run took 10.21 times longer than the fastest. This could mean that an intermediate result is being cached
->1000000 loops, best of 3: 274 ns per loop
->TypingError Traceback (most recent call last)
ipython-input-10-27199e82c72c> in <module>()
1 get_ipython().magic('timeit fdot(x0, T)')
----> 2 get_ipython().magic('timeit solve_my_ODE(res, fdot, x0, T, dt)')
(...)
TypingError: Failed at nopython (nopython frontend)
Undeclared pyobject(float64, float64)
File "<ipython-input-9-112bd04325a4>", line 6
</code></pre>
<p>我不明白我为什么会犯这个错误。我怀疑numba不能识别输入字段fdot(这是一个python函数,btw已经用numba编译过了)。在</p>
<p>因为我对麻巴这么陌生,我有几个问题要问</p>
<ul>
<li>我该怎么做才能让Numba理解输入字段fdot是一个函数?在</li>
<li>在函数fdot“only”上使用JIT会导致减少50%。我应该期待更多吗?或者这正常吗?在</li>
<li>这个脚本看起来像是模拟带有离散跳转的ODE的合理方法吗?从数学上讲,这相当于用delta函数求解ODE。在</li>
</ul>
<p>Numba版本是0.17</p>