为什么我们在这个程序中使用枚举?

时间:2017-03-14 13:35:40

标签: python enumerate

我有一个叫做数值方法的课程,在那里我们学习如何为物理学中的某些问题编写程序。我们必须编写4个可以解决ODE的程序(隐式/显式euler,速度 - verlet,隐式中点规则),现在我们必须使用| y_N - y(T)|来计算误差。我们已经有了一个我们需要填写的模板。 这是我们必须完成的代码。

def ex2_d():
T = 0.2
y0 = np.array([0.3, 0.0])

all_methods = [explicit_euler, implicit_euler, implicit_mid_point, velocity_verlet]
all_rhs = 3*[pendulum_rhs] + [pendulum_verlet_rhs]
resolutions = 2**np.arange(4, 11)

_, y_exact = ode45(pendulum_rhs, (0.0, T), y0, reltol=1e-12)

for method, rhs in zip(all_methods, all_rhs):
    error = np.empty(resolutions.size)
    for k, N in enumerate(resolutions):
        # TODO: Berechen Sie die Lösung und den Fehler
        error[k] = np.absolute(methode())

    rate = convergence_rate(error, resolutions)
    print(method)
    print("rate: " + str(rate) + "\n")

我唯一需要填写的是TODO部分。但是我不明白,for循环,它以枚举(分辨率)循环遍历k和N,为什么分辨率数组被声明为无论如何?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

在数值求解ODE时,您希望使用标准方法获得加倍分辨率(将步长减半),以找到收敛速度:

(u_h - u_(h/2))/(u_(h/2) - u_(h/4)) = 2^p + O(h)

u_h步骤h的数值解,u_(h/2)步骤h/2(例如双倍分辨率)和u_(h/4)解决方案步骤h/4(例如,再次双倍分辨率)。错误的顺序为p,其收敛率为h^p

这就是分辨率被声明为2**np.arange(4,11), which gives [16,32,64,128,256,512,1024]的原因。 (您可以使用其他网格尺寸,这将相应地更改公式。有关详细信息,请参阅this

要将错误存储在列表中,您需要相应的分辨率索引,这就是使用enumerate的原因:

enumerate(resolutions) -> [(0,16), (1,32), (2,64), (3,128), (4,256), (5,512), (6,1024)]

由for循环解压缩:

iteration    k    N
1            0    16
2            1    32

答案 1 :(得分:0)

这个练习的目的是比较解决pendulum_rhs给出的微分方程的不同方法。

比较发生的数量是收敛率。为了确定这个速率,您需要使用变化的分辨率(底层网格)来解决DE并计算每个分辨率的误差。

使用的决议是:resolutions =[16, 32, 64, ...]

因此,对于给定的方法method,您将迭代分辨率:

for k in range(len(resolutions)):
    N = resolutions[k]
    # calculate the result using N
    result = method(..., N, ...)
    #store it in an array called 
    error[k] = np.abs(y_exact - result)