【问题标题】:Second order differential numerically with python用python进行数值二阶微分
【发布时间】:2018-10-19 08:47:37
【问题描述】:

我想在不使用内置函数的情况下使用Python 计算二阶微分方程,但结果仅对一阶方程是正确的。

让我举个例子(插图没有声誉!- 更好的方程外观)

dy/dt = -ky

并使用导数的基本定义

f'(x)= h ->0 (f(x+h)-f(x))/h

我们可以为 k=0.3 这个方程编写基本的 Python 代码

def first_order(dt):
    t = np.arange(0, 20, dt)
    k = 0.3
    y = np.zeros(len(t))

    y[0] = 5
    for i in range(1, len(t)):
        y[i] = - k* y[i - 1] * dt + y[i-1]

    return t, y

这很好用,但是当我尝试计算相应的方程时:

dp^2/dx^2 = (p- p0)/L

使用: f''(x)= h ->0 (f(x+h)-2f(x)+ f(x-h)/h^2

二阶导数方程的初始条件是p(0) = 10^14p0 = 10^13L = 10 ^-6p(infinity) = p0,第二个条件可能会出错。

我尝试以直接的方式解决这个问题 - 类似于以前

def diffusion_lenght(dt):
   p0 = 10 ** 13  # initial state
   t = np.arange(0, 20, dt)
   p = np.zeros(len(t))
   L = 1 * 10 ** -6
   p[0] = 10 ** 14
   p[len(t)-1] = p0

   for i in range(1, len(t)):
      p[i] = (2* p[i-1]- p[i-2]- p0 * dt ** 2 / L) / (1 - dt ** 2 / L)
   print(p)
   return t, p

但结果不正确。它应该给我x 的指数递减,但我得到了收敛到dt 值的直线。

【问题讨论】:

    标签: python numeric equation derivative


    【解决方案1】:

    如果你不介意,我几年前就做过了,我有一个小脚本,所以我会给你我的代码,而不是在你的代码中查找错误。

    我认为它非常清晰明确。

    import numpy as np
    
    class dif_eq(object):
        def __init__(self):
            pass
        def ft4(self,dt,u,x1_before,x2_before,x3_before,x4_before,functionn):
            x1_now = x1_before + dt * x2_before
            x2_now = x2_before + dt * x3_before
            x3_now = x3_before + dt * x4_before
            x4_now = x4_before + dt * functionn(u,x1_before,x2_before,x3_before,x4_before)
            vals = [x1_now,x2_now,x3_now,x4_now]
            return vals
    
        def ft3(self,dt,u,x1_before,x2_before,x3_before,functionn):
            x1_now = x1_before + dt * x2_before
            x2_now = x2_before + dt * x3_before
            x3_now = x3_before + dt*functionn(u,x1_before,x2_before,x3_before)
            vals = [x1_now,x2_now,x3_now]
            return vals
    
        def ft2(self,dt,u,x1_before,x2_before,functionn):
            x1_now = x1_before + dt * x2_before
            x2_now = x2_before+  dt * functionn(u,x1_before,x2_before)
            vals = [x1_now,x2_now]
            return vals
    
        def ft1(self,dt,u,x1_before,functionn):
            x1_now = x1_before + dt*functionn(u,x1_before)
            vals = [x1_now]
            return vals
    

    使用示例:

    """
    def order3equation(u,b,c,a): # Your differential equations
        y=u-b*2-c*2.5-a*3.6 #+ noise*np.random.rand()/5
        return y
    def order1equation.....
        ....
        return y
    
    d=dif_eq()
    val=[0] # init for 1order
    val3=[0,0,0] # init for 3order
    dt=0.05
    result1order=[]
    result3order=[]
    for i in range(100):
        val=d.ft1(dt,u,val[0],order1equation)
        result1order.append(val[0])
    
    for i in range(1000):
        val3=d.ft3(dt,u,val3[0],val3[1],val3[2],order3equation)
        result3order.append(val3[0])
    """
    

    valx/vals 是导数的实际值。第一次传递初始值,然后将函数实际返回的值传递给函数。

    工作示例 - 不稳定的系统

        u = 1 # input/impulse or whatever name it is
        d=dif_eq()
    
        val3=[0,0,0]
        dt=0.05
    
        zz=[]
        def my3(u, b, c, a):
            y = u - b * 1 - c * 1 - a *1
            return y
        for i in range(1000):
            val3=d.ft3(dt,u,val3[0],val3[1],val3[2],my3)
            zz.append(val3[0])
        from matplotlib.pyplot import *
        plot(zz)
        show()
    

    【讨论】:

    • 嗨,我想我清楚地理解了您在课堂上的功能,但是当您定义自己的微分方程时出现问题(在工作示例中)。因此,我尝试应用您的方法来求解上述方程 dy/dt = -ky,其中 k = 0.3。第二个 dp^2/dx^2 = (p- p0)/L 其中 p(0) = 10^14, p0 = 10^13, L = 10 ^-6 和 p(infinity) = p0。我几乎可以肯定你可以应用你的方法来解决我的第一个方程,但第二个方程会是一个问题。因为在你所有的例子中,初始条件都从 0 开始,但在我的等式中,我的条件是无穷大。
    • 两个初始条件都是无限的?顺便说一句,我正在指数级增长。这在某些时候会降低和改变 konvexity。这是正确的解决方案ibb.co/gWjGaf 吗?
    • 在第二个等式中,初始条件为:p[0] = 10^14, p[infinity] = p0。正确答案是: p(x) = p0 + [p[0] - p0]* exp(-x/L) 您的解决方案不正确。输入适当的值:p(x) = 10^13 + [10^14 - 10^13]* e^(-x/10^-6),您可以轻松绘制正确的解决方案并与您的解决方案进行比较。
    • 我不明白 p[infinity]=p0 是什么意思。你不能给未来的dif方程条件
    • 这些“初始”条件具有物理意义。第一个: p[0] = 10^14 告诉您在 x = 0 处,电子/空穴的浓度在样品开始时为 10^14。第二个:p[infinity]=10^13 告诉你在 x = 距离起点很远(我们不知道多远 - 这个方程为我们提供了距离)电子/空穴的浓度将下降到 10^13 .我在枫树中使用这些条件求解这个方程并计算适当的限制,现在我想在 python 中用数字做同样的事情。这里的 L 就是所谓的“扩散长度” - 浓度下降 e
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    相关资源
    最近更新 更多