1

I am trying to fit some data to an equation in python and I am having some difficulty. I have the equation:

y(t)=yo+a(t-ti)^b+kt

where a, ti, b and k are fitting parameters, and t and disp are array varaibles representing time and displacement respectively. The equation will fit in gnuplot fine with some iteration, but fitting it in python throws up an error of:-

ValueError: array must not contain infs or NaNs

The complete stack trace is:

creep_test.py:246: RuntimeWarning: invalid value encountered in power
  fitfunc = lambda p, t: disp_list[0]+(p[0]*(t-p[1])**p[2])+p[3]*t # Target function
Traceback (most recent call last):
  File "creep_test.py", line 374, in <module>
    main()
  File "creep_test.py", line 368, in main
    python_fit(filename)  
  File "creep_test.py", line 256, in python_fit
    out = optimize.leastsq(errfunc, p0[:], args=(t, disp,err), full_output=1)
  File "/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py", line 338, in leastsq
    cov_x = inv(dot(transpose(R),R))
  File "/usr/lib/python2.7/dist-packages/scipy/linalg/basic.py", line 285, in inv
    a1 = asarray_chkfinite(a)
  File "/usr/lib/python2.7/dist-packages/numpy/lib/function_base.py", line 590, in asarray_chkfinite
    "array must not contain infs or NaNs")
ValueError: array must not contain infs or NaNs

I have found with playing around that its the term ti that is causing the issues in that the fitting works if you have ti fixed at around 35.5. I have used a spreadsheet and for any values of t under the ti, the equation throws up an #VALUE (probably because its imaginary)

Basically is there a way to get python to fit the curve like gnuplot (which I assume ignores the non valid results)? I the code I have used for the fittiong part of my programme is below:

  fitfunc = lambda p, t: disp_list[0]+(p[0]*(t-p[1])**p[2])+p[3]*t # Target function
  errfunc = lambda p, t, y, err: (fitfunc(p, t) - y)/(err) # Distance to the target function
  err=0.01
  p0 = [ 50, 35.5,0.005, 0.001] # Initial guess for the parameters
  out = optimize.leastsq(errfunc, p0[:], args=(t, disp,err), full_output=1)
  print out[0]
  print out[1]

Thankyou!!

Phil
  • 581
  • 1
  • 7
  • 11
  • Can you show us what your `t` and `disp` look like? – ford Jan 14 '13 at 16:34
  • Ah sorry disp_list[0] is the yo value (first value from a list read from my data (represents displacement)) and t is time in seconds (independent vairable) – Phil Jan 14 '13 at 16:37
  • oh and t is an array variable form (again just a list of time values) – Phil Jan 14 '13 at 16:38
  • Also disp is the array of dependent variables (measured displacement) – Phil Jan 14 '13 at 16:50
  • Please show the complete stack trace when you get the error. –  Jan 14 '13 at 16:52
  • Bad starting params can lead to such errors with optimize.leastsq(). can you try with parameters "near" the optional best fit values just to check? – reptilicus Jan 14 '13 at 17:34
  • 1
    Also, mpfit or kmpfit (http://www.astro.rug.nl/software/kapteyn/kmpfit.html) are much more robust than optimize.leastsq() – reptilicus Jan 14 '13 at 17:37
  • Ah excellent! thank you very much. I will have a look at that. Thank you all for your help! Sleeping tonight is back on the cards!!! – Phil Jan 14 '13 at 17:56

1 Answers1

2

Valuable lesson learned. The starting parameters I was using to try and break the more simplistic equation I was fitting prior to this was breaking the more complex equation Im fitting now. Always check your starting parameters if the fitting is claiming that solutions aren't making sense. Learning python the hard way so you don't have to.....

Phil
  • 581
  • 1
  • 7
  • 11