# Problem with fitting NonlinearModelFit::nrlnum:

I'm trying to fit a set of data to a non-linear model and I quickly ran into a problem where it keeps running into complex values. Here's my current code:

ag1 = 223 + 20.5/60;
bg1 = 131 + 57/60;

cg1 = {79 + 5/60, 75 + 42/60, 74 + 48/60, 74 + 50.5/60, 75 + 15/60,
75 + 52/60, 76 + 54/60, 77 + 40/60, 78 + 53.5/60, 80 + 3/60,
81 + 43.5/60, 83 + 14.5/60, 85 + 9.5/60};

thetag1 = {44.3042, 49.6458, 54.6708, 57.0958, 60.5625, 63.2958,
66.1958, 68.3875, 71.0125, 73.4292, 76.0792, 78.3458, 82.9625};

deltag1 = cg1 - ag1 + 200;

data = Transpose[{thetag1, deltag1}];

fitfunct =
theta \[Degree] +
ArcSin[Sin[60 \[Degree] ]*Sqrt[(n)^2 - Sin[theta \[Degree]]^2] -
Sin[theta \[Degree]]*Cos[60 \[Degree]]]/\[Degree] - 60 \[Degree];

error = StandardDeviation[{ 20, 21, 19.5, 20.5, 20.5, 21}]*
Table[1, {i, 13}];

fit = NonlinearModelFit[data, {fitfunct}, n, theta,
Weights -> 1/error^2]


To which the output was

NonlinearModelFit::nrlnum: The function value {58.1404 -26.4015 I,44.1256 +0. I,28.5762 +0. I,22.9152 +0. I,15.6495 +0. I,10.2762 +0. I,<<18>> +<<1>>,0.690677 +0. I,-4.09825+0. I,-8.20392+0. I,-13.0284+0. I,-17.0034+0. I,-22.2808+0. I} is not a list of real numbers with dimensions {13} at {n} = {1.7459}. >>


I tried to look up a solution to this and found this: How to solve this FindFit::nrlnum:

Following the advice there, I tried adding in "NormFunction -> (Norm[#, Infinity] &)" to my fit argument but that wasn't allowed with NonlinearModelFit, so I tried switching to FindFit, but FindFit wouldn't allow me to include weights!

I tried getting rid of the weights and without the weights, FindFit with "NormFunction -> (Norm[#, Infinity] &)" in it's argument was able to get me a reasonable value for n. However, I really need to be weighing my data by it's uncertainties.

Do any of you know how I can get my fit to run and accept weights simultaneously?

• Well, i bet your function is false. At least for this dataset.If you look in the plots for some n's (which have to be in a narrow interval btw.) the really don't seem to fit well anyway. Try yourself: Show[Plot[Table[fitfunct,{n,Sqrt[2],Sqrt[4],(Sqrt[6]-Sqrt[1])/20}],{theta,40,90}],ListPlot[data]] – Julien Kluge Sep 29 '16 at 22:20

## 1 Answer

This is an extended comment to echo @JulienKluge 's comment which says your function is not a very good fit to the data.

In setting up the code I recommend first doing the fit without the weights (especially as a plot of the data does not suggest any wild (and independent) deviations and the proposed weights are identical - so why have weights in the first place?).

One needs real values for fitfunct and a contour plot of fitfunct by theta and n shows the narrow range of acceptable values for n that @JulienKluge mentioned:

fitfunct =
theta ° + ArcSin[Sin[60 °]*Sqrt[(n)^2 - Sin[theta °]^2] - Sin[theta °]*Cos[60 °]]/° - 60 °;

ContourPlot[fitfunct, {theta, 44, 83}, {n, 0.5, 2},
ContourLabels -> (Text[Framed[#3], {#1, #2}, Background -> White] &),
PlotRange -> Full, Frame -> True,
FrameLabel -> (Style[#, Large, Bold] & /@ {"theta", "n", "Contours of fitfunct"})]


We see that we need to restrict n to be between about 1 to 1.7.

fit = NonlinearModelFit[data, fitfunct && 1.2 < n < 1.7, {{n, 1.6}}, theta];
fit["BestFitParameters"]
(* {n -> 1.6716614603902369} *)


And the starting value still needs to be pretty close the best value to run without errors or warnings. And yet the fit is extremely poor:

Manipulate[
ListPlot[{Transpose[{thetag1, deltag1}],
Transpose[{thetag1,
theta ° + ArcSin[Sin[60 °]*Sqrt[(n)^2 - Sin[theta °]^2] - Sin[theta °]*Cos[60 °]]/° - 60 ° /. theta -> thetag1}]},
PlotRange -> {Automatic, {-20, 85}},
PlotLegends -> {"Observed", "Predicted"}],
{{n, 1.6716614603902369}, 1, 1.7, Appearance -> "Labeled"},
TrackedSymbols :> n]
`