# Question: Using an independent parameter for FitFunc?

g.germer

Sun, 09/13/2020 - 10:39 am

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