繁体   English   中英

为什么这 2 个 python 列表有不同的 len?

[英]why these 2 python lists have different len's?

我为自适应步长 RungeKutta RK 4 阶积分方法编写了以下代码。

import numpy as np
import os
import matplotlib
from matplotlib import pyplot as plt

rhs_of_diff_Eq_str = "3 * t ** 2"

def first_derivative(t, y): # the first derivative of the function y(t)
    first_derivative_value = 3 * t ** 2
    return first_derivative_value

time_interval_lowerlimit = 0.0
time_interval_upperlimit = 1.0
dt = 0.01
ts = []

y = 0. # initial condition
t = 0. # initial condition
ys_step = ys_halfstep = ys_doublestep = ys = []
dy_min = 0.01
dy_max = 0.1
dt_min = 0.0001
y_tol = 0.0001

no_of_iterations = 0

while(t < 1):
    no_of_iterations += 1

    # for timestep = dt
    k1 = first_derivative(t,          y) 
    k2 = first_derivative(t + dt/2. , y + (dt/2.)*k1)
    k3 = first_derivative(t + dt/2. , y + (dt/2.)*k2)
    k4 = first_derivative(t +  dt   , y +   dt   *k3)
    y_step = y + (dt/6.) * (k1 + 2*k2 + 2*k3 + k4)
    ys_step.append(y_step) # for plotting y vs t, at the end of the script, after integration has finished

    # for timestep = dt / 2
    k1 = first_derivative(t,          y)
    k2 = first_derivative(t + dt/4. , y + (dt/4.)*k1)
    k3 = first_derivative(t + dt/4. , y + (dt/4.)*k2)
    k4 = first_derivative(t + dt/2. , y + (dt/2.)*k3)
    y_halfstep = y + (dt/12.) * (k1 + 2*k2 + 2*k3 + k4)
    ys_halfstep.append(y_halfstep)
    
    # for timestep = dt * 2
    k1 = first_derivative(t,          y)
    k2 = first_derivative(t +  dt ,   y +  dt   * k1)
    k3 = first_derivative(t +  dt ,   y +  dt   * k2)
    k4 = first_derivative(t + 2.*dt,  y + 2.*dt * k3)
    y_doublestep = y + (dt/3.) * (k1 + 2*k2 + 2*k3 + k4)
    ys_doublestep.append(y_doublestep)


    if (abs(y_step) <= y_tol): # fix the timestep to dt_min because otherwise we divide by 0 in comparisons below
        if (dt != dt_min):
            dt = dt_min
        new_y = y_step

    else: # can modify the timestep if needed
        if ( (abs(y_step) > y_tol)  and ( (abs(y_step - y_halfstep)/abs(y_step))  > dy_max ) ): # error is too large
            dt = dt / 2.
            new_y = y_halfstep
        else:
            if ( (abs(y_step) > y_tol) and ( (abs(y_step - y_doublestep)/abs(y_step)) < dy_min ) ) : # error too small, can increase dt
                dt = 2. * dt
                new_y = y_doublestep
            else: # timestep is just right! keep it as it is and return y_step (i.e. the y-value computed using timestep = dt)
                new_y = y_step
    
    y = new_y
    # print("y is :")
    # print(y)
    # print(len(y)) # error, object of type 'float' has no len()
    ys.append(y)
    # print("t is: ")
    # print(t)
    ts.append(t)
    t += dt

print(len(ys)) # 
print(len(ts)) # 
print("no of iterations: ")
print(no_of_iterations)

plt.figure()
plt.plot(ts, ys, label='y values', color='red')
plt.xlabel('t')
plt.ylabel('y')
plt.title("RK4 adaptive step-size integration for dy/dt = f(y,t) \n" + "f(y,t) = " + rhs_of_diff_Eq_str)
plt.savefig("RK4_adaptive_step_size_results.pdf", bbox_inches='tight')

由于 2 个列表tsys具有不同数量的元素,这会导致绘图指令出错。

我已经查看了一段时间的代码,但我不明白为什么在脚本退出 while 循环后ys总是有 4 倍于列表ts中的元素数量的原因。

你能帮我吗,也许这很明显?

谢谢

问题从这行ys_step = ys_halfstep = ys_doublestep = ys = []发生,有一个创建的四个列表,但都引用了相同的内存,当你 append 时,该列表中的元素之一将它与所有列出的 append 相同。

您只能更改如下:

ys_step = []
ys_halfstep = []
ys_doublestep = []
ys = []

它会起作用的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM