解压缩模拟参数

时间:2013-04-24 03:33:26

标签: python parameters scipy emcee

我做了很多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解决方案用于使用名称定义参数,将它们作为列表传递给函数,然后通过列表中的相同名称引用它们。

2 个答案:

答案 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.odeintscipy.integrate.odescipy.optimize.minimize测试了这个想法,然后它工作得很好。例如,在以下代码中,您可以使用costcost2作为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']