我使用solve_ivp
来求解ODE:
def test_ode(t, y):
dydt = C - y + (y ** 8 / (1 + y ** 8))
return dydt
steady_state = []
for C in np.linspace(0, 1, 1001):
sol = solve_ivp(test_ode, [0, 1e06], [0], method='BDF')
steady_state.append(sol.y[0][-1])
这给了我一个RuntimeWarning
:
ETA: --:--:--/anaconda3/lib/python3.6/site-packages/scipy/integrate/_ivp/bdf.py:418:
RuntimeWarning: divide by zero encountered in power
factors = error_norms ** (-1 / np.arange(order, order + 3))
但更糟糕的是,运行基本上停止了(或至少变得极其缓慢)。用[0]
替换初始值[1e-08]
不能解决问题。我该如何解决?
答案 0 :(得分:1)
您可以使用 NumbaLSODA: https://github.com/Nicholaswogan/NumbaLSODA 。类似于solve_ivp,但是所有的代码都可以编译。所以速度非常快:
from NumbaLSODA import lsoda_sig, lsoda
import numpy as np
import numba as nb
import time
@nb.cfunc(lsoda_sig)
def test_ode(t, y_, dydt, p):
y = y_[0]
C = p[0]
dydt[0] = C - y + (y ** 8 / (1 + y ** 8))
funcptr = test_ode.address
@nb.njit()
def main():
steady_state = np.empty((1001,),np.float64)
CC = np.linspace(0, 1, 1001)
y0 = np.array([0.0])
for i in range(len(CC)):
data = np.array([CC[i]],np.float64)
t_eval = np.array([0.0, 1.0e6])
sol, success = lsoda(funcptr, y0, t_eval, data = data)
steady_state[i] = sol[-1,0]
return steady_state
main()
start = time.time()
steady_state = main()
end = time.time()
print(end-start)
结果是 0.013 秒