Is fixing (holding) fitting parameters the same as writing directly their values in function?

Hi all,

Could you please tell me, is fixing (holding) some parameters in fitting function equivalent to direct writing the values of these parameters in the expression of fitting function?

For example, I generated data using:

Make '1'
'1' = exp(-(p-60)^2/50)

In the first case, I have fitting function:

Function mygauss(w, x) : FitFunc
        Wave w
        Variable x
        return w[0]*exp(-(x-w[1])^2/(2*w[2]^2))
End

Let's designate w[0]=a, w[1]=b, w[2]=c.

I set initial guess for first two parameters: a_0=1, b_0 = 55. And I hold the third parameter: c = 5.

In the second case, I create the following fitting function:

Function mygauss(w, x) : FitFunc
        Wave w
        Variable x
        return w[0]*exp(-(x-w[1])^2/(2*5^2))
End

Thus, instead of parameter c, I wrote the exact constant value 5.

The question is: are these two cases equivalent to each other in sense of fitting procedure? Are these cases the same for Igor Pro? Or the first case is more difficult in sense of calculation?

I always thought that two mentioned cases are the same, but recently one person told me that this might not be true, so I'd like to clarify.

It all depends on what you mean by "same".

The result of the fit with the held coefficient will be the same as the result with the literal constant value in the code. The iterations may even take the same path through chi-square space because effectively a held parameter is taken out of the fit and made into a constant. But the way that constant is introduced is not quite the same, so there might be rounding errors that make very small differences.

The case with holding a coefficient will take some additional computation, though it is hard to say how much. Probably not much.

In reply to by johnweeks

johnweeks wrote:

It all depends on what you mean by "same".

The result of the fit with the held coefficient will be the same as the result with the literal constant value in the code. The iterations may even take the same path through chi-square space because effectively a held parameter is taken out of the fit and made into a constant. But the way that constant is introduced is not quite the same, so there might be rounding errors that make very small differences.

The case with holding a coefficient will take some additional computation, though it is hard to say how much. Probably not much.

Thank you! I noticed that for two built-in functions exp_XOffset and dblexp_XOffset there is possibility to set constant X0. But one could just hold X0 parameter like all other fitting parameters, am I right? It would be great, if there was possibility to set constants for user-defined functions. In Igor Pro help, I only found that one can set constants only for sum-of-fit-functions:

The syntax of the sum-of-fit-functions specification is as follows:
{{func1, coef1, keyword =value },{func2, coef2, keyword =value }, ...}

Available keyword is:

CONST={constants}

But, as I understood, it is not suitable for me, because I don't need to use sum-of-fit-functions.

The sum-of-fit-functions use of the CONST keyword applies only to built-in fit functions included in the sum.

It would be nice to have a method to designate a constant for user-defined fit functions, but I haven't figured out a good way to implement that yet. I was driven to implement constants for built-in function exactly for the case of exp_XOffset. You are right, that it would be much the same to have a fit coefficient and to hold it, but in the case of exp_XOffset you MUST hold that coefficient. Visions of  a deluge of tech support queries from folks that forgot to hold it, or that didn't realize you had to hold it, drove me to invent constants for built-in fit functions.

Your need for a constant is the same as for the x0 constant in exp_XOffset: your w[0] and w[2] are not independent.

There is another, ultimately flexible way to write a user-defined fit function, but it is difficult to use. That would be a structure-based fit function. The first part of the structure passed to your fit function must have the standard fit function information (coefficient wave, x value; or coefficient wave, y wave and x wave). The rest of the structure can be anything you like, including constants for your function. The drawback is that since Igor has no way to create a global structure, you must write a wrapper function that creates an instance of your structure, fills it in, then calls FuncFit. To learn more, execute this Igor command: DisplayHelpTopic "Structure Fit Functions"

Resuming the question - I have two fitting functions:

