1
$\begingroup$

I am trying to fit the function in model, however I get

General::ivar: 5000.` is not a valid variable.

this error.

My code is that and



wavelength = 2.094;
zdata = {0.5, 1.6, 3, 4.6, 6.6, 8.2, 9.8, 12.1, 14.2, 16.6}*10^4;
W = {266.16, 257.385, 261.69, 290, 323.855, 365.07, 406.19, 455.33, 
   503.65, 560.17};
data = Thread[{zdata, W^2}]
model = w0^2 + Msquared^2*(wavelength/(Pi*w0))^2*(z - z0)^2
fit = FindFit[
  data, {model, {w0 > 0, 1 < Msquared, z0 > 0}}, {w0, Msquared, z0}, 
  z]

I think it is very trivial but couldn't manage to find the error. NonLinearModelFit doesn't resolve the issue.

The model equation is here https://www.wikiwand.com/en/M_squared#:~:text=It%20is%20calculated%20from%20the,M2%20is%20exactly%20one.

$\endgroup$
5
  • $\begingroup$ They are constants I am trying to find the equation is in here ; wikiwand.com/en/…. $\endgroup$
    – asdfg
    Commented May 5, 2022 at 10:27
  • 3
    $\begingroup$ You use "z" as data and as a variable. Use 2 different names. $\endgroup$ Commented May 5, 2022 at 10:28
  • $\begingroup$ As @DanielHuber mentioned, you need to make sure you are using distinct variables. $\endgroup$
    – alex
    Commented May 5, 2022 at 10:56
  • $\begingroup$ @DanielHuber thank you it solved my issue, can you answer once again so that I can choose it as answer $\endgroup$
    – asdfg
    Commented May 5, 2022 at 11:05
  • $\begingroup$ You probably need 2 more changes: (1) Put in a starting value for z0 such as {z0, 1} and (2) Add MaxIterations -> 5000 to FindFit. And I might be in the minority with this but I would always use NonlinearModelFit in place of FindFit as FindFit only gives parameter estimates and no regression diagnostics as NonlinearModelFit does. (You're going to find that the estimate of z0 is 0.) $\endgroup$
    – JimB
    Commented May 5, 2022 at 16:56

2 Answers 2

3
$\begingroup$

@DanielHuber has mentioned the main issue but you'll also need to make some other changes: (1) Set a reasonable starting value for z0 and (2) Either increase the maximum number of iterations to 5000 (MaxIterations -> 5000) or replace FindFit with NonlinearModelFit.

Here is one approach:

nlm = NonlinearModelFit[data, {model, {w0 > 0, 1 < Msquared, z0 > 0}}, {w0, Msquared, {z0, 1}}, z];
nlm["ParameterConfidenceIntervalTable"]

Parameter confidence interval table

Is having a 95% confidence interval for $M^2$ being $(0.969,1.393)$ good enough for your objective? If not, you need more data or data with less measurement error.

Looking at the fit and residuals is also helpful to decide on if the data matches the theoretical model. One essentially hopes for no apparent patterns.

Show[ListPlot[data], Plot[nlm[z], {z, Min[zdata], Max[zdata]}], Frame -> True, 
 FrameLabel -> (Style[#, Bold, 18] &) /@ {"z", "\!\(\*SuperscriptBox[\(W\), \(2\)]\)"}]

Data and fit

ListPlot[Transpose[{nlm["PredictedResponse"], nlm["FitResiduals"]}], Frame -> True,
 FrameLabel -> (Style[#, Bold, 18] &) /@ {"Predicted response", "Fit residual"}]

Predicted responses vs fit residuals

ListPlot[Transpose[{zdata, nlm["FitResiduals"]}], Frame -> True,
 FrameLabel -> (Style[#, Bold, 18] &) /@ {"z", "Fit residual"}]

Predictor vs fit residual

The residual fits don't look great as you have groups of neighboring points all above the fit or below the fit but you'll need to be the judge about that.

The webpage you mention is inadequate because it completely ignores any estimation of precision let alone what level of precision might be needed and any possible lack-of-fit.

$\endgroup$
2
$\begingroup$

Look at "z". You use it for storing data:

z = {0.5, 1.6, 3, 4.6, 6.6, 8.2, 9.8, 12.1, 14.2, 16.6}*10^4;

and you also use it as a variable:

model = w0^2 + Msquared^2*(wavelength/(Pi*w0))^2*(z - z0)^2

Use different names for different things.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.