[英]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 个列表ts
和ys
具有不同数量的元素,这会导致绘图指令出错。
我已经查看了一段时间的代码,但我不明白为什么在脚本退出 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.