Function fit_1(w,v) : FitFunc
    Wave w
    Variable v

    //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    //CurveFitDialog/ Equation:
    //CurveFitDialog/ f(v) = I0*(2*pi*(v-v0+vQ)*T2f^2/(1+(2*pi*(v-v0+vQ)*T2f)^2)-2*pi*(v-v0-vQ)*T2f^2/(1+(2*pi*(v-v0-vQ)*T2f)^2))
    //CurveFitDialog/ End of Equation
    //CurveFitDialog/ Independent Variables 1
    //CurveFitDialog/ v
    //CurveFitDialog/ Coefficients 4
    //CurveFitDialog/ w[0] = I0
    //CurveFitDialog/ w[1] = T2f
    //CurveFitDialog/ w[2] = vQ
    //CurveFitDialog/ w[3] = v0

    return w[0]*(2*pi*(v-w[3]+w[2])*w[1]^2/(1+(2*pi*(v-w[3]+w[2])*w[1])^2)-2*pi*(v-w[3]-w[2])*w[1]^2/(1+(2*pi*(v-w[3]-w[2])*w[1])^2))
End

Function fit_2(w,v) : FitFunc
    Wave w
    Variable v

    //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will
    //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog.
    //CurveFitDialog/ Equation:
    //CurveFitDialog/ f(v) = I1*(2*pi*(v-v0+vQ1)*T2f1^2/(1+(2*pi*(v-v0+vQ1)*T2f1)^2)-2*pi*(v-v0-vQ1)*T2f1^2/(1+(2*pi*(v-v0-vQ1)*T2f1)^2))+I2*(2*pi*(v-v0+vQ2)*T2f2^2/(1+(2*pi*(v-v0+vQ2)*T2f2)^2)-2*pi*(v-v0-vQ2)*T2f2^2/(1+(2*pi*(v-v0-vQ2)*T2f2)^2))
    //CurveFitDialog/ End of Equation
    //CurveFitDialog/ Independent Variables 1
    //CurveFitDialog/ v
    //CurveFitDialog/ Coefficients 7
    //CurveFitDialog/ w[0] = I1
    //CurveFitDialog/ w[1] = I2
    //CurveFitDialog/ w[2] = T2f1
    //CurveFitDialog/ w[3] = T2f2
    //CurveFitDialog/ w[4] = vQ1
    //CurveFitDialog/ w[5] = vQ2
    //CurveFitDialog/ w[6] = v0

    return w[0]*(2*pi*(v-w[6]+w[4])*w[2]^2/(1+(2*pi*(v-w[6]+w[4])*w[2])^2)-2*pi*(v-w[6]-w[4])*w[2]^2/(1+(2*pi*(v-w[6]-w[4])*w[2])^2))+w[1]*(2*pi*(v-w[6]+w[5])*w[3]^2/(1+(2*pi*(v-w[6]+w[5])*w[3])^2)-2*pi*(v-w[6]-w[5])*w[3]^2/(1+(2*pi*(v-w[6]-w[5])*w[3])^2))
End

