如何遍历元组或函数列表并对它们的 return 值进行操作?
How to iterate through a tuple or list of functions and operate on their return values?
我一直在研究据称接受耦合方程的通用元组吐出解决方案的模块。最初,我在我感兴趣的特定方程组上对其进行了测试,并且效果非常好。但是后来我在一个更简单的系统上测试了它,只是为了看看我是否真的实现了一个通用的功能。
似乎在有效的实例中,我能够从列表中提取每个函数,插入参数,并对 return 值进行操作。
在它不起作用的情况下,看起来 Python 将我的函数归类为 "generators",这是我无法计算的...
这段代码也是我第一次尝试使用*args
和**kwargs
,这很令人兴奋,但也许那里也有一些错误...
我是一个相对较新的程序员,在我的代码工作之前,他主要通过从文档和论坛中复制和粘贴来学习。请善待。如果我的问题格式不正确,请告诉我如何提出更好的问题。如果您回答,请根据我的知识水平回答(或者如果我需要研究某些内容以理解您的回答,请提供文档链接)
第一个片段是解决问题的原始函数:
# Below is the standard representation of RK4, generalized to any system
# ** init is the solution vector y_(n-1) from the previous step
# used to solve for the solution at the next step, y_n.
# ** t is the previous time step
# ** dfuncs is the vector field dy/dt = f(t,y)
def RK4(init, t, dfuncs, h):
k1 = [ h*f(*init,t) for f in dfuncs ]
args = [ r+0.5*kr for r,kr in zip((*init,t),(*k1, h)) ]
k2 = [ h*f(*args) for f in dfuncs ]
args = [ r+0.5*kr for r,kr in zip((*init,t),(*k2, h)) ]
k3 = [ h*f(*args) for f in dfuncs ]
args = [ r+kr for r,kr in zip((*init,t),(*k3, h)) ]
k4 =[ h*f(*args) for f in dfuncs ]
return (r+(k1r+2*k2r+2*k3r+k4r)/6 for r,k1r,k2r,k3r,k4r in
zip(init,k1, k2, k3, k4))
以下是该函数运行良好的代码:
#The following three functions represent the three ODEs in question
# dB/Dt =
def fx(B, S, E, t):
return (r_b*B*(1 - (B*(pow(T, 2)
+ pow(E, 2)))/(K*S*pow(E, 2)))
- (beta*pow(B, 2))/(pow((alpha*S),2)
+ pow(B, 2)))
#dS/dt =
def fy(B, S, E, t):
return r_s*S*(1 - (S*K_e) / (E*K_s))
# dE/dt =
def fz(B, S, E, t):
return r_e*E*(1 - E/K_e) - (P*B*pow(E, 2))/(S*(pow(T,2) + pow(E, 2)))
# set parameter values from Ludwig paper
r_b = 1.52
r_s = 0.095
r_e = 0.92
alpha = 1.11
beta = 43200
K = 355
K_s = 25440
K_e = 1
P = 0.00195
T = 0.1
t_0 = 0.
t_n = 50.
Dt = .5
steps=int(np.floor((t_n - t_0) / Dt))
# initialize solution vectors
t = steps * [0.0]
B = steps * [0.0]
S = steps * [0.0]
E = steps * [0.0]
#Set initial conditions
B[0],S[0],E[0],t[0] = 1e-16, .075*K_s, 1., 0.
# Solve the system using RK4
for i in range(1, steps):
B[i],S[i],E[i] = RK4((B[i - 1], S[i - 1], E[i - 1]), t[i - 1], (fx, fy, fz), Dt)
这是它失败的更简单的系统:
def dy(y, z, t):
return y
def dz(y, z, t):
return pow(z, 2)
t0 = 0
tn = 10
y0 = 1
z0 = 0
Dt = 0.01
steps = int(np.floor((tn - t0) / Dt))
y = steps * [0.0]
z = steps * [0.0]
t = steps * [0.0]
y[0] = y0
z[0] = z0
t[0] = t0
for i in range(1, steps):
y[i] = RK4((y[i-1], z[i-1]), t[i-1], (dy, dz), Dt)
有回溯:
Traceback (most recent call last):
File "C:/Users/wesle/PycharmProjects/Budworms/basic.py", line 27, in <module>
y[i] = RK4((y[i-1], z[i-1]), t[i-1], (dy, dz), Dt)
File "C:\Users\wesle\PycharmProjects\Budworms\RK4.py", line 23, in RK4
k1 = [ h*f(*init,t) for f in dfuncs ]
File "C:\Users\wesle\PycharmProjects\Budworms\RK4.py", line 23, in <listcomp>
k1 = [ h*f(*init,t) for f in dfuncs ]
TypeError: unsupported operand type(s) for *: 'float' and 'generator'
在非工作示例中,您没有分配 z[i]
。这导致 y[i]
被分配了整个输出,这是一个生成器。在以后的迭代中,这个 y[i]
是在浮点乘法的上下文中计算的,这就是错误所说的。我相信您需要做的就是添加 z[i]
,例如:
y[i], z[i] = RK4((y[i - 1], z[i - 1]), t[i - 1], (dy, dz), Dt)
我一直在研究据称接受耦合方程的通用元组吐出解决方案的模块。最初,我在我感兴趣的特定方程组上对其进行了测试,并且效果非常好。但是后来我在一个更简单的系统上测试了它,只是为了看看我是否真的实现了一个通用的功能。
似乎在有效的实例中,我能够从列表中提取每个函数,插入参数,并对 return 值进行操作。
在它不起作用的情况下,看起来 Python 将我的函数归类为 "generators",这是我无法计算的...
这段代码也是我第一次尝试使用*args
和**kwargs
,这很令人兴奋,但也许那里也有一些错误...
我是一个相对较新的程序员,在我的代码工作之前,他主要通过从文档和论坛中复制和粘贴来学习。请善待。如果我的问题格式不正确,请告诉我如何提出更好的问题。如果您回答,请根据我的知识水平回答(或者如果我需要研究某些内容以理解您的回答,请提供文档链接)
第一个片段是解决问题的原始函数:
# Below is the standard representation of RK4, generalized to any system
# ** init is the solution vector y_(n-1) from the previous step
# used to solve for the solution at the next step, y_n.
# ** t is the previous time step
# ** dfuncs is the vector field dy/dt = f(t,y)
def RK4(init, t, dfuncs, h):
k1 = [ h*f(*init,t) for f in dfuncs ]
args = [ r+0.5*kr for r,kr in zip((*init,t),(*k1, h)) ]
k2 = [ h*f(*args) for f in dfuncs ]
args = [ r+0.5*kr for r,kr in zip((*init,t),(*k2, h)) ]
k3 = [ h*f(*args) for f in dfuncs ]
args = [ r+kr for r,kr in zip((*init,t),(*k3, h)) ]
k4 =[ h*f(*args) for f in dfuncs ]
return (r+(k1r+2*k2r+2*k3r+k4r)/6 for r,k1r,k2r,k3r,k4r in
zip(init,k1, k2, k3, k4))
以下是该函数运行良好的代码:
#The following three functions represent the three ODEs in question
# dB/Dt =
def fx(B, S, E, t):
return (r_b*B*(1 - (B*(pow(T, 2)
+ pow(E, 2)))/(K*S*pow(E, 2)))
- (beta*pow(B, 2))/(pow((alpha*S),2)
+ pow(B, 2)))
#dS/dt =
def fy(B, S, E, t):
return r_s*S*(1 - (S*K_e) / (E*K_s))
# dE/dt =
def fz(B, S, E, t):
return r_e*E*(1 - E/K_e) - (P*B*pow(E, 2))/(S*(pow(T,2) + pow(E, 2)))
# set parameter values from Ludwig paper
r_b = 1.52
r_s = 0.095
r_e = 0.92
alpha = 1.11
beta = 43200
K = 355
K_s = 25440
K_e = 1
P = 0.00195
T = 0.1
t_0 = 0.
t_n = 50.
Dt = .5
steps=int(np.floor((t_n - t_0) / Dt))
# initialize solution vectors
t = steps * [0.0]
B = steps * [0.0]
S = steps * [0.0]
E = steps * [0.0]
#Set initial conditions
B[0],S[0],E[0],t[0] = 1e-16, .075*K_s, 1., 0.
# Solve the system using RK4
for i in range(1, steps):
B[i],S[i],E[i] = RK4((B[i - 1], S[i - 1], E[i - 1]), t[i - 1], (fx, fy, fz), Dt)
这是它失败的更简单的系统:
def dy(y, z, t):
return y
def dz(y, z, t):
return pow(z, 2)
t0 = 0
tn = 10
y0 = 1
z0 = 0
Dt = 0.01
steps = int(np.floor((tn - t0) / Dt))
y = steps * [0.0]
z = steps * [0.0]
t = steps * [0.0]
y[0] = y0
z[0] = z0
t[0] = t0
for i in range(1, steps):
y[i] = RK4((y[i-1], z[i-1]), t[i-1], (dy, dz), Dt)
有回溯:
Traceback (most recent call last):
File "C:/Users/wesle/PycharmProjects/Budworms/basic.py", line 27, in <module>
y[i] = RK4((y[i-1], z[i-1]), t[i-1], (dy, dz), Dt)
File "C:\Users\wesle\PycharmProjects\Budworms\RK4.py", line 23, in RK4
k1 = [ h*f(*init,t) for f in dfuncs ]
File "C:\Users\wesle\PycharmProjects\Budworms\RK4.py", line 23, in <listcomp>
k1 = [ h*f(*init,t) for f in dfuncs ]
TypeError: unsupported operand type(s) for *: 'float' and 'generator'
在非工作示例中,您没有分配 z[i]
。这导致 y[i]
被分配了整个输出,这是一个生成器。在以后的迭代中,这个 y[i]
是在浮点乘法的上下文中计算的,这就是错误所说的。我相信您需要做的就是添加 z[i]
,例如:
y[i], z[i] = RK4((y[i - 1], z[i - 1]), t[i - 1], (dy, dz), Dt)