1
$\begingroup$

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?

$\endgroup$
1
  • $\begingroup$ 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]] $\endgroup$ Sep 29, 2016 at 22:20

1 Answer 1

3
$\begingroup$

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"})]

Contours of fitfunct by theta and n

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]

Data and fit

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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