2020-12-17

复杂数学系统 Seminar 8 的解释说明:


 首先我们附上源代码:

import matplotlib.pyplot as plt
import numpy as np


def seminar8(scenario=1):
    # seminar8 Exploration of integration methods
    # Here we compare four integration schemes: euler, RK2, midpoint quadrature
    # and RK4.
    # 比较四种积分方案:欧拉、RK2、中点求积、RK4

    if scenario == 1:
        myfunc = lambda x, t: f1(x, t)
        tmax = 400  # why???
        h = 2  # 0.1  1  2
        t = np.arange(0, tmax + h, h)
        x = np.zeros((len(t), 1))  # pre-allocate x, x0=0 预先分配
        x[0] = 0
    else:
        myfunc = lambda x, t: f2(x, t)
        tmax = 10  # why???
        h = 2  # h = 0.1  1  2
        t = np.arange(0, tmax + h, h)
        x = np.zeros((len(t), 1))  # pre-allocate x, x0=0;
        x[0] = 0.5

    # Euler integration 欧拉积分
    for i in np.arange(len(t) - 1):
        x[i + 1] = x[i] + h * myfunc(x[i], t[i])

    # Plot result
    plt.figure()
    plt.plot(t, x, 'k-')

    # Now use RK2 integration
    for i in np.arange(len(t) - 1):
        xmidpoint = x[i] + h / 2. * myfunc(x[i], t[i])  # why we use a float here?and
        x[i + 1] = x[i] + h * myfunc(xmidpoint, t[i] + h / 2.)
    plt.plot(t, x, 'b-')

    # Now use mid-point quadrature formula, that is:
    # x(t+h)=x(t)+h/2 f(x(t),t) +h/2 f(x(t+h/2),t+h/2)
    for i in np.arange(len(t) - 1):
        xmidpoint = x[i] + h / 2. * myfunc(x[i], t[i])
        x[i + 1] = x[i] + h / 2. * myfunc(x[i], t[i] + h / 2) + h / 2. * myfunc(xmidpoint, t[i] + h / 2.)
    plt.plot(t, x, 'r-')

    # Now use RK4 integration
    for i in np.arange(len(t) - 1):
        k1 = h * myfunc(x[i], t[i])
        k2 = h * myfunc(x[i] + k1 / 2., t[i] + h / 2.)
        k3 = h * myfunc(x[i] + k2 / 2., t[i] + h / 2.)
        k4 = h * myfunc(x[i] + k3, t[i] + h)
        x[i + 1] = x[i] + (k1 + 2. * k2 + 2. * k3 + k4) / 6.
    plt.plot(t, x, 'g-')

    if scenario == 2:  # Here analytical solution is possible write it in the plot instruction!
        # 解析写到清洁说明里面
        plt.plot(t, (t + 1) ** 2 - 0.5 * np.exp(t), 'k.')  # ???

    plt.show()


# Function 1: exponential decay + periodic input (which stops after t=200)
# 函数1:指数衰减+周期性输入(t=200后停止)
def f1(x, t):
    tau = 10
    period = 30
    k = 1
    if t < 200:
        dxdt = -1. / tau * x + np.sin(2 * np.pi * t / period);
    else:
        dxdt = -1. / (k * tau) * x;
    return dxdt


# Some function! 
def f2(x, t):
    dxdt = x - t ** 2 + 1
    return dxdt


if __name__ == "__main__":
    seminar8(1)

 

第一个场景使用函数1,它大致对应于一个由周期性输入供电的CTRNN神经元。周期输入的频率可以通过修改。指数衰减的强度可以通过修改。在时间200处,周期性输入停止,并且可以使用进一步调谐衰变速度。

第二个场景使用函数2。这个函数可以解析积分。考虑了四种积分格式:Euler,Runge-Kutta二阶,中点求积,Runge-Kutta四阶

我们先来研究函数1:

先将main()函数中的入口seminar8()的参数填写为1:

分别取不同的h值(0.1、1、2)来进行函数运算,导出结果和曲线图:

 

2020-12-17
h=0.1时   f(1)的函数图像

 

2020-12-17
h=1时   f(1)的函数图像

 

 

 

2020-12-17
h=2时   f(1)的函数图像

 

综上:指数衰减+周期性输入(t=200之后开始停止)可以看到随着h的值不断增长,可以方法之间的偏差也越来越大,当h=2时,四种方法之间的偏差已经非常明显。在准确性方面,RK4应该是最优秀的。

现在我们再来继续研究函数2:

此时只需要将最后一行代码的输入改成2,即可。

我们分别对h取0.1、1、2,运行代码,绘出图像:

 

2020-12-17
h=0.1时   f(2)的函数图像
2020-12-17
h=1时   f(2)的函数图像
2020-12-17
h=2时   f(2)的函数图像

 

综上:可以看到随着h的值不断增长,各种方法之间的偏差也越来越大。当很轴向右取到5时,各个曲线之间开发发生分离。但无论是那一种h值情况下,均是RK4方法

的变化率最大,可见其优越性。

总结:函数2的阶数更高,即scenario2更为复杂,所以RK4与其他方法的偏差就会越大。

h的值取得越大,那么在固定长度的区间上所取的点就会越多,步长也就越小。有利于数值的准确度。当h很小时,步长变大,就会导致函数在区间内的数值变化很快,出现很大的误差。

上一篇:python装饰器


下一篇:Python3标准库:functools管理函数的工具