I am trying to fit the following ODE system which describes drug absorption and elimination.
If $A_e$ is the amount of drug in the absorption state and $A$ is the amount of drug in the body this can be described as:
$$\begin{aligned} {dA_e \over dt} &= -k_a A_e\\ {dA \over dt} &= k_a A_e - k A\end{aligned}$$
I am trying to estimate the parameter values the absorption rate ($k_a$) and the elimination rate ($k$).
Below is the Matlab code written to estimate the parameter values using lsqnolin. But I am getting warnings of RelTol has been increased to 2.2E-14. Can someone please tell me what is wrong with the way I have modelled it?
I want to know how to estimate using an ODE System (That is without writing the objective function as the solution of $A(t)$ as the actual model has many other states)
time=[0.5;1;1.5;2;3;4;5;6;8;12];%time in hours
Drugdata=[0.33;1.23;1.95;2.72;3.51;3.63;3.47;3.22;2.39;1.13];
%parameters estimated:k_a and k
initial=[0.5,0.5];%initial guesses of the estimates
ODEinit=[8.48,Drugdata(1)];%initial values to the ODE.
lb=[0,0];
ub=[100,100];
[fittedVals,resnorm,~,~,~,~,~]=lsqnonlin(@(xEstimate)errorFun(xEstimate,Drugdata,ODEinit,...
time),initial,lb,ub);
fittedValues=model2(fittedVals',time,ODEinit);
close all
figure
h2=scatter(time,Drugdata,20,'b','filled');
hold on
h1=plot(time,fittedValues,'color', 'r');
ylabel('Drug')
xlabel('time')
function err=errorFun(xEstimate,DrugMeas,ODEinit,thours)
Drug_est=model2(xEstimate,thours,ODEinit);%estiamted values of drug using the ODE model
err=DrugMeas-Drug_est;
end
function Drugout= model2(xEstimate,thours,ODEinit)
options = odeset('AbsTol',1e-25,'RelTol',1e-25);
[~,values] = ode45(@(t,y)Equations(t,y),thours,ODEinit,options);
function s=Equations(~,y)
%parameters estimated:k_a, k
k=xEstimate(2);%rate of elimination
ka=xEstimate(1);%rate of drug absorption
s=zeros(2,1);
s(1)=-ka*y(1);%absorption compartment
s(2)=ka*y(1)-k*y(2);%drug
end
Drugout=values(:,2);
end

You get a warning because in the usual 64bit floating point format a relative tolerance of
1e-25is not achievable. Rounding real numbers to floating point already gives a relative error of up to2e-16, add to that the accumulation over the computations of the solution method and a relative error of2.2e-14appears as justified for a minimal case for a positive value of it. Your data has 3 digits, thus a working precision of 6 digits for the integration seems sufficient. To be more than exact, setRelTolto1e-9andAbsTolto1e-7.Doing experiments with at translation of the code to python using scipy.optimize.least_squares, I get that
atol = 1e-4; rtol=1e-5;gives parameter estimates[0.25206566 0.30065899]atol = 1e-5; rtol=1e-7;gives parameter estimates[0.25207333 0.30065716]atol = 1e-12; rtol=1e-13;gives parameter estimates[0.25207395 0.30065723]So as can be seen, the first 3 or even 4 digits of the estimated parameters do not depend on the integration tolerances.
The plot of the fitted model is
Setting the initial time at $0$ and making the initial values also variables of the optimization process results in the fitted parameter vector $$ [k, k_a, A_{e0}, A_0] = [ 0.281374,\, 0.28137101,\, 10.95249421,\, -1.34117042] $$ with the plot
Forcing $A_0$ to be positive gives a much worse fit.