# Improving nonlinear model fit (piecewise function)

I have a piecewise relatively simple function, and I'm looking for three parameters. Here's an MWE:

data = {{0, 0}, {2.5, 0}, {7, 0}, {12, 0}, {17,
8.980000000000001*^-7}, {22, 1.435*^-6}, {27,
2.5400000000000002*^-6}, {32, 6.3830000000000006*^-6}, {37,
0.000012926000000000001}, {42, 0.000025553}, {47,
0.00005648100000000001}, {52, 0.00011215500000000001}, {57,
0.00020045200000000002}, {62, 0.00031542000000000007}, {67,
0.00045923800000000005}, {72, 0.0006145}, {77,
0.0007883660000000001}};

eqn = {Piecewise[{{1 - Exp[-a*t],
t <= to}, {1 - Exp[-a*t - b*(t - to)], t > to}}], a > 0, b > 0,
to > 0, to < 60};

nlm = NonlinearModelFit[data, eqn, {a, b, to}, t,
Method -> {NMinimize, Method -> "DifferentialEvolution"}];

Show[ListPlot[data], Plot[nlm[t], {t, 0, 80}], Frame -> True]
nlm["ParameterTable"]


When I run this, I get a fit with adjusted $R^2 = 0.9808$ and this fit; with to = 56.55

However, if instead specficy to < 51, by writing

eqn = {Piecewise[{{1 - Exp[-a*t],
t <= to}, {1 - Exp[-a*t - b*(t - to)], t > to}}], a > 0, b > 0,
to > 0, to < 51};


I get an improved fit ($R^2 = 0.9945$) and this fit, with to = 50.9941

Naively, one would have thought because 50.9941 is less than 60, the first form should have captured this. Does anyone know why the curve fitting terminates before this, and how to make it go and find a better best-fit curve? I'm not sure if the problem is using a piecewise function or whether it's the algorithm being employed!

Your a and b are strict positive, and their optimal values are very close to zero. Optimization algorithms sometimes handle problems better if such parameters are log-transformed.

eqn = {Piecewise[{{1 - Exp[-Exp[aLog]*t],                      t <= to},
{1 - Exp[-Exp[aLog]*t - Exp[bLog]*(t - to)], t > to}}], to > 0, to < 60};

nlm = NonlinearModelFit[data, eqn, {aLog, bLog, to}, t,
Method -> {NMinimize, Method -> "DifferentialEvolution"}];