Python 在迭代调用的函数中存储和加载参数的有效方法
我一直在研究一个需要模拟系统的问题。我已经将我编写的相关代码剥离到了对这个问题很重要的部分Python 在迭代调用的函数中存储和加载参数的有效方法,python,python-3.x,memory-management,Python,Python 3.x,Memory Management,我一直在研究一个需要模拟系统的问题。我已经将我编写的相关代码剥离到了对这个问题很重要的部分 def oscillatorParams(): K1,K2,K3 = 1e5,1e6,1e2 B1,B2,B3 = 100,100,100 a1,a2,a3 = 1,1,1 b1,b2,b3 = 1,1,1 I1,I2,I3 = 1000,10000,20000 return K1,K2,K3,B1,B2,B3,a1,a2,a3,b1,b2,b3,I1,I2
def oscillatorParams():
K1,K2,K3 = 1e5,1e6,1e2
B1,B2,B3 = 100,100,100
a1,a2,a3 = 1,1,1
b1,b2,b3 = 1,1,1
I1,I2,I3 = 1000,10000,20000
return K1,K2,K3,B1,B2,B3,a1,a2,a3,b1,b2,b3,I1,I2,I3
def ode_3DOF_oscillator(state,t, u):
K1, K2, K3, B1, B2, B3, a1, a2, a3, b1, b2, b3, I1, I2, I3 = oscillatorParams()
..equations for the odesolver..
return [omega[0],omega[1],omega[2],dw1dt,dw2dt,dw3dt]
def runSim(u,dt,T):
t=np.arange(0,T,dt) ; N=len(t)
for i in range(0, N ):
if i==N-1 or i==N:
tt = [t[i], t[i]] # [t1 t2]
else:
tt = [t[i], t[i+1]] # [t1 t2]
x=odeint(ode_3DOF_oscillator,x0,tt,args=(M[i,:],))
return t,y1,y2,y3
我没有很强的编程背景,我对如何优化实现参数感到困惑。我更愿意将参数存储在某个地方,使其易于编辑,因为我可能会在多个其他文件中使用这些函数,但我假设此函数将继续为每个ode_3DOF_振荡器(state,t,u)调用分配参数。有更好的方法吗?为了解释现有代码,ODE解算器Python的每次迭代都必须:
ode\u3dof\u振荡器
,该振荡器立即调用振荡器参数
def make_3DOF_oscillator():
K1,K2,K3 = 1e5,1e6,1e2
B1,B2,B3 = 100,100,100
a1,a2,a3 = 1,1,1
b1,b2,b3 = 1,1,1
I1,I2,I3 = 1000,10000,20000
def fn(state, t, u):
# ..equations for the odesolver..
return [omega[0],omega[1],omega[2],dw1dt,dw2dt,dw3dt]
return fn
def runSim(u,dt,T):
myfn = make_3DOF_oscillator()
t=np.arange(0,T,dt) ; N=len(t)
for i in range(0, N ):
if i==N-1 or i==N:
tt = [t[i], t[i]] # [t1 t2]
else:
tt = [t[i], t[i+1]] # [t1 t2]
x=odeint(myfn, x0,tt,args=(M[i,:],))
return t,y1,y2,y3
这导致了良好的性能,因为参数在函数fn
中作为局部变量直接可用(而全局变量稍慢)。此外,参数仅设置一次,而不是每一步
否则,假设性能不是一个问题,并且您不介意稍微多键入一点,您可以使用类:
class Oscillator3DOF:
def __init__(self):
self.K1, self.K2, self.K3 = 1e5,1e6,1e2
self.B1, self.B2, self.B3 = 100,100,100
self.a1, self.a2, self.a3 = 1,1,1
self.b1, self.b2, self.b3 = 1,1,1
self.I1, self.I2, self.I3 = 1000,10000,20000
def deriv(self, y, t, u):
# ..equations for the odesolver..
return [omega[0],omega[1],omega[2],dw1dt,dw2dt,dw3dt]
def runSim(u,dt,T):
system = Oscillator3DOF()
t=np.arange(0,T,dt) ; N=len(t)
for i in range(0, N ):
if i==N-1 or i==N:
tt = [t[i], t[i]] # [t1 t2]
else:
tt = [t[i], t[i+1]] # [t1 t2]
x=odeint(system.deriv, x0,tt,args=(M[i,:],))
return t,y1,y2,y3
请注意,deriv
将以self.K1
等方式访问参数
另一种选择是使用类似的方法存储参数一次。这将使在源代码之外保存参数值变得更容易,这可能是一个理想的属性
我不太确定你的
M
和u
参数是用来做什么的,但我很想用同样的方法设置它们。e、 g.将其传递给make_3DOF_振荡器(M[i,:])
,使其在fn
中可用,或将其保存为振荡器3DOF
的构造函数中的成员变量。在这些情况下,您可能希望在for i
循环中创建对象,这样它就可以访问正确的对象了,这应该不会有任何问题。你有证据表明这段代码有问题吗?不,我不认为在这种情况下它会很明显,因为它只有15个值。我只是想在这一过程中学习一些好的实践,如果我理解正确的话,如果我在每次迭代中都要加载1000个float,它可能会变得更容易识别。但总的来说,我只是想从更有经验的人那里得到代码的反馈,也许可以看看最佳实践是什么。