我一直在研究应该接受耦合方程的通用元组的模块,以提出解决方案。最初,我在我感兴趣的特定方程组上对其进行了测试,并且效果很好。但是后来我在一个简单的系统上对其进行了测试,以查看我是否确实实现了通用功能。
似乎在可行的实例中,我能够从列表中拉出每个函数,插入参数,并对返回值进行操作。
在无法正常工作的情况下,Python似乎将我的函数归类为“生成器”,这是我无法进行算术运算的...
这段代码也是我第一次尝试使用*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'
答案 0 :(得分:1)
在非工作示例中,您没有分配if let routePickerButton = routePickerView.subviews.first(where: { $0 is UIButton }) as? UIButton {
routePickerButton.sendActions(for: .touchUpInside)
}
。这导致z[i]
被分配了整个输出,它是一个生成器。在以后的迭代中,此y[i]
是在浮点乘法的情况下求值的,这就是错误的意思。我相信您需要做的就是添加y[i]
,例如:
z[i]