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

why these 2 python lists have different len's?

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

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 的元素数量不同,这会导致绘图指令出错。

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

你能帮帮我吗,也许这是显而易见的事情?

谢谢

从这一行 ys_step = ys_halfstep = ys_doublestep = ys = [] 开始出现问题,创建了四个列表,但所有列表都引用相同的内存,当您附加该列表中的元素之一时,它仍然附加所有列表。

您只能更改如下:

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

它会起作用。