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. – J. M. will be back soon 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. – Heike 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"? – Mathieu 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 – Dr. belisarius 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. – Heike 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. – Mathieu May 28 '12 at 19:32