【问题标题】:Python odeint with array in differential equationPython odeint 与微分方程中的数组
【发布时间】:2020-06-12 15:53:45
【问题描述】:

我有下一个一阶微分方程(示例):

dn/dt=A*n; n(0)=28

当 A 为常数时,用 python odeint 完美解决。 但是我有一个来自 .txt 文件的不同 A 值的数组 [不是函数,只是一个值数组]

A = [0.1,0.2,0.3,-0.4,0.7,...,0.0028]

而且我希望在求解 ode A 的每次迭代(或每个时刻 t)中是数组中的一个新值。 我的意思是: 第一次迭代(或 t=0) - A=0.1 第二次迭代(或 t=1) - 数组中的 A=0.2 等。

如何使用 python odeint 做到这一点?

【问题讨论】:

    标签: python ode odeint


    【解决方案1】:

    是的,你可以这样做,但不能直接在odeint 中,因为它没有事件机制,而你提出的需要一个事件-动作机制。

    但是您可以将问题分成多个步骤,在每个步骤中使用odeint 和现在的常量A 参数,然后最后加入这些步骤。

    T = [[0]]
    N = [[n0]]
    for k in range(len(A)):
        t = np.linspan(k,k+1,11);
        n = odeint(lambda u,t: A[k]*u, [n0],t)
        n0 = n[-1]
        T.append(t[1:])
        N.append(n[1:])
    
    T = np.concatenate(T)
    N = np.concatenate(N)
    

    如果您对低效率感到满意,无论是在 ODE 的评估上还是在内部步数上,您也可以将参数实现为分段常数函数。

    tA = np.arange(len(A));
    A_func = interp1d(tA, A, kind="zero", fill_value="extrapolate")
    T = np.linspace(0,len(A)+1, 10*len(A)+11);
    N = odeint(lambda u,t: A_func(t)*u, [n0], T)
    

    内部步长控制器的工作假设 ODE 函数可以很好地微分到 5 阶或更高阶。然后通过步进误差计算中固有的隐式数值微分将跳跃视为高度振荡的事件,需要非常小的步长。代码内部有一些缓解措施,通常允许求解器最终跨过这种跳转,但与上面的第一个变体相比,它需要更多的内部步骤,因此需要更多的函数评估。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-28
      • 2019-07-15
      • 2015-12-13
      • 2015-03-05
      • 2018-02-08
      • 1970-01-01
      • 2017-11-18
      • 2017-10-06
      相关资源
      最近更新 更多