Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
685 views
in Technique[技术] by (71.8m points)

scipy curve_fit error: Result from function call is not a proper array of floats

I have an [x,y] dataset and I would like to fit a function to it. This are x and y

parang = np.array([  61.1725  ,   62.140625,   62.93275 ,   63.701625,   65.89225 ,
     66.476875,   68.33525 ,   68.902375,   72.03975 ,   72.590375,
     73.144125,   73.670625,   80.36525 ,   80.80275 ,   87.505375,
     87.90375 ,  100.557875,  100.8915  ])

q      = np.array([-0.03699417, -0.03451252, -0.03851238, -0.0393034 , -0.04059193,
   -0.03941371, -0.04206476, -0.04153004, -0.04721763, -0.04667099,
   -0.03996427, -0.03872865, -0.05054322, -0.0466561 , -0.05476921,
   -0.05274144, -0.0474299 , -0.04974607])

and then I want to fit a function to the data that goes as follows:

def fq(x,bq,cuq):
    qval = bq*stndqu[0]*np.cos(np.radians(2*x))+cuq*stndqu[1]*np.sin(np.radians(2*x))
    print qval
    print qval.dtype
    return qval

where 'bq,cuq' are the parameter I need to fit and stndqu are global parameters I obtain as:

stnd    = input(r'P ($\%$) and $heta$ of pol. standard? (as tuple)')
p       = stnd[0]/100.
ang     = np.radians(stnd[1])  
x,y     = sympy.symbols('x y')  
stndqu  = sympy.solve([sympy.sqrt(x**2+y**2)-p,(0.5*sympy.atan(y/x))-ang],[x,y])[1] 

and P and theta are 2.73 and 95. The stndqu[0] and stndqu[1] I get out from that block are 0.0272334985720932 and 0.00190435173321445

To find the parameters 'bq' and 'cuq' of the function that fit my data I do:

qpopt,pconv   = scio.curve_fit(fq, parang, q)

and here's the result:

[-0.0129614827538107 -0.0137658898997091 -0.0144124082012406
 -0.0150294169782742 -0.0167265263727253 -0.0171633151430064
 -0.0185034265676582 -0.0188971421096823 -0.0209373417940197
 -0.0212701779430718 -0.0215969783128203 -0.0219002154908251
 -0.0250793309165333 -0.0252411052388773 -0.0269646924974054
 -0.0270214005655701 -0.0260909416985902 -0.0259956074319825]
object
[-0.0129614827538107 -0.0137658898997091 -0.0144124082012406
 -0.0150294169782742 -0.0167265263727253 -0.0171633151430064
 -0.0185034265676582 -0.0188971421096823 -0.0209373417940197
 -0.0212701779430718 -0.0215969783128203 -0.0219002154908251
 -0.0250793309165333 -0.0252411052388773 -0.0269646924974054
 -0.0270214005655701 -0.0260909416985902 -0.0259956074319825]
object
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
TypeError: array cannot be safely cast to required type
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
/Users/mj/Documents/NACO/VLT/DataReduction/<ipython-input-57-cac353117232> in <module>()
----> 1 qpopt,pconv   = scio.curve_fit(fq, parang, q)

/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/optimize/minpack.pyc in curve_fit(f, xdata, ydata, p0, sigma, **kw)
    408    # Remove full_output from kw, otherwise we're passing it in twice.

    409    return_full = kw.pop('full_output', False)
--> 410    res = leastsq(func, p0, args=args, full_output=1, **kw)
    411    (popt, pcov, infodict, errmsg, ier) = res
    412 

/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/optimize/minpack.pyc in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag, warning)
    268    if (maxfev == 0):
    269        maxfev = 200*(n+1)
--> 270        retval = _minpack._lmdif(func,x0,args,full_output,ftol,xtol,gtol,maxfev,epsfcn,factor,diag)
    271    else:
    272        if col_deriv:

error: Result from function call is not a proper array of floats.

I tried specifying the type of the qval element making it

def fq(x,bq,cuq):
    qval = np.array(
           bq*stndqu[0]*np.cos(np.radians(2*x))+cuq*stndqu[1]*np.sin(np.radians(2*x)),
    dtype=float)

and then the result changes to:

qpopt   = scio.curve_fit(fq, parang, q)
[-0.01296148 -0.01376589 -0.01441241 -0.01502942 -0.01672653 -0.01716332
 -0.01850343 -0.01889714 -0.02093734 -0.02127018 -0.02159698 -0.02190022
 -0.02507933 -0.02524111 -0.02696469 -0.0270214  -0.02609094 -0.02599561]
float64
[-0.01296148 -0.01376589 -0.01441241 -0.01502942 -0.01672653 -0.01716332
 -0.01850343 -0.01889714 -0.02093734 -0.02127018 -0.02159698 -0.02190022
 -0.02507933 -0.02524111 -0.02696469 -0.0270214  -0.02609094 -0.02599561]
float64
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
TypeError: array cannot be safely cast to required type
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
/Users/mj/Documents/NACO/VLT/DataReduction/<ipython-input-50-1f4d3764f7ae> in <module>()
----> 1 qpopt   = scio.curve_fit(fq, parang, q)

/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/optimize/minpack.pyc in curve_fit(f, xdata, ydata, p0, sigma, **kw)
    408    # Remove full_output from kw, otherwise we're passing it in twice.

    409    return_full = kw.pop('full_output', False)
--> 410    res = leastsq(func, p0, args=args, full_output=1, **kw)
    411    (popt, pcov, infodict, errmsg, ier) = res
    412 

/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scipy/optimize/minpack.pyc in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag, warning)
    268     if (maxfev == 0):
    269         maxfev = 200*(n+1)
--> 270         retval = _minpack._lmdif(func,x0,args,full_output,ftol,xtol,gtol,maxfev,epsfcn,factor,diag)
    271     else:
    272         if col_deriv:

error: Result from function call is not a proper array of floats.

So no progress...

Can someone tell me where is this going wrong?

Thank you very much in advance!

M.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since stndqu is the result of a call to sympy.solve, it is a symbolic object still. The numbers that you see when printing qval from within your function are probably sympy floats (and thus generic objects to numpy). You should convert stndqu into a numpy array before using it with scipy.curve_fit:

stndqun = numpy.array([sympy.N(i) for i in stndqu])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...