fitting parameters for a system of differential equations

I have defined a system of differential equations controlled by three parameters. it describes the time evolution of 3 species defined by 3 rate constants KK[0], KK[1] and KK[2]. The model is supposed to describe data that is presented in graph zero as lines and markers (the data describes the species labeled E0 and E2. E1, in this case, is just obtained by assuming E0 + E1 + E2 = 1). my goal here is to vary the KK parameters to get as close as possible to the data. ( I realize the fit will may not be great, and getting a good fit may require a more sophisticated model, just want to see how closely this model can fit)  How can i do this with Igor? ihave attached the relevant pxp file which has all the data and the model in it. 

 

 

kinetic model and data to be fit kinetic ODE sim.pxp

Fitting two components is a bit tricky, start by fitting one component. I've looked at your experiment file and I'm a little bit confused about your intentions; it looks like you started from the fit function in the Differential Equation Demo experiment, which is too simple for your case.

You have three rate constants- if they are independent, then you have three fit coefficients just for the rate constants. It looks like the initial conditions are simply E0=1, E1=E2=0, so no need to put those into the fit coefficients. It's not clear that you need fit coefficients other than your rate constants. Here is a possible fit function for fitting the third component:

Function Fit_Chem_kin(pw, yw, xw) : FitFunc
    wave pw, yw,  xw
 
// pw contains the rate constants
 
    Make/FREE/D/N=(numpnts(yw), 3) ODEsolution
    ODEsolution[0][0] = 1
    ODEsolution[0][1] = 0
    ODEsolution[0][2] = 0
    IntegrateODE /X=xw chem_kin,  pw, ODEsolution       // we use pw as the parameter wave for IntegrateODE if the rate constants are the only fit coefficients
    yw = ODEsolution[p][2]                          // [2] if we are fitting the third component
End

A flexible but inefficient way to fit the first and third components would be to write two fit functions, one for each component. Then use the Global Fit package to fit the two components together. That will evaluate the ODE twice as many times as necessary, though.

Another way to fit two components would be to concatenate the two components into a single wave, one after the other. The wave would have 2N components, the first N would be the first component, the second N would be the third component. You also need to make an X wave that has all the X values twice, one set for the first component, one for the third. The fit function might look like this:

Function Fit_Chem_kin_2Components(pw, yw, xw) : FitFunc
    wave pw, yw,  xw
 
// pw contains the rate constants
    Variable npnts = numpnts(yw)
    Make/FREE/D/N=(npnts/2, 3) ODEsolution
    Duplicate/FREE/R=[0,npnts/2-1] xw, ODEx             // just need half the X values for the ODE solution
    ODEsolution[0][0] = 1
    ODEsolution[0][1] = 0
    ODEsolution[0][2] = 0
    IntegrateODE /X=ODEx chem_kin,  pw, ODEsolution     // we use pw as the parameter wave for IntegrateODE if the rate constants are the only fit coefficients
    yw[0,npnts/2-1] = ODEsolution[p][0]                         // first component
    yw[npnts/2, npnts-1] = ODEsolution[p][2]                    // third component
End

FuncFit doesn't know that your fit function expects two data sets in the yw wave, so the /D (autodestination) doesn't work. You can use /D=destwave, though, because all the numbers of points and point order will Just Work that way.

Good luck with this project, and feel free to ask more questions. I guarantee you will have more :)

Dear All,

I found this topic very useful regarding the data analysis I am currently doing on enzymatic reactions monitored using fluorophores. 

@johnweeks, you propose a fitting function in which the number of points of the ODEsolution is identical to the one of the data set wave. Would the quality of the fit better with a higher number of points in the ODEsolution ? 

In that spirit, I was trying the following:

Function ChemKinetic(pw, tt, yw, dydt)
    Wave pw // pw[0] = k1, pw[1] = k-1, pw[2] = k3
    Variable tt // time value at which to calculate derivatives
    Wave yw // yw[0]-yw[3] containing concentrations of A,B,C,D
    Wave dydt   // wave to receive dA/dt, dB/dt etc. (output)
    dydt[0] = -pw[0]*yw[0]*yw[1]+pw[1]*yw[2]
    dydt[1] = -pw[0]*yw[0]*yw[1]+pw[1]*yw[2]
    dydt[2] = pw[0]*yw[0]*yw[1]-pw[1]*yw[2]-pw[2]*yw[2]
    dydt[3] = pw[2]*yw[2]
End

Function Fit_Chem_kin_l(pw, yw, xw) : FitFunc
    wave pw, yw,  xw

    Variable nb=numpnts(xw)
    Variable pp=xw[nb-1]
    Make/FREE/D/N=100 xx
    SetScale/I x,0,pp,"",xx
    xx=x
    Make/FREE/D/N=(100, 4) ODEsolution
    ODEsolution[0][0] = 1e-6
    ODEsolution[0][1] = 10e-6
    ODEsolution[0][2] = 0
    ODEsolution[0][3] = 0
    IntegrateODE /X=xx ChemKinetic,  pw, ODEsolution      
    yw = ODEsolution[p][3]                        
End

Here I am using xw (which define the total experimental observation time from 0 to x seconds) to create a reference wave that will be used as x-axis values during the numerical integration. 

Unfortunately the scaling along the x (temporal) axis seemed to be wrong so I guess that I did a mistake. Maybe you can comment on that ? 

Thank a lot.

Integrating at a finer X resolution will not help the quality of the solution. Internally, IntegrateODE adjusts step size to maintain the requested accuracy estimate. It will take as many steps between your X values as are required to maintain accuracy.

The error in your code is using [p] on the right-hand side of the final wave assignment. You need to use the values from xw:

yw = ODEsolution(xw[p])[3]    

 

Thank a lot ! I to your explanation regarding the number of points. So I do not need to increase it to get better results. 

For the code I guess you meant:

yw = ODEsolution(xx[p])[3]

not

yw = ODEsolution(xw[p])[3]

 

No, I really meant xw[p].

The reason is that the X values where you need to fill in yw are in the wave xw. The [p] means to use the point numbers from the left side of the wave assignment; xw[p] is the correct X value for the point in yw. Using () for indexing the rows of ODEsolution means to index by scaled X value rather than by point numbers.

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More