This is a modification of the question Is it normal that adding constraints on the parameters of NonlinearModelFit increases execution time 100 times??
I want a program that fits a SIR model to reported new infections data. The SIR model works, it produces a vector of 33 components (estimated weekly new infections)
pobTotal = 4950738;
mu = 7*41157/365 // N(* weekly births *);
d = mu/pobTotal;(*constant population*)
reported = {107, 135, 612, 195, 626, 619, 491, 1164, 1137, 511, 1036,
1144, 2650, 3162, 6074, 6693, 8253, 6639, 6148, 4345, 3141, 1958,
1130, 484, 356, 296, 195, 121, 208, 101, 67, 128, 20};
data = Thread[{Range[1, 33], reported}];
T = Length[reported ];n=7;(*discretization to days, to avoid long times taken by NIntegrate*)
SIR[\[Gamma]_?NumericQ, \[Beta]_?NumericQ, s0_?NumericQ, i0_?NumericQ] :=
Module[{ssol, isol, RiemSum, fd},
{ssol, isol} = NDSolveValue[{
s'[t] == mu - (\[Beta]*s[t]*i[t]/pobTotal) - d*s[t],
i'[t] == (\[Beta]*s[t]*i[t]/pobTotal) - (\[Gamma] + d)*i[t],
s[0] == s0, i[0] == i0
},
{s, i},
{t, 0, T},
MaxStepSize -> 400];
fd = \[Beta]*ssol[Range[0, n T]/n]*isol[Range[0, n T]/n]/pobTotal;
RiemSum = Total[Partition[Drop[fd, 1], n], {2}]/n]
SIR[1,1,10^6,22]
ListLinePlot[SIR[1,1,10^6,22]]
I tried 'NonlinearModelFit' which works very quickly, but produces negative parameters, and the plot also looks nonsense.
Timing[nlm = NonlinearModelFit[
data, p*SIR[\[Gamma], \[Beta], s0, i0], {{\[Gamma],1}, {\[Beta],1.8}, {s0,4254150}, {i0,146},{p,.023}}, t]] // Quiet
{\[Gamma],\[Beta],s0,i0,p}/. nlm["BestFitParameters"]
ListPlot[nlm[t]]
It seems the input to 'NonlinearModelFit' should be a function, not a vector, which leads to the nonsensical output. This suggests I should use some other fitting command.
A second question: I must also add constraints on the parameters. These multiply the execution times by hundreds, and it would be nice to be able to replace constraints by a penalty function (soft constraint). Is it possible to modify the objective of 'NonlinearModelFit' by a penalty function ? Or are we forced to use 'NMinimize', and give up all the statistics diagnostics of 'NonlinearModelFit'?