我做了很多ODE模拟,我使用了一些python参数优化工具(例如scipy.optimize.minimize,emcee),这些工具需要将参数作为列表传入。这使得它们非常麻烦,因为我必须将参数称为params[0]
,params[1]
等,而不是更直观的名称,这些名称实际上描述了它们在模拟中的作用。到目前为止,我对此的解决方案一直是这样的:
k1 = 1.0
k2 = 0.5
N = 0.01
params = [k1,k2,N]
def sim(params,timerange):
k1 = params[0]
k2 = params[1]
N = params[2]
# run the simulation
这确实很糟糕,并且由于多种原因而不能令人满意。每当我需要向模拟添加新参数时,我必须修改参数列表并更改我在模拟函数中手动解压缩列表的方式;浪费一些时间在每一轮模拟等方面做出新的参考。
我想知道是否有一个理智的,非kludgey解决方案用于使用名称定义参数,将它们作为列表传递给函数,然后通过列表中的相同名称引用它们。
答案 0 :(得分:1)
def sim(params,timerange):
k1,k2,N = params
你想要的是我想的..,..如果你添加了一个额外的参数,你只需要在N之后添加它......但它不会是一个可选参数
或者更好
def sim(*params,**kwargs):
timerange = kwargs.get('timerange',default_timerange)
K1,K2,N = params #assuming you know you have exactly 3
#then call it like so
sim(k1,k2,N,timerange=(-100,100))
答案 1 :(得分:1)
我经常按照乔伦在答案中的建议行事:
def sim(params, timerange):
k1, k2, N = params
...
但你也可以这样做:
def sim((k1, k2, N), timerange):
...
(至少,它适用于Python 2.7。我没有尝试过其他Python版本。)我用scipy.integrate.odeint
,scipy.integrate.ode
和scipy.optimize.minimize
测试了这个想法,然后它工作得很好。例如,在以下代码中,您可以使用cost
或cost2
作为minimize
的第一个参数:
from scipy.optimize import minimize
def cost(z, a, b):
x, y = z
c = (x - a)**2 + (y - b)**2
return c
def cost2((x, y), a, b):
c = (x - a)**2 + (y - b)**2
return c
if __name__ == "__main__":
a = 5.0
b = 1.5
x0 = 4.2
y0 = 1.5
sol = minimize(cost2, (x0, y0), args=(a,b))
print sol['x']