resolve_ivp返回不同的odeint结果吗?

时间:2019-05-13 15:23:56

标签: python scipy ode

我正在尝试解决一个简单的ODE,以便了解Scipy的新API。

我为4阶的Runge Kutta编写了一个例程来编写该例程,并使用旧的API odeint对其进行了确认,并且该例程非常漂亮。但是,现在我正尝试解决Solve_ivp,看来这是行不通的。我怎么了?

import numpy as np
from matplotlib import pyplot as plt
from scipy.integrate import solve_ivp, odeint
import time

freq = np.arange(1, 10000, 100)

def g(q, t):
    return -q ** 3 + np.sin(t)


a = 0
b = 10
npoints = 100
h = (b - a) / npoints
t = np.arange(a, b, h)

output1 = np.zeros(t.shape)
x = 0
for i in range(len(t)):
    output1[i] = x
    k1 = h * g(x, t[i])
    k2 = h * g(x + 0.5 * k1, t[i] + 0.5 * h)
    k3 = h * g(x + 0.5 * k2, t[i] + 0.5 * h)
    k4 = h * g(x + k3, t[i] + 0.5 * h)
    x = x + 1 / 6 * (k1 + 2 * k2 + 2 * k3 + k4)


# ---------------Solving using odeint (old API)---------------#

y1_odeint = odeint(g, 0, t)

#---------------Solving using new API-------------#

y2=solve_ivp(g,(a,b),[0],t_eval=t)


# --------------------Representação gráfica--------------------------#
fig = plt.figure()
ax = fig.add_subplot(121)
ax1=fig.add_subplot(122)

ax.plot(t, output1,label="my own")
ax.plot(t,y1_odeint,label="odeint")
ax.plot(y2.t,np.squeeze(y2.y),label="new API")
ax.legend()
ax.set_title("Output")

ax1.plot(t,output1-np.squeeze(y1_odeint),label="|odeint-my own|")
ax1.legend()


plt.tight_layout()
plt.show()

enter image description here enter image description here

1 个答案:

答案 0 :(得分:2)

再看看solve_ivp的文档字符串。它期望g first 参数为t。默认情况下,odeint使用相反的约定。如果您使用的是最新版本的scipy,则可以通过向其指定参数odeint来告诉t第一个参数为tfirst=True