Scipy Curve拟合全局参数

时间:2015-10-23 00:10:48

标签: python scipy curve-fitting

我试图在python中使用Scipy curve_fit来拟合银河模型的两个全局参数。我有一个自变量数组和一个因变量数组。数据集的前1/4需要根据两个全局参数和两个局部参数拟合一个函数,下一个四分之一的函数取决于两个全局参数和两个局部变量等。

无论如何,我可以编写一个函数,通过整个数组使用正确的索引和全局参数调用相应的函数。

到目前为止我所拥有的是:

id

问题是这只适用于第一次但是整个时间数组,并且单点仅适合于相应的模型点而不是整个数组。关于如何重新制定这个的任何帮助?我试图将其重新表述为:

   def galaxy_func_inner(time,a,b,c,d):
     telescope_inner = lt.station(rot_angle=c,pol_angle=d)
     power = telescope_inner.calculate_gpowervslstarray(time)[0]
     return a*np.array(power)+b

   def galaxy_func_outer(time,a,b,c,d):
     telescope_outer = lt.station(rot_angle=c,pol_angle=d)
     power = telescope_outer.calculate_gpowervslstarray(time)[0]
     return a*np.array(power)+b

   def galaxy_func_global(time,R,P,a,b,c,d,e,f,g,h):
        for t_index in range(len(time)):
           if t_index in range(0,50):
                   return galaxy_func_outer(t_index,a,b,R,P)
           elif t_index in range(50,100):
                   return galaxy_func_outer(t_index,c,d,R,P)
           elif t_index in range(100,150):
                   return galaxy_func_inner(t_index,e,f,R,P)
           elif t_index in range(150,200):
                   return galaxy_func_inner(t_index,g,h,R,P)

但是我收到了错误:

 def galaxy_func_global(xdata,R,P,a,b,c,d,e,f,g,h):
     return galaxy_func_outer(xdata[0:50],a,b,R,P),galaxy_func_outer(xdata[50:100],c,d,R,P),galaxy_func_inner(xdata[100:150],e,f,R,P),galaxy_func_inner(xdata[150:200],g,h,R,P)

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

如果要将输入数据分成4批(基于time点的索引)并根据批次处理数据,然后将结果返回到单个数组,然后你可以这样做:

def galaxy_func_global(time,R,P,a,b,c,d,e,f,g,h):
    return np.concatenate([galaxy_func_outer(time[0:50],a,b,R,P),
                          galaxy_func_outer(time[50:100],c,d,R,P),
                          galaxy_func_inner(time[100:150],e,f,R,P),
                          galaxy_func_inner(time[150:200],g,h,R,P)])

这将切入您的time数组以挑选出每个感兴趣的切片,然后为每个切片调用相应的函数。在我看来,这些函数返回简单的np.array s,它们可以连接起来以获得单个数组。

(我刚才意识到我可以说“你尝试过的几乎是完美的,但你需要将结果数组连接成一个数组”:)

请注意,至少有两种方法可以解决尺寸问题。

首先,您应该确保两个函数(galaxy...inner/outer())的返回值都是1d numpy数组。否则,您的全局返回值会遇到问题。

其次,由于显而易见的原因,每个拟合方法都需要一个函数,其返回值与输入变量具有相同的大小(形状)。因此,如果time不完全是200个元素,那么您也可能会遇到当前代码的问题,因为即使time更长,您的输出也会被截断为200个元素。至少你应该把

galaxy_func_inner(time[150:],g,h,R,P)

进入上次函数调用以捕获 time的所有剩余点,但如果您想正确执行,请致电

def galaxy_func_global(time,R,P,a,b,c,d,e,f,g,h):
    inds=np.floor(np.linspace(0,len(time)-1,5))
    return np.concatenate([galaxy_func_outer(time[0:inds[1]],a,b,R,P),
                      galaxy_func_outer(time[inds[1]:inds[2]],c,d,R,P),
                      galaxy_func_inner(time[inds[2]:inds[3]],e,f,R,P),
                      galaxy_func_inner(time[inds[3]:],g,h,R,P)])

另请注意,您的原始错误是正式的:

File "/Library/Python/2.7/site-packages/scipy-0.14.0.dev_7cefb25-py2.7-macosx-10.9-intel.egg/scipy/optimize/minpack.py", line 445, in _general_function
    return function(xdata, *params) - ydata
ValueError: operands could not be broadcast together with shapes (4,) (191,) 

这告诉你python无法从ydata(即你的拟合模型)中减去function(xdata,*params)因为一个长度为4而另一个长度为191.这是因为如果你的函数调用return a,b,c,d,然后它将返回元组 (a,b,c,d),因此返回值的长度为4.有趣的是,ydata的长度为191,这可能意味着你仍然会遇到错误。