为什么这 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 个列表 ts
和 ys
的元素数量不同,这会导致绘图指令出错。
我已经看了一段时间的代码,但我不明白为什么 ys
总是有 4 倍于脚本后列表 ts
中元素的数量退出 while 循环。
你能帮帮我吗,也许这是显而易见的事情?
谢谢
从这一行 ys_step = ys_halfstep = ys_doublestep = ys = []
开始出现问题,创建了四个列表,但所有列表都引用相同的内存,当您附加该列表中的元素之一时,它仍然附加所有列表。
您只能更改如下:
ys_step = []
ys_halfstep = []
ys_doublestep = []
ys = []
它会起作用。
我已经为自适应步长 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 个列表 ts
和 ys
的元素数量不同,这会导致绘图指令出错。
我已经看了一段时间的代码,但我不明白为什么 ys
总是有 4 倍于脚本后列表 ts
中元素的数量退出 while 循环。
你能帮帮我吗,也许这是显而易见的事情?
谢谢
从这一行 ys_step = ys_halfstep = ys_doublestep = ys = []
开始出现问题,创建了四个列表,但所有列表都引用相同的内存,当您附加该列表中的元素之一时,它仍然附加所有列表。
您只能更改如下:
ys_step = []
ys_halfstep = []
ys_doublestep = []
ys = []
它会起作用。