简体   繁体   English

如何在Python中绘制耦合的非线性二阶ODE的二阶导数?

[英]How to graph the second derivatives of coupled non-linear second order ODEs in Python?

I am very new to Python and have written this code to model the motion of a spring pendulum: 我是Python的新手,并编写了以下代码来模拟弹簧摆的运动:

import numpy as np
from scipy.integrate import odeint
from numpy import sin, cos, pi, array
import matplotlib.pyplot as plt

init = array([0,pi/18,0,0]) 

def deriv(z, t):
    x, y, dxdt, dydt = z
    dx2dt2=(4+x)*(dydt)**2-5*x+9.81*cos(y)
    dy2dt2=(-9.81*sin(y)-2*(dxdt)*(dydt))/(0.4+x)

    return np.array([dxdt, dydt, dx2dt2, dy2dt2])

time = np.linspace(0.0,10.0,1000)
sol = odeint(deriv,init,time)

plt.xlabel("time")
plt.ylabel("y")
plt.plot(time, sol)
plt.show()

But it gives me the graphs of x , dxdt , y and dydt instead of dx2dt2 and dy2dt2 (which are the second derivatives of x and y respectively). 但这给了我xdxdtydydt的图,而不是dx2dt2dy2dt2 (分别是xy的二阶导数)。 How do I alter my code to graph the second derivatives instead? 如何更改代码以绘制二阶导数?

The return value of odeint is the solution to z(t) which you have defined to be z = [x,y,x',y'] . odeint的返回值是z(t) ,您已将其定义为z = [x,y,x',y'] Therefore the second derivative is not a part of the solution returned by odeint . 因此,二阶导数不是odeint返回的解决方案的odeint You can approximate the second derivative of x and y by taking finite differences of the returned values of the first derivatives. 您可以通过对一阶导数的返回值进行有限差分来近似xy的二阶导数。

For example: 例如:

import numpy as np
from scipy.integrate import odeint
from numpy import sin, cos, pi, array
import matplotlib.pyplot as plt

init = array([0,pi/18,0,0]) 

def deriv(z, t):
    x, y, dxdt, dydt = z
    dx2dt2=(4+x)*(dydt)**2-5*x+9.81*cos(y)
    dy2dt2=(-9.81*sin(y)-2*(dxdt)*(dydt))/(0.4+x)

    return np.array([dxdt, dydt, dx2dt2, dy2dt2])

time = np.linspace(0.0,10.0,1000)
sol = odeint(deriv,init,time)

x, y, xp, yp = sol.T

# compute the approximate second order derivative by computing the finite
# difference between values of the first derivatives
xpp = np.diff(xp)/np.diff(time)
ypp = np.diff(yp)/np.diff(time)

# the second order derivatives are now calculated at the midpoints of the
# initial time array, so we need to compute the midpoints to plot it
xpp_time = (time[1:] + time[:-1])/2

plt.xlabel("time")
plt.ylabel("y")
plt.plot(time, x, label='x')
plt.plot(time, y, label='y')
plt.plot(time, xp, label="x'")
plt.plot(time, yp, label="y'")
plt.plot(xpp_time, xpp, label="x''")
plt.plot(xpp_time, ypp, label="y''")
plt.legend()
plt.show()

Alternatively, since you already have a function to compute the second order derivatives from the solution, you can just call that function: 另外,由于您已经有一个函数可以从解中计算二阶导数,因此您可以调用该函数:

plt.plot(time, deriv(sol.T,time)[2], label="x''")
plt.plot(time, deriv(sol.T,time)[3], label="y''")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM