Question: Using an independent parameter for FitFunc?
ggermer
Is it possible to fit a parameter w[n] that is independent of x? In my case I would like to compensate shifts.
function name_of_this_function(w,x) : FitFunc
Wave w
Variable x
wave wave0 = root:pathofwave:wave0
wave wave1 = root:pathofwave:wave1
//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(x) = a*wave0(x+c)+b*wave1+d
//CurveFitDialog/ End of Equation
//CurveFitDialog/ Independent Variables 1
//CurveFitDialog/ x
//CurveFitDialog/ Coefficients 4
//CurveFitDialog/ w[0] = wave0
//CurveFitDialog/ w[1] = wave1
//CurveFitDialog/ w[2] = shiftofwave0
//CurveFitDialog/ w[3] = abs
return w[0]*wave0(x+w[2]) + w[1]*wave1(x) +w[3]
End
Wave w
Variable x
wave wave0 = root:pathofwave:wave0
wave wave1 = root:pathofwave:wave1
//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(x) = a*wave0(x+c)+b*wave1+d
//CurveFitDialog/ End of Equation
//CurveFitDialog/ Independent Variables 1
//CurveFitDialog/ x
//CurveFitDialog/ Coefficients 4
//CurveFitDialog/ w[0] = wave0
//CurveFitDialog/ w[1] = wave1
//CurveFitDialog/ w[2] = shiftofwave0
//CurveFitDialog/ w[3] = abs
return w[0]*wave0(x+w[2]) + w[1]*wave1(x) +w[3]
End
When I try to fit a function that matches the one shown above, I get the following error message:
FitProgressDialog allocating a dialogFitFunction instance
**** Singular matrix error during curve fitting ****
There may be no dependence on these parameters:
W_coef[2]
Did I do something basically wrong or is there a trick to fit such a shift?
Which starting values are you using? If w[0] becomes 0 you will have no dependency on w[2] and your fit will fail. Maybe you need to constrain w[0] to be larger than some small value?
If wave0 is a flat line with no x dependency you will run into the same problem
September 13, 2020 at 01:12 pm - Permalink
The zero seems to be the problem. If w[0] = 0 is the best possible fit, can you force the fit of the other w[n] or in this case skip w[2]?
(Unfortunately, the error also occurs when "K0 > 0" is specified and the fit of w[0] is very small).
September 14, 2020 at 03:43 am - Permalink
You could just hold the values of w[0] and w[2] (set the initial guess to zero and then check Hold). Then the fit will proceed using just the remaining coefficients w[1] and w[3].
September 14, 2020 at 05:37 am - Permalink
You could do something like "K0 > 0.001" Use a low but not too low value
September 14, 2020 at 07:21 am - Permalink
Many thanks for your help. For a single fit both holding values and using "K0 > 0.0x" work. Only if I let several fits in a loop be performed automatically, I do not have the possibility to set such parameters manually for each individual fit.
Is there a possibility that w[2] will only be fit if w[0] is above a threshold? Something like this (this Code does not work):
Wave w
Variable x
wave wave0 = root:pathofwave:wave0
wave wave1 = root:pathofwave:wave1
//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(x) = a*wave0(x+c)+b*wave1+d
//CurveFitDialog/ End of Equation
//CurveFitDialog/ Independent Variables 1
//CurveFitDialog/ x
//CurveFitDialog/ Coefficients 4
//CurveFitDialog/ w[0] = wave0
//CurveFitDialog/ w[1] = wave1
//CurveFitDialog/ w[2] = shiftofwave0
//CurveFitDialog/ w[3] = abs
do
return w[0]*wave0(x+w[2]) + w[1]*wave1(x) +w[3]
while (w[0]>0.00001)
return w[0]*wave0(x) + w[1]*wave1(x) +w[3]
end
September 14, 2020 at 11:07 am - Permalink
Fitting a shift coefficient like your w[2] can be tricky. Since for a user-defined fit function Igor computes numerical derivatives, the differencing interval for the derivatives must be large enough that the difference is non-zero. If w[0] is small or zero, or if the shift simply doesn't cause much difference, you can get a singular matrix caused by a zero derivative. Analytically, it may not be zero, but numerically it can be so small as to be effectively zero.
The solution to that problem is to provide an epsilon wave. If you are using Igor 8, you can read about epsilon waves: DisplayHelpTopic "The Epsilon Wave"
Usually the exact choice of values is not critical. My favorite value is 1e-6; for coefficients with very small expected values, you need something small. It is hard, but possible to have an epsilon that is too big.
September 14, 2020 at 03:44 pm - Permalink
In reply to Fitting a shift coefficient… by johnweeks
Okay, thank you very much. I will read this HelpTopic in Igor 8.
In what order of magnitude should the value be compared to the smallest possible (or expected) order of magnitude of the result?
September 15, 2020 at 01:01 pm - Permalink
That's a hard question to answer. It's not the smallest value that is relevant; that could be zero. It's more like some fraction of expected range. So if the coefficient could be somewhere between -1e-6 to 1e-6, you might set it to, so 1e-12. But what is most important is that it be big enough to give a non-zero derivative. So the most important aspect is the magnitude of the slope of d(chi-square)/d(coefficient). The value of coefficient - (coefficient + epsilon) needs to be non-zero.
September 15, 2020 at 02:27 pm - Permalink
Ok, thank you!
September 17, 2020 at 01:17 am - Permalink