Exemplo n.º 1
0
 def simulate(self, data):
     varying, varynames, dependent, _ = prepare_params(
         self.params, data.meta)
     pd = dict((p.name, p.value) for p in self.params)
     update_params(dependent, data.meta, pd)
     yy = self.fcn(pd, data.x)
     new = data.copy()
     new.y = yy
     new.dy = zeros(len(yy))
     return new
Exemplo n.º 2
0
def do_fit(data, fcn, params, add_kw):
    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    def leastsqfcn(params, data):
        pd = dict(zip(varynames, params))
        update_params(dependent, meta, pd)
        return (fcn(pd, x) - y) / dy

    initpars = []
    warned = False
    for p in varying:
        initpars.append(p.value)
        if (p.pmin is not None or p.pmax is not None) and not warned:
            print('Sorry, scipy backend cannot handle parameter bounds.')
            warned = True

    try:
        res = leastsq(leastsqfcn,
                      initpars,
                      args=(data, ),
                      full_output=1,
                      **add_kw)
    except Exception as e:
        return False, str(e), 0

    popt, pcov, infodict, errmsg, ier = res
    success = (ier in [1, 2, 3, 4])

    nfree = len(y) - len(varying)
    if nfree > 0 and pcov is not None:
        s_sq = (leastsqfcn(popt, data)**2).sum() / nfree
        pcov = pcov * s_sq
    else:
        pcov = inf

    pd = {}
    for i, p in enumerate(varying):
        pd[p.name] = popt[i]
        if pcov is not inf:
            p.error = sqrt(pcov[i, i])
        else:
            p.error = 0
        p.correl = {}  # XXX
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]

    return success, errmsg, get_chisqr(fcn, x, y, dy, params)
Exemplo n.º 3
0
def do_fit(data, fcn, params, add_kw):

    # lmfit can handle expression-based parameters itself, but that is
    # a) buggy (cannot pass custom items into namespace without subclass)
    # and b) it is better to use the same mechanism in all backends

    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    lmfparams = Parameters()
    for p in varying:
        lmfparams.add(p.name, p.value, min=p.pmin, max=p.pmax)

    def lmfitfcn(lmfparams, data):
        pd = dict((pn, lmfparams[pn].value) for pn in varynames)
        update_params(dependent, meta, pd)
        return (fcn(pd, x) - y) / dy

    printReport = add_kw.pop('printReport', False)

    try:
        out = minimize(lmfitfcn, lmfparams, args=(data,), **add_kw)
    except Exception as e:
        print(str(e))
        return False, str(e), 0

    if printReport:
        report_fit(out.params)

    pd = dict((pn, out.params[pn].value) for pn in varynames)
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]
        if p.name in lmfparams:
            p.error = out.params[p.name].stderr
            p.correl = out.params[p.name].correl
        else:
            p.error = 0
            p.correl = {}

    # sadly, out.message is a bit buggy
    message = ''
    if not out.success:
        message = out.lmdif_message
    if not out.errorbars:
        message += ' Could not estimate error bars.'
    return out.success, message, out.redchi
Exemplo n.º 4
0
def do_fit(data, fcn, params, add_kw):
    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    def minuitfcn(*args):
        pd = dict(zip(varynames, args))
        update_params(dependent, meta, pd)
        return ((fcn(pd, x) - y)**2 / dy**2).sum()

    printReport = add_kw.pop('printReport', False)

    marg = dict(
        print_level=int(printReport),
        forced_parameters=varynames,
    )
    marg.update(add_kw)
    if 'errordef' not in marg:
        marg['errordef'] = 1
    for p in varying:
        marg[p.name] = p.value
        marg['error_' + p.name] = 100*p.delta or p.value/100. or 0.01
        if p.pmin is not None or p.pmax is not None:
            marg['limit_' + p.name] = (p.pmin is None and -1e8 or p.pmin,
                                       p.pmax is None and +1e8 or p.pmax)

    m = Minuit(minuitfcn, **marg)
    try:
        m.migrad()
        m.hesse()
    except Exception as e:
        return False, str(e), 0
    # m.minos()  -> would calculate more exact and asymmetric errors

    pd = dict((pn, m.values[pn]) for pn in varynames)
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]
        if p.name in varynames:
            p.error = m.errors[p.name]
            p.correl = {}  # XXX
        else:
            p.error = 0
            p.correl = {}

    return True, '', get_chisqr(fcn, x, y, dy, params)
Exemplo n.º 5
0
def do_fit(data, fcn, params, add_kw):
    x, y, dy = data.fit_columns
    meta = data.meta
    varying, varynames, dependent, _ = prepare_params(params, meta)

    def leastsqfcn(x, params):
        pd = dict(zip(varynames, params))
        update_params(dependent, meta, pd)
        return fcn(pd, x)

    initpars = []
    initdp = []
    warned = False
    for p in varying:
        initpars.append(p.value)
        initdp.append(p.delta or p.value / 10. or 0.01)
        if (p.pmin is not None or p.pmax is not None) and not warned:
            print('Sorry, unifit backend cannot handle parameter bounds.')
            warned = True
    try:
        res = __leastsq((x, y, dy), leastsqfcn, initpars, initdp, **add_kw)
    except Exception as e:
        raise
        return False, str(e), 0

    success = res['converged']
    errmsg = res['errmsg']

    pd = {}
    for i, p in enumerate(varying):
        pd[p.name] = res['values'][i]
        p.error = res['errors'][i]
        p.correl = {}  # XXX
    update_params(dependent, meta, pd)
    for p in params:
        p.value = pd[p.name]

    return success, errmsg, get_chisqr(fcn, x, y, dy, params)
Exemplo n.º 6
0
 def minuitfcn(*args):
     pd = dict(zip(varynames, args))
     update_params(dependent, meta, pd)
     return ((fcn(pd, x) - y)**2 / dy**2).sum()
Exemplo n.º 7
0
 def leastsqfcn(params, data):
     pd = dict(zip(varynames, params))
     update_params(dependent, meta, pd)
     return (fcn(pd, x) - y) / dy
Exemplo n.º 8
0
 def leastsqfcn(x, params):
     pd = dict(zip(varynames, params))
     update_params(dependent, meta, pd)
     return fcn(pd, x)
Exemplo n.º 9
0
 def lmfitfcn(lmfparams, data):
     pd = dict((pn, lmfparams[pn].value) for pn in varynames)
     update_params(dependent, meta, pd)
     return (fcn(pd, x) - y) / dy