# [SciPy-User] Nonlinear fit to multiple data sets with a shared parameter, and three variable parameters.

Charles R Harris charlesr.harris@gmail....
Wed Apr 3 13:08:11 CDT 2013

```On Wed, Apr 3, 2013 at 11:44 AM, <josef.pktd@gmail.com> wrote:

> On Wed, Apr 3, 2013 at 12:09 PM, Troels Emtekær Linnet
> <tlinnet@gmail.com> wrote:
> > Dear Scipy users.
> >
> > I am having trouble to implement what is probably known as:
> > Nonlinear fit to multiple data sets with shared parameters
> >
> > I haven't been able to find a solution for this in scipy, and I would be
> > happy to hear if someone could guide med how to fix this.
> >
> > I have a set of measured NMR peaks.
> > Each peak has two eksperiment x values, x1, x2, which I can fit to a
> > measured Y value.
> > I have used lmfit, which extends scipy leastsq with some boundary
> options.
> >
> > For each peak, i can fit the following function:
> >
> > --------------------------------------
> > def R1r_exch(pars,inp,data=None,eps=None):
> >     tiltAngle,omega1=inp
> >     R1 = pars['R1'].value
> >     R2 = pars['R2'].value
> >     kEX = pars['kEX'].value
> >     phi = pars['phi'].value
> >     model =
> >
> R1*cos(tiltAngle*pi/180)**2+(R2+phi*kEX/((2*pi*omega1/tan(tiltAngle*pi/180))**2+(2*pi*omega1)**2+kEX**2))*sin(tiltAngle*pi/180)**2
> >     if data is None:
> >         return model
> >     if eps is None:
> >         return (model - data)
> >     return (model-data)/eps
> >
> > calling with
> >
> > datX = [tilt,om1]
> > par = lmfit.Parameters()
> > par.add('R1', value=1.0, vary=True)
> > par.add('R2', value=40.0, vary=True)
> > par.add('kEX', value=10000.0, vary=False, min=0.0)
> > par.add('phi', value=100000.0, vary=True, min=0.0)
> > lmf = lmfit.minimize(R1r_exch, par, args=(datX, R1rex,
> > R1rex_err),method='leastsq')
> >
> > print lmf.success, lmf.nfev
> > print par['R1'].value, par['R2'].value, par['kEX'].value,
> par['phi'].value
> > fig = figure('R1r %s'%NI)
> > ax = fig.add_subplot(111)
> > calcR1r = R1r_exch(par,datX)
> > tilt_s, om1_s = zip(*sorted(zip(datX[0], datX[1])))
> > datXs = [array(tilt_s), array(om1_s)]
> > calcR1rs = f_R1r_exch_lmfit(par,datXs)
> > -----------------------------------------------------------
> >
> > That goes fine for each single peak.
> >
> > But now I wan't to do global fitting.
> >
> http://www.originlab.com/index.aspx?go=Products/Origin/DataAnalysis/CurveFitting/GlobalFitting
> >
> http://www.wavemetrics.com/products/igorpro/dataanalysis/curvefitting/globalfitting.htm
> >
> > I would like to fit the nonlinear model to several peak data sets
> > simultaneously.
> > The parameters "R1,R2 and phi" should be allowed to vary for each NMR
> peak,
> > while kEX should be global and shared for all NMR peaks.
> >
> >
> > Is there anybody who would be able to help finding a solution or guide
> med
> > to a package?
>
> The general solution for this kind of problems in statistics is to stack
> the
> fitting problems into one big problem.
>
> Stack all observations, concatenate the sub-problem specific
> parameters and the common parameters, and then write a model/error
> function that calculates all sub-problems and returns the stacked
> fitting error.
>
>
In this case it looks like things can be simplified even further as the
function is linear in R1, R2 unless I made a parse mistake. Hence once kEX
is given they can be solved for using linear least squares, so it is
really  a 1D nonlinear least squares problem. You can either stack the
residuals of the linear fits and return that to leastsqr, or you can use
another minimiser and return the sum the squared residuals.

Chuck
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/scipy-user/attachments/20130403/562c2e25/attachment-0001.html
```