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[{\[Theta] = 40},
 fit = NonlinearModelFit[
   dat, {( A Cos[\[Theta] Degree] + 
      B Sin[\[Theta] Degree] Cos[\[Theta] Degree] Cos[\[Phi] Degree]),
     A > 0, B > 0 },
   {{A, 0}, {B, 0}}, \[Phi]]; 
 ListLinePlot[{Table[{\[Phi], (( A Cos[\[Theta] Degree] + 
         B Sin[\[Theta] Degree] Cos[\[Theta] Degree] Cos[\[Phi] \
Degree])) /. fit["BestFitParameters"]}, {\[Phi], 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 15 hours ago
  • $\begingroup$ Sorry, dat modified. $\endgroup$ Commented 15 hours ago
  • 2
    $\begingroup$ Using two parameters a A has no sense. $\endgroup$ Commented 15 hours ago
  • 1
    $\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 5 hours ago
  • $\begingroup$ I have a data for an observable that is a function of \theta and \phi in sphirical coordinate. I am trying to find a single model that can fit all data. Sorry, what do you mean by " only have half of the observations presented"? $\endgroup$ Commented 3 hours ago

3 Answers 3

7
$\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$
5
$\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$
4
$\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$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.