# [SciPy-User] curve_fit and least squares

josef.pktd@gmai... josef.pktd@gmai...
Thu Oct 22 15:29:09 CDT 2009

```On Thu, Oct 22, 2009 at 4:20 PM, Kris Maynard <maynard@bu.edu> wrote:
> Oops.
>
> Right you both are. I suppose the answer to my general confusion is that
> jimmying the initial fit parameters in the right way will make curve_fit
> work. Thanks!
>
> ~Kris
>
> On Thu, Oct 22, 2009 at 4:12 PM, Warren Weckesser
> <warren.weckesser@enthought.com> wrote:
>>
>> Kris,
>>
>> Your script worked for me if I explicitly converted everything to numpy
>> arrays.  Here's my edited version:
>>
>> ----------
>> #!/usr/bin/env python
>> import numpy as np
>> import scipy as sp
>> import pylab as pl
>> from scipy.optimize.minpack import curve_fit
>>
>> x = np.array([  50.,  110.,  170.,  230.,  290.,  350.,  410.,  470.,
>> 530.,  590.])
>> y = np.array([ 3173.,  2391.,  1726.,  1388.,  1057.,   786.,   598.,
>> 443.,   339.,   263.])
>>
>> smoothx = np.linspace(x[0], x[-1], 20)
>> guess_a, guess_b, guess_c = 4000, -0.005, 100
>> guess = [guess_a, guess_b, guess_c]
>>
>> f_theory1 = lambda t, a, b, c: a * np.exp(b * t) + c
>>
>> p, cov = curve_fit(f_theory1, x, y, p0=np.array(guess))
>>
>> pl.clf()
>> f_fit1 = lambda t: p[0] * np.exp(p[1] * t) + p[2]
>> # pl.plot(x, y, 'b.', smoothx, f_theory1(smoothx, guess_a, guess_b,
>> guess_c))
>> pl.plot(x, y, 'b.', smoothx, f_fit1(smoothx), 'r-')
>> pl.show()
>>
>> ##
>> ## EOF
>> ##
>>
>> ----------
>>
>> Warren
>>
>>
>> Kris Maynard wrote:
>> > Hi,
>> >
>> > Thanks for your responses. After some more digging and some more
>> > testing I'm beginning to think that the algorithm used by curve_fit
>> > simply isn't robust enough for the data that I am trying to fit. Below
>> > is an example of some experimental radioactive decay data that I am
>> > trying to fit to an exponential decay.
>> >
>> > #!/usr/bin/env python
>> > import numpy as np
>> > import scipy as sp
>> > import pylab as pl
>> > from scipy.optimize.minpack import curve_fit
>> >
>> > x = [  50.,  110.,  170.,  230.,  290.,  350.,  410.,  470.,  530.,
>> >  590.]
>> > y = [ 3173.,  2391.,  1726.,  1388.,  1057.,   786.,   598.,   443.,
>> > 339.,   263.]
>> >
>> > smoothx = np.linspace(x[0], x[-1], 20)
>> > guess_a, guess_b, guess_c = 4000, -0.005, 100
>> > guess = [guess_a, guess_b, guess_c]
>> >
>> > f_theory1 = lambda t, a, b, c: a * np.exp(b * t) + c
>> > f_theory2 = lambda t, a, b: np.exp(a * t) + b
>> >
>> > pl.plot(x, y, 'b.', smoothx, f_theory1(smoothx, guess_a, guess_b,
>> > guess_c))
>> > pl.show()
>> >
>> > p, cov = curve_fit(f_theory1, x, y)
>> > #p, cov = curve_fit(f_theory2, x, y)
>> >
>> > # the following gives:
>> > #   ValueError: shape mismatch: objects cannot be broadcast to a
>> > single shape
>> > #p, cov = curve_fit(f_theory1, x, y, p0=guess)
>> >
>> > pl.clf()
>> > f_fit1 = lambda t: p[0] * np.exp(p[1] * t) + p[2]
>> > #f_fit2 = lambda t: np.exp(p[0] * t) + p[1]
>> > pl.plot(x, y, 'b.', smoothx, f_fit1(smoothx), 'k-')
>> > pl.show()
>> >
>> > ##
>> > ## EOF
>> > ##
>> >
>> > As you can see, I have tried to fit using 2 or 3 parameters with no
>> > luck. Is there something that I could do to make this work? I have
>> > tried this exact thing in matlab and it worked the first time.
>> > Unfortunately, I would really like to use python as I find it in
>> > general more intuitive than matlab.
>> >
>> > Thanks,
>> > ~Kris
>> >
>> > On Wed, Oct 7, 2009 at 9:40 AM, Bruce Southey <bsouthey@gmail.com
>> > <mailto:bsouthey@gmail.com>> wrote:
>> >
>> >     On Wed, Oct 7, 2009 at 1:19 AM,  <josef.pktd@gmail.com
>> >     <mailto:josef.pktd@gmail.com>> wrote:
>> >     > On Wed, Oct 7, 2009 at 1:36 AM, Kris Maynard <maynard@bu.edu
>> >     <mailto:maynard@bu.edu>> wrote:
>> >     >> I am having trouble with fitting data to an exponential curve.
>> >     I have an x-y
>> >     >> data series that I would like to fit to an exponential using
>> >     least squares
>> >     >> and have access to the covariance matrix of the result. I
>> >     summarize my
>> >     >> problem in the following example:
>> >     >>
>> >     >> import numpy as np
>> >     >> import scipy as sp
>> >     >> from scipy.optimize.minpack import curve_fit
>> >     >>
>> >     >> A, B = 5, 0.5
>> >     >> x = np.linspace(0, 5, 10)
>> >     >> real_f = lambda x: A * np.exp(-1.0 * B * x)
>> >     >> y = real_f(x)
>> >     >> ynoisy = y + 0.01 * np.random.randn(len(x))
>> >     >>
>> >     >> exp_f = lambda x, a, b: a * np.exp(-1.0 * b * x)
>> >     >>
>> >     >> # this line raises the error:
>> >     >>
>> >     >>
>> >     >> #  actual and predicted relative reductions in the sum of squares
>> >     >>
>> >     >> #  are at most 0.000000 and the relative error between two
>> >     >>
>> >     >> #  consecutive iterates is at most 0.000000
>> >     >>
>> >     >> params, cov = curve_fit(exp_f, x, ynoisy)
>> >     >
>> >
>> >     As you would see, the curve is very poorly defined with those model
>> >     parameters and range. So you are asking a lot from your model and
>> >     data. At least you need a wider range with those parameters or Josef
>> >     says different parameter(s):
>> >
>> >     > this might be the same as
>> >      http://projects.scipy.org/scipy/ticket/984 and
>> >     > http://mail.scipy.org/pipermail/scipy-user/2009-August/022090.html
>> >     >
>> >     > If I increase your noise standard deviation from 0.1 to 0.2 then
>> >     I do get
>> >     > correct estimation results in your example.
>> >     >
>> >     >>
>> >     >> I have tried to use the minpack.leastsq function directly with
>> >     similar
>> >     >> results. I also tried taking the log and fitting to a line with
>> >     no success.
>> >     >> The results are the same using scipy 0.7.1 as well as
>> >     0.8.0.dev5953. Am I
>> >     >> not using the curve_fit function correctly?
>> >     >
>> >     > With   minpack.leastsq   error code 2 should be just a warning.
>> >     If you get
>> >     > incorrect parameter estimates with optimize.leastsq, besides the
>> >     warning, could
>> >     > you post the example so I can have a look.
>> >     >
>> >     > It looks like if you take logs then you would have a problem
>> >     that is linear in
>> >     > (transformed) parameters, where you could use linear least
>> >     squares if you
>> >     > just want a fit without the standard errors of the original
>> >     parameters
>> >     > (constant)
>> >
>> >     The errors will be multiplicative rather than additive.
>> >
>> >     Bruce
>> >
>> >     >
>> >     > I hope that helps.
>> >     >
>> >     > Josef
>> >     >
>> >     >
>> >     >> Thanks,
>> >     >> ~Kris
>> >     >> --
>> >     >> Heisenberg went for a drive and got stopped by a traffic cop.
>> >     >> "Do you know how fast you were going?" Heisenberg replied, "No,
>> >     but I know
>> >     >> where I am."
>> >     >>
>> >     >> _______________________________________________
>> >     >> SciPy-User mailing list
>> >     >> SciPy-User@scipy.org <mailto:SciPy-User@scipy.org>
>> >     >> http://mail.scipy.org/mailman/listinfo/scipy-user
>> >     >>
>> >     >>
>> >     > _______________________________________________
>> >     > SciPy-User mailing list
>> >     > SciPy-User@scipy.org <mailto:SciPy-User@scipy.org>
>> >     > http://mail.scipy.org/mailman/listinfo/scipy-user
>> >     >
>> >
>> >     Hi,
>> >     _______________________________________________
>> >     SciPy-User mailing list
>> >     SciPy-User@scipy.org <mailto:SciPy-User@scipy.org>
>> >     http://mail.scipy.org/mailman/listinfo/scipy-user
>> >
>> >
>> >
>> >
>> > --
>> > Heisenberg went for a drive and got stopped by a traffic cop. The cop
>> > asked, "Do you know how fast you were going?" Heisenberg replied, "No,
>> > but I know where I am."
>> > ------------------------------------------------------------------------
>> >
>> > _______________________________________________
>> > SciPy-User mailing list
>> > SciPy-User@scipy.org
>> > http://mail.scipy.org/mailman/listinfo/scipy-user
>> >
>>
>> _______________________________________________
>> SciPy-User mailing list
>> SciPy-User@scipy.org
>> http://mail.scipy.org/mailman/listinfo/scipy-user
>
>
>
> --
> Heisenberg went for a drive and got stopped by a traffic cop. The cop asked,
> "Do you know how fast you were going?" Heisenberg replied, "No, but I know
> where I am."
>
> _______________________________________________
> SciPy-User mailing list
> SciPy-User@scipy.org
> http://mail.scipy.org/mailman/listinfo/scipy-user
>
>

I haven't looked, but from your discussion, it looks like there is an
y = np.asarray(y)  missing in curve_fit ?

Josef
```