在 numpy 中表示一阶微分方程
Represent a first order differential equation in numpy
我有一个方程 dy/dx = x + y/5
和一个初始值 y(0) = -3
。
我想知道如何使用 pyplot 绘制此函数的精确图形。
我还有一个 x = np.linspace(0, interval, steps+1)
,我想将其用作 x 轴。所以我只寻找 y 轴值。
提前致谢。
鉴于您需要解决d.e。你可能更喜欢用代数的方式来做这件事,有同情心。 (或者你可能不会。)
导入模块并定义函数和因变量。
>>> from sympy import *
>>> f = Function('f')
>>> var('x')
x
调用求解器。注意所有的条款d.e。必须转置到等号左侧,并且 y 必须替换为函数的指示符。
>>> dsolve(Derivative(f(x),x)-x-f(x)/5)
Eq(f(x), (C1 + 5*(-x - 5)*exp(-x/5))*exp(x/5))
如您所料,解是根据任意常数给出的。我们必须使用初始值来解决这个问题。我们将其定义为一个 sympy 变量。
>>> var('C1')
C1
现在我们创建一个表达式来表示这个任意常数作为我们可以求解的方程的左边。我们将 f(0) 替换为其在初始条件下的值。然后我们在该条件下代入 x 的值,得到 C1.
中的方程
>>> expr = -3 - ( (C1 + 5*(-x - 5)*exp(-x/5))*exp(x/5) )
>>> expr.subs(x,0)
-C1 + 22
也就是说C1=22,最后我们可以利用这个值求出微分方程的特解
>>> ((C1 + 5*(-x - 5)*exp(-x/5))*exp(x/5)).subs(C1,22)
((-5*x - 25)*exp(-x/5) + 22)*exp(x/5)
因为我心不在焉并且一直害怕犯严重错误,所以我检查这个函数是否满足初始条件。
>>> (((-5*x - 25)*exp(-x/5) + 22)*exp(x/5)).subs(x,0)
-3
(一般都是忘记检查才出错,这就是生活。)
我也可以在 sympy 中绘制它。
>>> plot(((-5*x - 25)*exp(-x/5) + 22)*exp(x/5),(x,-1,5))
<sympy.plotting.plot.Plot object at 0x0000000008C2F780>
为了完整起见,使用 scipy.integrate.odeint
可以很容易地对这种方程进行数值积分。
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# function dy/dx = x + y/5.
func = lambda y,x : x + y/5.
# Initial condition
y0 = -3 # at x=0
# values at which to compute the solution (needs to start at x=0)
x = np.linspace(0, 4, 101)
# solution
y = odeint(func, y0, x)
# plot the solution, note that y is a column vector
plt.plot(x, y[:,0])
plt.xlabel('x')
plt.ylabel('y')
plt.show()
我有一个方程 dy/dx = x + y/5
和一个初始值 y(0) = -3
。
我想知道如何使用 pyplot 绘制此函数的精确图形。
我还有一个 x = np.linspace(0, interval, steps+1)
,我想将其用作 x 轴。所以我只寻找 y 轴值。
提前致谢。
鉴于您需要解决d.e。你可能更喜欢用代数的方式来做这件事,有同情心。 (或者你可能不会。)
导入模块并定义函数和因变量。
>>> from sympy import *
>>> f = Function('f')
>>> var('x')
x
调用求解器。注意所有的条款d.e。必须转置到等号左侧,并且 y 必须替换为函数的指示符。
>>> dsolve(Derivative(f(x),x)-x-f(x)/5)
Eq(f(x), (C1 + 5*(-x - 5)*exp(-x/5))*exp(x/5))
如您所料,解是根据任意常数给出的。我们必须使用初始值来解决这个问题。我们将其定义为一个 sympy 变量。
>>> var('C1')
C1
现在我们创建一个表达式来表示这个任意常数作为我们可以求解的方程的左边。我们将 f(0) 替换为其在初始条件下的值。然后我们在该条件下代入 x 的值,得到 C1.
中的方程>>> expr = -3 - ( (C1 + 5*(-x - 5)*exp(-x/5))*exp(x/5) )
>>> expr.subs(x,0)
-C1 + 22
也就是说C1=22,最后我们可以利用这个值求出微分方程的特解
>>> ((C1 + 5*(-x - 5)*exp(-x/5))*exp(x/5)).subs(C1,22)
((-5*x - 25)*exp(-x/5) + 22)*exp(x/5)
因为我心不在焉并且一直害怕犯严重错误,所以我检查这个函数是否满足初始条件。
>>> (((-5*x - 25)*exp(-x/5) + 22)*exp(x/5)).subs(x,0)
-3
(一般都是忘记检查才出错,这就是生活。)
我也可以在 sympy 中绘制它。
>>> plot(((-5*x - 25)*exp(-x/5) + 22)*exp(x/5),(x,-1,5))
<sympy.plotting.plot.Plot object at 0x0000000008C2F780>
为了完整起见,使用 scipy.integrate.odeint
可以很容易地对这种方程进行数值积分。
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# function dy/dx = x + y/5.
func = lambda y,x : x + y/5.
# Initial condition
y0 = -3 # at x=0
# values at which to compute the solution (needs to start at x=0)
x = np.linspace(0, 4, 101)
# solution
y = odeint(func, y0, x)
# plot the solution, note that y is a column vector
plt.plot(x, y[:,0])
plt.xlabel('x')
plt.ylabel('y')
plt.show()