3
$\begingroup$

Is there a way to improve this fitting?

dat={{0, 0.183453}, {10, 0.18317}, {20, 0.182312}, {30, 0.180844}, {40, 
  0.178713}, {50, 0.175843}, {60, 0.172141}, {70, 0.167506}, {80, 
  0.161841}, {90, 0.155074}, {100, 0.147198}, {110, 0.138308}, {120, 
  0.128652}, {130, 0.118654}, {140, 0.108915}, {150, 0.100168}, {160, 
  0.093188}, {170, 0.0886728}, {180, 0.0871093}, {190, 
  0.0886728}, {200, 0.093188}, {210, 0.100168}, {220, 0.108915}, {230,
   0.118654}, {240, 0.128652}, {250, 0.138308}, {260, 0.147198}, {270,
   0.155074}, {280, 0.161841}, {290, 0.167506}, {300, 0.172141}, {310,
   0.175843}, {320, 0.178713}, {330, 0.180844}, {340, 0.182312}, {350,
   0.18317}, {360, 0.183453}};

Block[{θ = 40},
 fit = NonlinearModelFit[dat, {( 
  A Cos[θ Degree] + B Sin[θ Degree] Cos[θ Degree] Cos[ϕ Degree]),
     A > 0, B > 0 }, {{A, 0}, {B, 0}}, ϕ];

 ListLinePlot[{Table[{ϕ, ((A Cos[θ Degree] + 
   B Sin[θ Degree] Cos[θ Degree] Cos[ϕ Degree])) /. 
   fit["BestFitParameters"]}, {ϕ, 0, 360, 10}], dat}, 
  PlotStyle -> {Gray, Red}, PlotLegends -> {"fit", "dat"}]]    

enter image description here

$\endgroup$
7
  • $\begingroup$ Your data point {190, 0} does not correspond to your dat graph. $\endgroup$ Commented yesterday
  • $\begingroup$ Sorry, dat modified. $\endgroup$ Commented yesterday
  • 2
    $\begingroup$ Using two parameters a A has no sense. $\endgroup$ Commented yesterday
  • 2
    $\begingroup$ NonlinearModelFit (and LinearModelFit) is not the problem. You need a better model (as shown in the current two answers). Is there some physical model that is indicated? If not, a better fit is just a better description of the data rather than an explanation of the data. Also, you really only have half of the observations presented which means that any standard errors are underestimated. The fitting should just use the real data and not any of the duplicated data. $\endgroup$ Commented 23 hours ago
  • 2
    $\begingroup$ Half of the observations are duplicates: the 0 degree value is exactly the same as the 360 degree value, the 10 degree value is exactly the same as the 350 degree value, and so on. You don't describe how the data was obtained or anything about the subject matter which matters when making decisions about fitting. $\endgroup$ Commented 20 hours ago

3 Answers 3

8
$\begingroup$

Adding quadratic term helps

Block[{\[Theta] = 40}, 
 fit = NonlinearModelFit[
   dat, {(A Cos[\[Theta] Degree] + 
      B Sin[\[Theta] Degree] Cos[\[Theta] Degree] Cos[\[Phi] Degree] +
       F  Cos[\[Phi] Degree]^2), A > 0, 
    B > 0}, {{A, 0}, {B, 0}, {F, 0}}, \[Phi]];
 ListLinePlot[{Table[{\[Phi], (( 
        A Cos[\[Theta] Degree] + 
         B Sin[\[Theta] Degree] Cos[\[Theta] Degree] Cos[\[Phi]\
 Degree] + F Cos[\[Phi] Degree]^2)) /. 
      fit["BestFitParameters"]}, {\[Phi], 0, 360, 10}], dat}, 
  PlotStyle -> {Gray, Red}, PlotLegends -> {"fit", "dat"}]]

trigonometric fit

$\endgroup$
6
$\begingroup$

The model is linear, so NonlinearModelFit is overkill. Also Cos[θ Degree] and Sin[θ Degree] are just constants so they just make the model more complicated looking than it needs to be. We do a quadratic fit like yarchik

basis = Cos[phi*Degree]^Range[0, 2];
mat = DesignMatrix[dat, basis, phi];
lsqParams = PseudoInverse[mat] . dat[[All, 2]];


lsqFit[phi_] = lsqParams . basis;
datPlot = ListLinePlot[dat, PlotStyle -> Red];
legend = LineLegend[{Red, White}, {"data", "fit"}];
fitPlot = 
  Plot[lsqFit[phi], {phi, 0, 360}, PlotStyle -> White, 
   PlotLegends -> Placed[legend, {0.75, 0.5}]];
Show[datPlot, fitPlot, Frame -> True]

enter image description here

$\endgroup$
6
$\begingroup$

I think your dat can be fitted by an even function so the model could be a type of cosine Fourier series. Choose nn for how many terms you need.

dat = {{0, 0.183453}, {10, 0.18317}, {20, 0.182312}, {30, 
    0.180844}, {40, 0.178713}, {50, 0.175843}, {60, 0.172141}, {70, 
    0.167506}, {80, 0.161841}, {90, 0.155074}, {100, 0.147198}, {110, 
    0.138308}, {120, 0.128652}, {130, 0.118654}, {140, 
    0.108915}, {150, 0.100168}, {160, 0.093188}, {170, 
    0.0886728}, {180, 0.0871093}, {190, 0.0886728}, {200, 
    0.093188}, {210, 0.100168}, {220, 0.108915}, {230, 
    0.118654}, {240, 0.128652}, {250, 0.138308}, {260, 
    0.147198}, {270, 0.155074}, {280, 0.161841}, {290, 
    0.167506}, {300, 0.172141}, {310, 0.175843}, {320, 
    0.178713}, {330, 0.180844}, {340, 0.182312}, {350, 0.18317}, {360,
     0.183453}};

nn = 3;

su = Sum[a[n] Cos[n Φ Degree], {n, 0, nn}];

fit = NonlinearModelFit[dat, su, Cases[su, x_a, All], Φ];
su /. fit["BestFitParameters"]

ListLinePlot[{Table[{Φ, su /. fit["BestFitParameters"]}, {Φ,
     0, 360, 10}], dat}, PlotStyle -> {Gray, Directive[Red, Dashed]}, 
 PlotLegends -> {"fit", "dat"}]

enter image description here

For nn=6 we have the following (amplitude of 6-th cosine is already very small):

enter image description here

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.