# Why FindFit could not exactly fulfill condition?

I tried to fit some data with boundary conditions, but FindFit just could not work. Does anyone know the reason?

Details:

The function to be fitted is A*Tanh[x+a]+B. Data is provided from x=0 to some positive number.

I set the requirement that the fitted function should be same as Tanh[x] at x=0 both for its value and its first derivative.

I realized such a condition in FindFit through a direct setting; however, it does not seems to work, i.e. the function is NOT exactly connected to the expected one. There is still about 10^-7 to 10^-10 difference between the two.

Following is my code and result

 tL = Transpose[{Range[0, 5, .5], Tanh[#] & /@ Range[0, 5, .5] + RandomReal[.2, 11]}];
f = Tanh[x]; fD = D[tf, {x, 1}];
fitf = A*Tanh[x + a] + B; fitfD = D[fitf, {x, 1}];
fitf0 = fitf /. x -> 0; fitfD0 = fitfD /. x -> 0;
fit = FindFit[tL, {fitf, {fitf0 == 0, fitfD0 == 1}}, {{a, 0}, {A, 1}, {B, 0}}, x];
fitf=fitf/.fit;
F = Piecewise[{{f, x < 0}, {fitf, x >= 0}}]
FD = D[F, {x, 1}]
Show[Plot[F, {x, -6, 6}, PlotStyle -> Red, AxesLabel -> {x, "f(x)"}],ListPlot[tL], PlotRange -> All]
Limit[F, x -> 0, Direction -> -1]
Plot[FD, {x, -1, 1}, AxesLabel -> {x, "f'(x)"}]  • You can try uploading your figure to another site, and somebody else here can edit in the image for you. May 28 '12 at 17:17
• You could increase AccuracyGoal and PrecisionGoal in FindFit. For example for AccuracyGoal -> 12 and PrecisionGoal -> 12 I get fitf /. x -> 0 === 1.38778*10^-17 and (fitfD /. x -> 0) - 1 === -1.11022*10^-16. May 28 '12 at 18:38
• Thanks, Heike. It works. However, im not clear about the difference between AccuracyGoal,PrecisionGoal, and also WorkingPrecision. Actually which one "dominates"? May 28 '12 at 19:46
• @Heike You're right. But the ultimate cause of the problem is that the OP is leaving to FindFit two degrees of freedom more that those allowed by the conds over the function and its derivative May 28 '12 at 19:53
• @Mathieu You can find more information about the relation between AccuracyGoal, PrecisionGoal and WorkingPrecision under "More Information" in the documentation of PrecisionGoal or AccuracyGoal. Basically, PrecisionGoal is related to the absolute error in the estimated value, and AccuracyGoal the to the relative error. May 28 '12 at 20:14

The FindFit[] function is working as expected for the required accuracy.

If you want to force an exact value for the function and its derivative at the origin, you lose 2 degrees of freedom for the solution, like this (I chose A and B):

tL = Transpose[{Range[0, 5, .5], Tanh[#] & /@ Range[0, 5, .5] + RandomReal[.2, 11]}];

Clear[f, fD, fitf, fitfD, a, A, B];
f = Tanh[x];
fitf = A Tanh[x + a] + B;
fitfD = D[fitf, {x, 1}];
exact = Solve[(fitf == 0 && fitfD == 1) /. x -> 0, {A, B}];

fit = FindFit[tL, fitf /. exact[], {{a, 0}}, x];
F = Piecewise[{{f, x < 0}, {(fitf /. exact /. fit)[], x >= 0}}];
FD = D[F, {x, 1}];

Show[Plot[F, {x, -1, 5}], ListPlot[tL], PlotRange -> All]
Plot[Evaluate@D[fPcw, {x, 1}], {x, -1, 1}]


Function: Derivative: Edit

Perhaps better coding

tL = Transpose[{Range[0, 5, .5], Tanh[#] & /@ Range[0, 5, .5] + RandomReal[.2, 11]}];
Clear[fPcw, fit, fitf];

fitf = u Tanh[x + a] + v;
exact = Solve[(fitf == 0 && D[fitf, {x, 1}] == 1) /. x -> 0, {u, v}][];

fit = FindFit[tL, fitf /. exact, a, x];

fPcw = Piecewise[{{Tanh@x, x < 0}, {fitf /. exact /. fit, x >= 0}}];

Show[Plot[fPcw, {x, -1, 5}], ListPlot[tL], PlotRange -> All]
Plot[Evaluate@D[fPcw, {x, 1}], {x, -1, 1}]

• You are right. Any condition would reduce degree of freedom. However, i still wonder what is the difference between your method and my original one. Problem may be arise in your method is that the solution may be not unique by using Solve. Anyway, fortunately it works to increase AccuracyGoal and PrecisionGoal. May 28 '12 at 19:32