Fitting Y vs X without direct equation

Hi all,

I'm a new user of Igor and, up to now, I only performed curve fitting and global fitting without programming. I think I'll have to start with that in the near future and hope getting some help here!

I have to fit experimental data corresponding to signal intensity of an analyte (host at fixed concentration, H) vs concentration of added guest (G) to study binding equilibria; so I(G). Of course, the signal can be related to the concetration at the equilibrium of the different species present (so different from the known total concentration); but except for the simpliest case, there is no direct relation between I and G (and I'm thus unable to fit the data with a user-defined function). Indeed, a cubic relation should be solved to build the relation (which depends from the situation considered).

After reading some post on this website, I guess I should use "all-at-once" fitting function, but coupled with a find roots function. I hope this message is not too messy, but, as I have to consider different situations, I don't have a unique mathematical model to solve.

Is the all-at-once + findroots strategy the right one?

Thanks for all!

Not being a chemist, I don't fully understand the details of your equation requirements. However, Igor Pro does have the capability of fitting implicit functions. I suggest you look at this by executing in the command line:
DisplayHelpTopic "Fitting Implicit Functions"
Thanks for the tip. But I think my problem is more important... To be more precise, I can give you one example of a fitting I'd like to perform.

The data I obtained is a wave I, as function of a wave Gtot. There is no obvious relation, but I can be related to concentration at equilibrium, Heq and Geq (with various parameters, a, b, K1, K2, Htot (fixed), I have to determine thanks to the fitting process).

I = Heq + a * K1 * Heq^2 * Geq + b * sqrt(K1 * K2) * Heq * Geq

Geq and Heq can be related to Gtot, the known x wave, but there is a cubic expression for Heq.

Geq = Gtot / (1+sqrt(K1 * K2) * Heq + K1 * Heq^2)
0 = K1 * Heq^3 + (K1 * Gtot - K1 Htot + sqrt(K1 * K2) ) * Heq^2 + (1+ sqrt(K1 * K2) *Gtot - Htot * sqrt(K1 * K2) ) * Heq - Htot

As I have no access to Heq as function of Gtot, I cannot use implicit fitting (I guess). Do you think that such a fitting process is achievable?
So you're saying that you need to solve the second equation for Heq given the fit coefficients and Gtot? In that case, you may need to use FindRoots as you said in the beginning. I don't think you need to use an all-at-once fitting function because you need to solve for every value of Gtot (which, if I have understood is your independent variable).

Do not attempt to do the fit right away. First you need to figure out how to use FindRoots to solve your equation. After that works, then use it to define your fitting function. Make sure it returns reasonable values for reasonable coefficients. Only then should you attempt to actually do a fit.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
So you're saying that you need to solve the second equation for Heq given the fit coefficients and Gtot?

Exactly! As you proposed, I started trying to find roots for Heq. It works, except I didn't find out how to introduce Gtot as a separate coefficient (and I didn't find such a way to do that within the help doc). This is problematic for the fitting as I cannot put Gtot as x to perform the fitting... I don't know if I'm progressing in the good direction...

Function Eq21(w, x)
    Wave w //, Gtot
    Variable x
   
        // w[0] = K1
        // w[1] = K2
        // w[2] = Gtot
        // w[3] = Htot
        // w[4] = alpha
        // w[5] = beta
        // w[6] = Cst

    return w[0] * x^3 + (w[0] * w[2] - w[0] * w[3] + sqrt(w[0] * w[1]) ) * x^2 + (1+ sqrt(K1 * K2) *w[2] - w[3] * sqrt(w[0] * w[1]) ) * x - w[3]

    // return w[0] * x^3 + (w[0] * Gtot - w[0] * w[3] + sqrt(w[0] * w[1]) ) * x^2 + (1+ sqrt(K1 * K2) *Gtot - w[3] * sqrt(w[0] * w[1]) ) * x - w[3] // tryed to use a 2D function but failed

End

Function FitEq21(w,x) : FitFunc
    WAVE w
    Variable x
   
    wave Gtot

    //CurveFitDialog/ x
    //CurveFitDialog/ Coefficients 7
    //CurveFitDialog/ w[0] = K1
    //CurveFitDialog/ w[1] = K2
    //CurveFitDialog/ w[2] = Gtot
    //CurveFitDialog/ w[3] = Htot
    //CurveFitDialog/ w[4] = alpha
    //CurveFitDialog/ w[5] = beta
    //CurveFitDialog/ w[6] = Cst

    make/O/N=(numpnts(Gtot)) Heq, Qeq
   
    variable i
       
    for(i=0;iter<numpnts(Gtot);i+=1)
        FindRoots/L=0/H=(w[3]) Eq21, w
        Heq[i] = V_root
        Qeq[i] = w[2] / (1+sqrt(w[0] * w[1]) * Heq[i] + w[0] * Heq[i]^2)
    endfor
   
    return w[6] * (Heq + w[4] * w[0] * Heq^2 * Qeq + w[5] * sqrt(w[0] * w[1]) * Heq * Qeq)
End
Well, indeed, Gtot is my independnat variable x. My problem is that I don't know how to handle this, as x should be used as a parameter (encoded as w[2]) for finding roots of Eq21 which will give a couple Geq and Heq for each x (Gtot) value... Maybe I should use a 2D function for Eq21, but I failed.

Sorry, I'm very bad... still a lot of progress to do in order to use Igor properly...
This is making my head spin... there are too many variables to keep track of.

You have
p=(a, b, K1, K2)
I = f(Heq, Geq; p)

Geq = f(Gtot, Heq; p)
0 = f(Heq, Gtot;Htot, p)

I've used the arbitrary convention there that things to the right of the semicolon are known constants.
In order to compute a value of I, you need to find Heq and Geq. You have an expression for Geq that depends on Heq and Gtot. For a given value of Gtot (to compute a single model value of I, you will deal with just one value of Gtot at a time) you need to solve that last equation for Heq so that you can compute the second-to-last equation. So in the FindRoots context Heq confusingly becomes X since that's what's being varied to find the solution. In the context of the fitting function, a given value of Gtot is called "x" also.

Step 1 might be to rename the various things called "x" so that they have distinct names. You can do that because "x" has no intrinsic meaning, they are just ways to talk about input variables.

You don't need to look up the Gtot wave. You only need one value from the Gtot wave at a time, and that value is supplied via the x input parameter to your fitting function.

You may need to construct a new parameter wave to use with FindRoots so that you can transmit that value of Gtot to the object function used by FindRoots. Maybe something like
Function FitEq21(pw, Gtot) : FitFunc
    WAVE pw
    Variable Gtot

    Make/O/D/N=8/FREE FRpw
    FRpw[0,6] = pw[p]
    FRpw[7] = Gtot
    FindRoots/L=minHeq/H=maxHeq Eq21, FRpw
    Variable Heq = V_Root

    Variable Geq = ...
    return f(Geq, Heq, pw)
end

Since I didn't actually implement your equations and all, there could well be mistake in this. But I think I've got the essential structure of it.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Wonderful it works fine! Sorry to have made spin your head... Just a last thing to add: thank you very much for your help!

All the best,