I have a number of experiments, each of them contains 23 experimental nuclear magnetic resonance spectra. In Igor Pro 8.03, in procedure, I've written function that uses two above pointed fitting functions in two runs. The purpose of my function is to fit all 23 spectra within single experiment. In the first run, I use fitting function fit_1. I hold the parameter v0 using the option /H="0001" when calling FuncFit. The fit_1 function fits quite well only beginning with 10th experimental spectrum, for example (in other experiments it can fit well beginning with 9th or 11th spectrum, or 12th spectrum; so it depends on experiment). The experimental spectra until 10th spectrum can't be fit well with the function fit_1 (I took the example when fit_1 can fit well beginning with 10th spectrum). When saying 'it fits well', I mean that fitting curve visually describes experimental points well and the errors of found parameters are small. Then I take two parameters found after fitting the 10th experimental spectrum, namely T2f and vQ. In the second run, I use fitting function fit_2. In the second run, I only fit 1st - 9th experimental spectra which couldn't be fit with function fit_1. When fitting in the second run, I hold the parameters T2f1, vQ1 and v0. The values of parameters T2f1 and vQ1 are equal to the values of T2f and vQ which were found when fitting the 10th spectrum. The values of the parameters T2f1 and vQ1 are the same for each spectrum in first 9 spectra. The free parameters are I1, I2, T2f2 and vQ2, so I need to find the values of these 4 parameters when fitting first 9 spectra. For example, the function fit_2 can fit 1st - 6th spectra quite well. But the rest of spectra, i.e. 7th, 8th and 9th spectra, can't be fit even with the function fit_2 - fitting curve visually describes experimental points poorly and the errors are big. The question is - if considering such quite complicated functions (fit_1 and fit_2), is it important to use constants, i.e.literal constant values in code, instead of holding fitting parameters? Maybe, if I use literal constant values for the parameters v0, T2f1, vQ1, the result of fitting will be better for 7th, 8th and 9th spectra? You advised to use Structure Fit functions, but I didn't yet try to use them, because until now I thought that holding (fixing) parameters will be enough. But recently one person again told me that when fit functions are complicated (fit_1 is two lorentzians, and fit_2 is four lorentzians), there is difference in using hold parameters and literal constant values in sense of covariation matrix. She said that even when holding parameters, these parameters are included in covariation matrix, i.e. they participate in fitting and complicate the calculation. I will provide information of my laptop - maybe it is important. The laptop is Lenovo Thinkpad X1, processor - Intel Core i7-7500U CPU @ 2.70GHz - 2.90GHz (2 cores), RAM = 8 GB. OS - Windows 10 (64-bit).

I'll throw a few alternate thoughts in the mix.

* Fit all of the spectra using the second function. In the first 10, hold the unneeded parameters at zero.

* Fit the first 10 spectra with the first function. Subtract the general envelope result determined from these 10 fit from the remaining spectra. Fit the remaining spectra with a new fit function that only includes the additional terms needed for the "overlapping peaks".

Otherwise, what is the ultimate goal? Is it to obtain a best fit *in the best, consistent way possible* or is it to extract critical information from the covariance matrix that itself is tied directly to the physical system *with high confidence*? In the former case, my experience is that the final results of the fitting can change with the method used, the uncertainties on the fitting parameters will cover this properly, and the focus is on consistency in the way the fitting routines are applied. In the latter case, I must defer to those with deeper insights about the rigor that is needed to create a fitting routine that allows the covariances to be tied realistically to the uncertainties in the physical system.

In reply to by jjweimer

jjweimer wrote:

I'll throw a few alternate thoughts in the mix.

* Fit all of the spectra using the second function. In the first 10, hold the unneeded parameters at zero.

* Fit the first 10 spectra with the first function. Subtract the general envelope result determined from these 10 fit from the remaining spectra. Fit the remaining spectra with a new fit function that only includes the additional terms needed for the "overlapping peaks".

Otherwise, what is the ultimate goal? Is it to obtain a best fit *in the best, consistent way possible* or is it to extract critical information from the covariance matrix that itself is tied directly to the physical system *with high confidence*? In the former case, my experience is that the final results of the fitting can change with the method used, the uncertainties on the fitting parameters will cover this properly, and the focus is on consistency in the way the fitting routines are applied. In the latter case, I must defer to those with deeper insights about the rigor that is needed to create a fitting routine that allows the covariances to be tied realistically to the uncertainties in the physical system.

 

Thank you for your answer!

The ultimate goal is to obtain good fit, i.e. to obtain visually good fits and reasonable values of parameters and their errors. For example, T2f1 and T2f2 should be on the order of 1E-03 seconds, and vQ1 and vQ2 should be in the range 50 - 500 Hz. I don't know, starting with which spectrum I can describe data using fit_1 function, and therefore firstly I try to fit all 23 spectra using fit_1 function to reveal, starting from which spectrum I can use fit_1 function. So, for example, I found that 10th - 23rd spectra can be described by the first model (fit_1 function), but first 9 spectra can't be described by this model. So I try to fit these 9 spectra with more complicated model (fit_2 function), but holding three parameters: T2f1, vQ1 and v0. v0 is just the x-position of maximum of a peak in spectrum, I hold this parameter when fitting using fit_1 and fit_2 functions (each spectrum has its own v0 value), but maybe I need to make it be literal constant value for simplifying the process of fitting - I don't know. I set the parameters T2f1 and vQ1 be equal to the values of T2f and vQ respectively and hold them when using fit_2 function, but again maybe it will be better to make them be literal constant values. T2f and vQ values are taken from fit of the 10th spectrum (when it was fit by fit_1 function).

