将其他参数传递给scipy.optimize.curve_fit

时间:2018-01-31 18:45:31

标签: python scipy curve-fitting

这个问题有一个答案here但是解决方案对我来说似乎没有用。

我的功能如下:

def slopefunction_cf(xin,amp,phase,off,freq,intercept,t):
    fitted =np.zeros((4,12))

    for im in t:        
        fitted[:,im-1] = intercept[im-1]+[amp*np.sin(freq*(im)+phase)+off]*xin
    return fitted.ravel()

其中intercept和t是附加参数,至少我会以args =

的形式传递

我试过了:

popt, pcov = curve_fit(slopefunction_cf, np.arange(0,4), datain, p0=paramin, args=(intercept,t) )

并收到错误:

TypeError: func_wrapped() takes exactly 1 argument (3 given)

然后我尝试了我链接的答案中建议的内容并将其转换为:

def define_var_args(interceptin,tin):
    def slopefunction_cf(xin,amp,phase,off,freq):
        intercept = interceptin
        t = tin
        fitted =np.zeros((4,12))

        for im in t:        
            fitted[:,im-1] = intercept[im-1]+[amp*np.sin(freq*(im)+phase)+off]*xin
        return fitted.ravel()

然后调用curve_fit:

popt, pcov = curve_fit(define_var_args(intercept, t), np.arange(0,4), datain, p0=paramin )

但我收到以下错误(我复制了所有内容)

--> 115 popt, pcov = curve_fit(define_var_args(interceptconus, t), np.arange(0,4), datain.ravel(), p0=paramin )
    116 
    117 print popt

/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
    734         # Remove full_output from kwargs, otherwise we're passing it in twice.
    735         return_full = kwargs.pop('full_output', False)
--> 736         res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
    737         popt, pcov, infodict, errmsg, ier = res
    738         cost = np.sum(infodict['fvec'] ** 2)

/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
    375     if not isinstance(args, tuple):
    376         args = (args,)
--> 377     shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
    378     m = shape[0]
    379     if n > m:

/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
     24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
     25                 output_shape=None):
---> 26     res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
     27     if (output_shape is not None) and (shape(res) != output_shape):
     28         if (output_shape[0] != 1):

/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in func_wrapped(params)
    452     if transform is None:
    453         def func_wrapped(params):
--> 454             return func(xdata, *params) - ydata
    455     elif transform.ndim == 1:
    456         def func_wrapped(params):

TypeError: 'NoneType' object is not callable

我甚至不确定错误是什么 - 如果代码或我的数据中的某些内容?它有点模糊。

是否有其他方法可以传递其他参数?

编辑:添加一些数据并略微更改上述功能

t = np.arange(1,13)
paramin = [0.40569370873086791, 1, -0.88134718450091365, 0.5]
datain = [-3.45083921, -3.405628  , -2.57401114, -1.7632551 , -1.29342567,
   -1.44200248, -2.05366981, -2.51467815, -2.79597983, -2.95528074,
   -2.90766603, -3.60850134, -3.90036107, -3.87760971, -3.18549774,
   -2.43304533, -2.1734368 , -2.43953997, -3.1183866 , -3.57696154,
   -3.72915335, -3.67344888, -3.29697388, -4.10385938, -4.88945667,
   -4.82385939, -4.10568684, -3.50093464, -3.26766599, -3.78206157,
   -4.51782818, -4.95149472, -4.93689182, -4.75850421, -4.22849458,
   -4.91811193, -5.34080606, -5.40676402, -4.66050702, -4.29447163,
   -4.16430688, -4.75008652, -5.57106708, -5.58801663, -5.96637981,
   -5.51549722, -4.94026303, -5.42975354]
intercept = [-3.39651633, -3.33601661, -2.55447417, -1.69869584, -1.26867791,
       -1.41340658, -2.02249291, -2.56860547, -2.74926044, -2.91082705,
       -2.78895263, -3.57335517]

我已经“raveled”了数据,所以我在问题的开头修改了这个功能。 使用这些数据我在新笔记本中重现我的错误。

解决方案:

我的代码中有两个问题: 1)我没有返回嵌套函数 2)我没有把xin作为嵌套函数的参数 3)我不得不把这颗星放在p

之前

现在可行了

def define_extravar(interceptin,tin):
    def slopefunction_cf(xin,*p):
        intercept = interceptin
        t = tin
        fitted =np.zeros((4,12))
        amp,phase,off,freq = p

        for im in t:        
            fitted[:,im-1] = intercept[im-1]+[amp*np.sin(freq*(im)+phase)+off]*xin
        return fitted.ravel()
    return slopefunction_cf

0 个答案:

没有答案