简体   繁体   English

使用此代码求解二阶微分方程

[英]Solving 2nd order differential equations wrt this code

I cannot write the program which is solving 2nd order differential equation with respect to code I wrote for y'=y 我无法编写针对y'= y编写的求解二阶微分方程的程序

I know that I should write a program which turn a 2nd order differential equation into two ordinary differential equations but I don!t know how can I do in Python. 我知道我应该编写一个程序,将一个二阶微分方程转换为两个常微分方程,但是我不知道该如何在Python中做。

PS : I have to use that code below. PS:我必须在下面使用该代码。 It's a homework 这是一项作业

Please forgive my mistakes, it's my first question. 请原谅我的错误,这是我的第一个问题。 Thanks in advance 提前致谢

from pylab import*
xd=[];y=[]
def F(x,y):
    return y
def rk4(x0,y0,h,N):
    xd.append(x0)
    yd.append(y0)
    for i in range (1,N+1) :
        k1=F(x0,y0)
        k2=F(x0+h/2,y0+h/2*k1)
        k3=F(x0+h/2,y0+h/2*k2)
        k4=F(x0+h,y0+h*k3)
        k=1/6*(k1+2*k2+2*k3+k4)
        y=y0+h*k
        x=x0+h
        yd.append(y)
        xd.append(x)
        y0=y
        x0=x
    return xd,yd
x0=0
y0=1
h=0.1
N=10
x,y=rk4(x0,y0,h,N)
print("x=",x)
print("y=",y)
plot(x,y)
show()

You can basically reformulate any scalar ODE (Ordinary Differential Equation) of order n in Cauchy form into an ODE of order 1. The only thing that you "pay" in this operation is that the second ODE's variables will be vectors instead of scalar functions. 您基本上可以将Cauchy形式的任何n阶的标量ODE(常微分方程)重新格式化为1阶的ODE。您在此操作中“支付”的唯一事情是第二个ODE的变量将是向量而不是标量函数。

Let me give you an example with an ODE of order 2. Suppose your ODE is: y'' = F(x,y, y'). 让我给您一个ODE为2的示例。假设您的ODE为:y''= F(x,y,y')。 Then you can replace it by [y, y']' = [y', F(x,y,y')], where the derivative of a vector has to be understood component-wise. 然后,您可以将其替换为[y,y']'= [y',F(x,y,y')],在这种情况下,必须对向量的导数进行逐项理解。

Let's take back your code and instead of using Runge-Kutta of order 4 as an approximate solution of your ODE, we will apply a simple Euler scheme. 让我们取回代码,而不是使用4阶的Runge-Kutta作为ODE的近似解决方案,我们将应用一个简单的Euler方案。

from pylab import*
import matplotlib.pyplot as plt

# we are approximating the solution of y' = f(x,y) for x in [x_0, x_1] satisfying the Cauchy condition y(x_0) = y0

def f(x, y0):
    return y0

# here f defines the equation y' = y

def explicit_euler(x0, x1, y0, N,):
    # The following formula relates h and N
    h = (x1 - x0)/(N+1)

    xd = list()
    yd = list()

    xd.append(x0)
    yd.append(y0)

    for i in range (1,N+1) :
        # We use the explicite Euler scheme y_{i+1} = y_i + h * f(x_i, y_i)
        y = yd[-1] + h * f(xd[-1], yd[-1])
        # you can replace the above scheme by any other (R-K 4 for example !)
        x = xd[-1] + h

        yd.append(y)
        xd.append(x)

    return xd, yd

N = 250
x1 = 5
x0 = 0
y0 = 1
# the only function which satisfies y(0) = 1 and y'=y is y(x)=exp(x).
xd, yd =explicit_euler(x0, x1, y0, N)
plt.plot(xd,yd)
plt.show()
# this plot has the right shape !

看起来像一个不错的指数函数!

Note that you can replace the Euler scheme by RK 4 which has better stability and convergence properties. 请注意,您可以用具有更好的稳定性和收敛性的RK 4代替Euler方案。

Now, suppose that you want to solve a second order ODE, let's say for example: y'' = -y with initial conditions y(0) = 1 and y'(0) = 0. Then you have to transform your scalar function y into a vector of size 2 as explained above and in the comments in code below. 现在,假设您要求解二阶ODE,例如:y''= -y,初始条件为y(0)= 1且y'(0)=0。然后,您必须转换标量函数将y转换为大小为2的向量,如上所述,并在下面的代码注释中。

from pylab import*
import matplotlib.pyplot as plt
import numpy as np

# we are approximating the solution of y'' = f(x,y,y') for x in [x_0, x_1] satisfying the Cauchy condition of order 2:
# y(x_0) = y0 and y'(x_0) = y1

def f(x, y_d_0, y_d_1):
    return -y_d_0

# here f defines the equation y'' = -y

def explicit_euler(x0, x1, y0, y1, N,):
    # The following formula relates h and N
    h = (x1 - x0)/(N+1)

    xd = list()
    yd = list()

    xd.append(x0)
    # to allow group operations in R^2, we use the numpy library
    yd.append(np.array([y0, y1]))

    for i in range (1,N+1) :
        # We use the explicite Euler scheme y_{i+1} = y_i + h * f(x_i, y_i)
        # remember that now, yd is a list of vectors

        # the equivalent order 1 equation is [y, y']' = [y', f(x,y,y')]
        y = yd[-1] + h * np.array([yd[-1][1], f(xd[-1], yd[-1][0], yd[-1][1])])  # vector of dimension 2
        print(y)
        # you can replace the above scheme by any other (R-K 4 for example !)

        x = xd[-1] + h  # vector of dimension 1

        yd.append(y)
        xd.append(x)

    return xd, yd

x0 = 0
x1 = 30
y0 = 1
y1 = 0

# the only function satisfying y(0) = 1, y'(0) = 0 and y'' = -y is y(x) = cos(x)
N = 5000
xd, yd =explicit_euler(x0, x1, y0, y1, N)
# I only want the first variable of yd
yd_1 = list(map(lambda y: y[0], yd))

plt.plot(xd,yd_1)
plt.show()

看起来像一个很好的余弦函数!

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

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