def residual(pars, x, sigma=None, data=None): yg = gauss(x, pars["amp_g"].value, pars["cen_g"].value, pars["wid_g"].value) yl = loren(x, pars["amp_l"].value, pars["cen_l"].value, pars["wid_l"].value) frac = pars["frac"].value slope = pars["line_slope"].value offset = pars["line_off"].value model = (1 - frac) * yg + frac * yl + offset + x * slope if data is None: return model if sigma is None: return model - data return (model - data) / sigma
def residual(pars, x, sigma=None, data=None): yg = gaussian(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data) / sigma
def residual(pars, x, sigma=None, data=None): yg = gauss(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data)/sigma
def residual(pars, x, data=None): # print 'RESID ', pars['amp_g'].value, pars['amp_g'].init_value yg = gauss(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) frac = pars['frac'].value slope = pars['line_slope'].value offset = pars['line_off'].value model = (1-frac) * yg + frac * yl + offset + x * slope if data is None: return model return (model - data)
def test_constraints2(): """add a user-defined function to symbol table""" def residual(pars, x, sigma=None, data=None): yg = gaussian(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data) / sigma n = 601 xmin = 0. xmax = 20.0 x = linspace(xmin, xmax, n) data = (gaussian(x, 21, 8.1, 1.2) + loren(x, 10, 9.6, 2.4) + random.normal(scale=0.23, size=n) + x * 0.5) pfit = [ Parameter(name='amp_g', value=10), Parameter(name='cen_g', value=9), Parameter(name='wid_g', value=1), Parameter(name='amp_tot', value=20), Parameter(name='amp_l', expr='amp_tot - amp_g'), Parameter(name='cen_l', expr='1.5+cen_g'), Parameter(name='line_slope', value=0.0), Parameter(name='line_off', value=0.0) ] sigma = 0.021 # estimate of data error (for all data points) myfit = Minimizer(residual, pfit, fcn_args=(x, ), fcn_kws={ 'sigma': sigma, 'data': data }, scale_covar=True) def width_func(wpar): """ """ return 2 * wpar myfit.asteval.symtable['wfun'] = width_func myfit.params.add(name='wid_l', expr='wfun(wid_g)') myfit.leastsq() print(' Nfev = ', myfit.nfev) print(myfit.chisqr, myfit.redchi, myfit.nfree) report_fit(myfit.params) pfit = myfit.params fit = residual(myfit.params, x) assert (pfit['cen_l'].value == 1.5 + pfit['cen_g'].value) assert (pfit['amp_l'].value == pfit['amp_tot'].value - pfit['amp_g'].value) assert (pfit['wid_l'].value == 2 * pfit['wid_g'].value)
offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data)/sigma n = 601 xmin = 0. xmax = 20.0 x = linspace(xmin, xmax, n) data = (gauss(x, 21, 8.1, 1.2) + loren(x, 10, 9.6, 2.4) + random.normal(scale=0.23, size=n) + x*0.5) if HASPYLAB: pylab.plot(x, data, 'r+') pfit = [Parameter(name='amp_g', value=10), Parameter(name='cen_g', value=9), Parameter(name='wid_g', value=1), Parameter(name='amp_tot', value=20), Parameter(name='amp_l', expr='amp_tot - amp_g'), Parameter(name='cen_l', expr='1.5+cen_g'), Parameter(name='wid_l', expr='2*wid_g'),
def test_constraints(): def residual(pars, x, sigma=None, data=None): yg = gaussian(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data)/sigma n = 601 xmin = 0. xmax = 20.0 x = linspace(xmin, xmax, n) data = (gaussian(x, 21, 8.1, 1.2) + loren(x, 10, 9.6, 2.4) + random.normal(scale=0.23, size=n) + x*0.5) pfit = [Parameter(name='amp_g', value=10), Parameter(name='cen_g', value=9), Parameter(name='wid_g', value=1), Parameter(name='amp_tot', value=20), Parameter(name='amp_l', expr='amp_tot - amp_g'), Parameter(name='cen_l', expr='1.5+cen_g'), Parameter(name='wid_l', expr='2*wid_g'), Parameter(name='line_slope', value=0.0), Parameter(name='line_off', value=0.0)] sigma = 0.021 # estimate of data error (for all data points) myfit = Minimizer(residual, pfit, fcn_args=(x,), fcn_kws={'sigma':sigma, 'data':data}, scale_covar=True) myfit.prepare_fit() init = residual(myfit.params, x) myfit.leastsq() print(' Nfev = ', myfit.nfev) print( myfit.chisqr, myfit.redchi, myfit.nfree) report_fit(myfit.params) pfit= myfit.params fit = residual(myfit.params, x) assert(pfit['cen_l'].value == 1.5 + pfit['cen_g'].value) assert(pfit['amp_l'].value == pfit['amp_tot'].value - pfit['amp_g'].value) assert(pfit['wid_l'].value == 2 * pfit['wid_g'].value)
def test_constraints(with_plot=True): with_plot = with_plot and HASPYLAB def residual(pars, x, sigma=None, data=None): yg = gaussian(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data) / sigma n = 201 xmin = 0. xmax = 20.0 x = linspace(xmin, xmax, n) data = (gaussian(x, 21, 8.1, 1.2) + loren(x, 10, 9.6, 2.4) + random.normal(scale=0.23, size=n) + x*0.5) if with_plot: pylab.plot(x, data, 'r+') pfit = [Parameter(name='amp_g', value=10), Parameter(name='cen_g', value=9), Parameter(name='wid_g', value=1), Parameter(name='amp_tot', value=20), Parameter(name='amp_l', expr='amp_tot - amp_g'), Parameter(name='cen_l', expr='1.5+cen_g'), Parameter(name='wid_l', expr='2*wid_g'), Parameter(name='line_slope', value=0.0), Parameter(name='line_off', value=0.0)] sigma = 0.021 # estimate of data error (for all data points) myfit = Minimizer(residual, pfit, fcn_args=(x,), fcn_kws={'sigma':sigma, 'data':data}, scale_covar=True) myfit.prepare_fit() init = residual(myfit.params, x) myfit.leastsq() print(' Nfev = ', myfit.nfev) print( myfit.chisqr, myfit.redchi, myfit.nfree) report_fit(myfit.params, min_correl=0.3) fit = residual(myfit.params, x) if with_plot: pylab.plot(x, fit, 'b-') assert(myfit.params['cen_l'].value == 1.5 + myfit.params['cen_g'].value) assert(myfit.params['amp_l'].value == myfit.params['amp_tot'].value - myfit.params['amp_g'].value) assert(myfit.params['wid_l'].value == 2 * myfit.params['wid_g'].value) # now, change fit slightly and re-run myfit.params['wid_l'].expr = '1.25*wid_g' myfit.leastsq() report_fit(myfit.params, min_correl=0.4) fit2 = residual(myfit.params, x) if with_plot: pylab.plot(x, fit2, 'k') pylab.show() assert(myfit.params['cen_l'].value == 1.5 + myfit.params['cen_g'].value) assert(myfit.params['amp_l'].value == myfit.params['amp_tot'].value - myfit.params['amp_g'].value) assert(myfit.params['wid_l'].value == 1.25 * myfit.params['wid_g'].value)
slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data) / sigma n = 601 xmin = 0. xmax = 20.0 x = linspace(xmin, xmax, n) data = (gauss(x, 21, 8.1, 1.2) + loren(x, 10, 9.6, 2.4) + random.normal(scale=0.23, size=n) + x * 0.5) if HASPYLAB: pylab.plot(x, data, 'r+') pfit = [ Parameter(name='amp_g', value=10), Parameter(name='cen_g', value=9), Parameter(name='wid_g', value=1), Parameter(name='amp_tot', value=20), Parameter(name='amp_l', expr='amp_tot - amp_g'), Parameter(name='cen_l', expr='1.5+cen_g'), Parameter(name='wid_l', expr='2*wid_g'), Parameter(name='line_slope', value=0.0), Parameter(name='line_off', value=0.0)
xmax = 20.0 x = linspace(xmin, xmax, n) noise = random.normal(scale=0.2, size=n) p_true = Parameters() frac = 0.37 p_true.add('amp_g', value=21.0) p_true.add('cen_g', value=8.1) p_true.add('wid_g', value=1.6) p_true.add('cen_l', value=13.1) p_true.add('frac', value=frac) p_true.add('line_off', value=-1.023) p_true.add('line_slope', value=0.62) data = ((1-frac)*gauss(x, p_true['amp_g'].value, p_true['cen_g'].value, p_true['wid_g'].value) + frac*loren(x, 0.5*p_true['amp_g'].value, p_true['cen_l'].value, 2.5*p_true['wid_g'].value) + x*p_true['line_slope'].value + p_true['line_off'].value ) + noise if HASPYLAB: pylab.plot(x, data, 'r+') p_fit = Parameters() max_x = x[where(data == max(data))][0] print 'MAX X = ', max_x p_fit.add('amp_g', value=15.0) p_fit.add('cen_g', value=max_x) p_fit.add('wid_g', value=2.0) p_fit.add('frac', value=0.50) p_fit.add('amp_l', expr='0.5*amp_g') p_fit.add('cen_l', value=12.5) p_fit.add('wid_l', expr='2.5*wid_g')
def test_constraints(with_plot=True): with_plot = with_plot and HASPYLAB def residual(pars, x, sigma=None, data=None): yg = gaussian(x, pars['amp_g'].value, pars['cen_g'].value, pars['wid_g'].value) yl = loren(x, pars['amp_l'].value, pars['cen_l'].value, pars['wid_l'].value) slope = pars['line_slope'].value offset = pars['line_off'].value model = yg + yl + offset + x * slope if data is None: return model if sigma is None: return (model - data) return (model - data) / sigma n = 201 xmin = 0. xmax = 20.0 x = linspace(xmin, xmax, n) data = (gaussian(x, 21, 8.1, 1.2) + loren(x, 10, 9.6, 2.4) + random.normal(scale=0.23, size=n) + x * 0.5) if with_plot: pylab.plot(x, data, 'r+') pfit = [ Parameter(name='amp_g', value=10), Parameter(name='cen_g', value=9), Parameter(name='wid_g', value=1), Parameter(name='amp_tot', value=20), Parameter(name='amp_l', expr='amp_tot - amp_g'), Parameter(name='cen_l', expr='1.5+cen_g'), Parameter(name='wid_l', expr='2*wid_g'), Parameter(name='line_slope', value=0.0), Parameter(name='line_off', value=0.0) ] sigma = 0.021 # estimate of data error (for all data points) myfit = Minimizer(residual, pfit, fcn_args=(x, ), fcn_kws={ 'sigma': sigma, 'data': data }, scale_covar=True) myfit.prepare_fit() init = residual(myfit.params, x) myfit.leastsq() print(' Nfev = ', myfit.nfev) print(myfit.chisqr, myfit.redchi, myfit.nfree) report_fit(myfit.params, min_correl=0.3) fit = residual(myfit.params, x) if with_plot: pylab.plot(x, fit, 'b-') assert (myfit.params['cen_l'].value == 1.5 + myfit.params['cen_g'].value) assert (myfit.params['amp_l'].value == myfit.params['amp_tot'].value - myfit.params['amp_g'].value) assert (myfit.params['wid_l'].value == 2 * myfit.params['wid_g'].value) # now, change fit slightly and re-run myfit.params['wid_l'].expr = '1.25*wid_g' myfit.leastsq() report_fit(myfit.params, min_correl=0.4) fit2 = residual(myfit.params, x) if with_plot: pylab.plot(x, fit2, 'k') pylab.show() assert (myfit.params['cen_l'].value == 1.5 + myfit.params['cen_g'].value) assert (myfit.params['amp_l'].value == myfit.params['amp_tot'].value - myfit.params['amp_g'].value) assert (myfit.params['wid_l'].value == 1.25 * myfit.params['wid_g'].value)