[Ifeffit] Issues with larch built-in shape functions for fitting

Matthew Newville matt.newville at gmail.com
Sat Nov 19 16:44:15 CST 2016


Hi Sean,


On Fri, Nov 18, 2016 at 6:09 PM, Sean Fackler <swfackler at lbl.gov> wrote:

> Dear Matt,
>
> I’ve been fitting with Larch and found a few issues with some of the
> functions from code based on the example: examples/fitting/doc_example2a.lar.
> It’s for fitting two gaussians and an error function. Briefly, the two
> issues are related to fitting parameters for erf() and asymmetrical
> distribution functions like lognormal() or breit_wigner() not outputting
> results.
>
> 1. When trying to define parameters for the error function erf() in the
> params Group I get the following error:
>
> ufunc 'erf' not supported for the input types, and the inputs could not be
> safely coerced to any supported types according to the casting rule
> ''safe’’.
>




> It appears to originate when minimizing and using the defined function.
> However if I simply define erf_cen=531 (explicit definition) and leave
> other definitions for erf_amp and erf_wid alone, minimize() appears to work
> but obviously does not fit for centering of the error function. That’s my
> current workaround. Any comments on this or a better solution would be
> appreciated. You can find the particular section of code on line 139 of the
> attached script where I redefine params so it “works". The attached
> data-set is also included so you can also see my fit.
>
>
When reporting a problem, please try to isolate the actual problem as much
as possible.  Your script is too long and complex to easily read and try to
debug.  It also runs for a long time.   So, I would say "your script
worked" -- it ran for a while without error before I killed it.   It took
me a while to figure out what precisely you were saying was not working.

I suspect that the problem is with some of the magic that makes

    p1 = pars.amp1 * gaussian(data.e, pars.cen1, pars.wid1)
    p2 = pars.amp2 * gaussian(data.e, pars.cen2, pars.wid2)
    p3 = pars.amp3 * gaussian(data.e, pars.cen3, pars.wid3)
    e1 = pars.off + pars.erf_amp * erf(pars.erf_wid * (data.e -
pars.erf_cen))

when 'pars.erf_wid' is a Parameter object and 'data.e' is a Pandas.Series
--neither of these are precisely numeric objects, and though coercion to a
number works most of the time, it looks like it is not working inside the
erf() function call.  I believe that if you explicitly use the 'value'
attribute of the parameters, this will work better:

   e1 = pars.off + pars.erf_amp * erf(pars.erf_wid.value * (data.e -
pars.erf_cen.value))

FWIW, it works for gaussian() because each function argument is really a
numpy array, pandas Series, or a Parameter, but with erf() the argument is
a pandas.Series (or numpy array) of object type.

I believe these coercion issues are fixed in lmfit (which started as a
side-project of Larch, has taken on a life of its own).  In fact, the basic
fitting and lineshapes thing in Larch should just be replaced with lmfit.
More people are using this so it's gotten far ahead of Larch especially for
fitting data to sums of lineshapes.    The Peak Fitting GUI I'm working on
uses Larch for much of the processing, but lmfit for the actual fitting --
I'm hoping to get a first-release of this out soon.   You might find lmfit
somewhat easier to work with than Larch fitting too...

Anyway, the short answer is: try using "pars.PAR.value" instead of
"pars.PAR" if you run into trouble -- that will really be a float, not some
Parameter object that tries to act like a float.

--Matt Newville <newville at cars.uchicago.edu> 630-252-0431
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://millenia.cars.aps.anl.gov/pipermail/ifeffit/attachments/20161119/2cdd3061/attachment.html>


More information about the Ifeffit mailing list