0

我做了很多 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

这真的很笨拙,并且由于多种原因而不能令人满意。每当我需要向模拟添加新参数时,我都必须修改参数列表并更改我在模拟函数中手动解包列表的方式;浪费一些时间在每一轮模拟中建立新的参考,等等。

我想知道是否有一个理智的、非笨拙的解决方案来定义带有名称的参数,将它们作为列表传递给函数,然后通过列表中的相同名称来引用它们。

4

2 回答 2

1

我通常会按照 Joran 在他的回答中提出的建议:

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,它运行良好。例如,在以下代码中,您可以使用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']
于 2013-04-24T18:26:04.100 回答
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))
于 2013-04-24T03:54:38.523 回答