function example_adjoint()
COMPILATION
[exdir,~,~]=fileparts(which('example_adjoint.m')); % compile the model amiwrap('model_adjoint','model_adjoint_syms',exdir)
Generating model struct ... Parsing model struct ... Generating C code ... headers | wrapfunctions | Compiling mex file ... amici | Building with 'Xcode with Clang'. MEX completed successfully. Building with 'Xcode with Clang'. MEX completed successfully.
SIMULATION
% time vector t = [linspace(0,4,5)]; p = [1.1,0.3,1]; k = []; D.Y = [ 1.0171 1.3423 1.6585 0.9814 0.3288]; D.Sigma_Y = 0.1*ones(size(D.Y)); options.sensi = 1; options.sensi_meth = 'adjoint'; options.maxsteps = 1e4; options.rtol = 1e-12; options.atol = 1e-12; % load mex into memory [~] = which('simulate_model_adjoint'); % fix for inaccessability problems sol = simulate_model_adjoint(t,log10(p),k,D,options);
Plot
figure
subplot(3,1,1)
errorbar(t,D.Y,D.Sigma_Y)
hold on
% plot(t,sol.y)
xlabel('time t')
ylabel('observable')
title(['log-likelihood: ' num2str(sol.llh) ])
y = (p(2)*t + p(3)).*(t<2) + ( (2*p(2)+p(3)-p(2)/p(1))*exp(-p(1)*(t-2))+p(2)/p(1) ).*(t>=2);
tfine = linspace(0,4,100001);
xfine = (p(2)*tfine + 1).*(tfine<2) + ( (2*p(2)+p(3)-p(2)/p(1))*exp(-p(1)*(tfine-2))+p(2)/p(1) ).*(tfine>=2);
mu = zeros(1,length(tfine));
for it = 1:length(t)
if(t(it)<=2)
mu = mu + ((y(it)-D.Y(it))/(D.Sigma_Y(it)^2))*(tfine<=t(it));
else
mu = mu + ((y(it)-D.Y(it))/(D.Sigma_Y(it)^2))*exp(p(1)*(tfine-t(it))).*(tfine<=t(it)).*(tfine>2) + ((y(it)-D.Y(it))/(D.Sigma_Y(it)^2))*exp(p(1)*(2-t(it))).*(tfine<t(it)).*(tfine<=2);
end
end
plot(tfine,xfine)
legend('data','simulation')
xlim([min(t)-0.5,max(t)+0.5])
subplot(3,1,2)
plot(tfine,mu)
ylabel('adjoint')
xlabel('time t')
xlim([min(t)-0.5,max(t)+0.5])
subplot(3,1,3)
plot(fliplr(tfine),-cumsum(fliplr(-mu.*xfine.*(tfine>2)))*p(1)*log(10)*(t(end)/numel(tfine)))
hold on
plot(fliplr(tfine),-cumsum(fliplr(mu))*p(2)*log(10)*(t(end)/numel(tfine)))
plot(tfine,-mu(1)*p(3)*log(10)*(tfine<2))
xlim([min(t)-0.5,max(t)+0.5])
ylabel('integral')
xlabel('time t')
legend('p1','p2','p3')
grad(1,1) = -trapz(tfine,-mu.*xfine.*(tfine>2))*p(1)*log(10);
grad(2,1) = -trapz(tfine,mu)*p(2)*log(10);
grad(3,1) = -mu(1)*p(3)*log(10);
plot(zeros(3,1),grad,'ko')
FD
eps = 1e-5;
xi = log10(p);
grad_fd_f = NaN(3,1);
grad_fd_b = NaN(3,1);
for ip = 1:3;
options.sensi = 0;
xip = xi;
xip(ip) = xip(ip) + eps;
solp = simulate_model_adjoint(t,xip,k,D,options);
grad_fd_f(ip,1) = (solp.llh-sol.llh)/eps;
xip = xi;
xip(ip) = xip(ip) - eps;
solp = simulate_model_adjoint(t,xip,k,D,options);
grad_fd_b(ip,1) = -(solp.llh-sol.llh)/eps;
end
figure
plot(abs(grad),abs(grad_fd_f),'o')
hold on
plot(abs(grad),abs(grad_fd_b),'o')
plot(abs(grad),mean([abs(grad_fd_b),abs(grad_fd_f)],2),'o')
plot(abs(grad),abs(sol.sllh),'o')
plot([1e1,1e2],[1e1,1e2],'k:')
set(gca,'XScale','log')
set(gca,'YScale','log')
axis square
legend('forward FD','backward FD','central FD','adjoint sensintivity analysis','Location','SouthEast')
xlabel('analytic absolute value of gradient element')
ylabel('computed absolute value of gradient element')
set(gcf,'Position',[100 300 1200 500])
drawnow
end