%% Day 3, part 3: Other types of sensitivity analysis
% 
% In this section, we'll try two other types of sensitivity analysis.
% * Full forward sensitivity calculation
% * Sensitivities to the timing of a concentration's maximum or minimum

%% Computing *full* forward sensitivities
% 
% Sometimes you're not just interested in the value of a species or output
% at a particular timepoint, but instead want the continuous sensitivity as
% a function of time.
% 
% This problem can be solved by solving differentiating the model
% 
% $$ \frac{dx}{dt} = f\left(t,x,u\right) $$
% 
% with respect to parameters to obtain
% 
% $$ \frac{d}{dt}\frac{dx}{dp} = \frac{df}{dx}\frac{dx}{dp} + \frac{df}{dp} $$
% 
% We'll first modify the experiment to run for a shorter time, as we don't
% want you to have to wait forever for this line to run!

expt = constructExperiment(tF, u, [], events, 3);   % <--- only run for 3 events, instead of 5

[dydp dxdp t] = sensitivity_state(m, expt);
plot(t, dydp(t))

%% Computing sensitivities with respect to timings
% 
% Again, we're going to use one of KroneckerBio's builtin objective
% functions.  The math for computing the sensitivities of event timings is
% actually somewhat involved; see [2] for an introduction to these sorts of
% issues.
% 
% For the system
% 
% $$ \frac{dx}{dt} = f(t,x,u) $$
% 
% $$ x_i(t^*) = 0 $$
% 
% it can be shown that
% 
% $$ \frac{dt^*}{dp} = \left(\frac{df_i}{dx}f\right)^{-1}\left(\frac{df_i}{dx}\frac{dx}{dp}\right) + \left(\frac{df_i}{dx}f\right)^{-1}\left(\frac{df_i}{dp}\right) $$
% 
% This is what constitutes the guts of the constructObjectiveTiming
% functions.

expt = constructExperiment(tF, u, [], events, 5);   % <--- run for 5 events again
obj = constructObjectiveTimingOutputValue(m, 1, 2);
[O dOdp] = sensitivity(m, obj, expt);
rankSensitivities(m, dOdp, 10)

%% References
% [2]	Wilkins KA, Barton PI, Tidor B. _PLoS Comp Biol_ *3*(12):e242 (2007).