When speaking about one single experiment, all 23 spectra in this experiment are acquired from one sample. The difference between these spectra is that they were acquired using different values of one acquisition parameter. So the experiment is carrying out in the following way: the acquisition parameter PAR is set to one value VAL, the first spectrum is acquired; the acquisition parameter PAR is set to the second value VAL+increment, the second spectrum is acquired, the acquisition parameter PAR is set to the third value VAL+2*increment, and so on.

There is no difference in the fit result between using a held coefficient versus using a literal constant, except that the held coefficient appears in the reported results. But before the fit starts the held coefficients are segregated so that no derivatives are computed for them, and no errors are computed in the result. That is, the errors are reported as zero. There is an entry for held coefficients in the covariance matrix, but with a value of zero, indicating that the didn't participate in the fit.

What is the nature of the transition from good fits with f1 and good fits with f2? Are there overlapping peaks that get closer together until they merge? We could probably use a picture of the situation or a copy of your experiment file so that we can see the difficulties.

If you have overlapping peaks that get gradually closer together, resulting ultimately in a single merged peak, the transition region can be very difficult to fit. As you note, the fit isn't very good because the peak shape is broadened by being two overlapping peaks, but the overlap creates an identifiability problem- the peak shape doesn't adequately constrain trade-offs between parameters like amplitude versus peak width. There isn't much you can do about that except to use a transitional peak shape, if one is available that captures the aspects of the problem that are important to you.

Mathematically, there is little difference between a structure fit function and a regular function with held coefficients. I suggested using a structure fit function because that is a way to encapsulate some coefficients along with constants that don't participate in fitting. You seem to be very concerned about held coefficients, and that is a way to avoid them. Using a structure fit function with constants can reduce operator error because there is no chance you will forget to hold the coefficients that represent constants.

In reply to by johnweeks

johnweeks wrote:

There is no difference in the fit result between using a held coefficient versus using a literal constant, except that the held coefficient appears in the reported results. But before the fit starts the held coefficients are segregated so that no derivatives are computed for them, and no errors are computed in the result. That is, the errors are reported as zero. There is an entry for held coefficients in the covariance matrix, but with a value of zero, indicating that the didn't participate in the fit.

What is the nature of the transition from good fits with f1 and good fits with f2? Are there overlapping peaks that get closer together until they merge? We could probably use a picture of the situation or a copy of your experiment file so that we can see the difficulties.

If you have overlapping peaks that get gradually closer together, resulting ultimately in a single merged peak, the transition region can be very difficult to fit. As you note, the fit isn't very good because the peak shape is broadened by being two overlapping peaks, but the overlap creates an identifiability problem- the peak shape doesn't adequately constrain trade-offs between parameters like amplitude versus peak width. There isn't much you can do about that except to use a transitional peak shape, if one is available that captures the aspects of the problem that are important to you.

Mathematically, there is little difference between a structure fit function and a regular function with held coefficients. I suggested using a structure fit function because that is a way to encapsulate some coefficients along with constants that don't participate in fitting. You seem to be very concerned about held coefficients, and that is a way to avoid them. Using a structure fit function with constants can reduce operator error because there is no chance you will forget to hold the coefficients that represent constants.

Thanks a lot for your explanation! So I will continue to use held coefficients when fitting.

Each spectrum is represented by single peak. The first peak (spectrum) is the broadest, the second peak is narrower, the third peak is narrower than the second one, and so on.

Please sorry, but my supervisor doesn't allow me to post our experimental data on the Internet.