# Optimization of Curve fitting

I have a set of data:

{{0°, 222597.}, {10°, 215256.}, {20°, 205889.}, {30°, 190917.},
{40°, 173117.}, {50°, 154249.}, {60°, 138540.}, {70°, 125409.},
{80°, 116973.}, {90°, 112937.}}


and I believe it is of the form a*cos(x+b)+c, where a, b, and c are undetermined coefficients.

As a result I use FindFit to determine the three coefficients.

data = {{0°, 222597.}, {10°, 215256.}, {20°, 205889.}, {30°, 190917.},
{40°, 173117.}, {50°, 154249.}, {60°, 138540.}, {70°, 125409.},
{80°, 116973.}, {90°, 112937.}};

intensityList = data[[All, 2]];

model = a Cos[b + 10°*x]^2 + c;

fittingParameter = FindFit[intensityList, {model}, {a, b, c}, x];

p2 = Plot[{a Cos[b+x]^2 + c} /. fittingParameter, {x, -0.1, 3.2}];
p1 = ListPlot[data];
Show[p1, p2]


And I get a curve which is not well-fitted as expected. However, if I eliminate the fitted b coefficient, the curve is much more well-fitted. Usually when there are more manipulable coefficients, the better the curve-fitting. I hazard a guess that constraints on b coefficient is necessary. How should I do so that I can obtain the more accurate a, b, c coefficients?

• try also nlm = NonlinearModelFit[data, a Cos[b + 10 \[Degree]*x]^2 + c, {a, b, c}, x]; p3 = Plot[nlm[x], {x, -0.1, 3.2}];Show[p1, p3]? – kglr Jul 19 '18 at 12:05
• @kglr: Without x-factor 10 \[Degree] your solution is straightforward! – Ulrich Neumann Jul 19 '18 at 12:24
• Can the a, b, c coefficients be extracted from NonlinearModelFit? – chika Jul 19 '18 at 14:33
• @chika: NonlinearModelFit can return the estimates of the coefficients: nlm["BestFitParameters"] (as stated in the online help). NonlinearModelFit can provide much more than FindFit so I would avoid using FindFit. I have no idea why one would even want to use the more limited FindFit (unless there's less overhead and it's speedier if for some strange reason one doesn't need goodness-of-fit summaries). In fact, I think I'll ask that question. – JimB Jul 19 '18 at 16:23

The main problem is you are changing the horizontal axis a few times. Try

data = {{0 °, 222597.}, {10 °, 215256.}, {20 °, 205889.},
{30 °, 190917.}, {40 °, 173117.}, {50 °, 154249.},
{60 °, 138540.}, {70 °, 125409.}, {80 °, 116973.}, {90 °, 112937.}};
model = a Cos[b + x]^2 + c;
fittingParameter = FindFit[data, {model}, {a, b, c}, x]
p2 = Plot[model /. fittingParameter, {x, 0, 90 °}];
p1 = ListPlot[data];
Show[p1, p2]


Note: there is no need to extract the "y values" as you did with intensityList = data[[All, 2]] and therefore there is no need to try to re-scale the horizontal axis as you did with the factor 10 in model = a Cos[b + 10°*x]^2 + c.

From the documentation of FindFit:

The data can have the form {{x1,y1,…,f1},{x2,y2,…,f2},…}, where the number of coordinates x, y, … is equal to the number of variables in the list vars.