Commit da9ec0f1 authored by Marco Ratto's avatar Marco Ratto Committed by Michel Juillard
Browse files

Estimation with analytic scores and hessian;

This includes re-setting the list of output arguments in objective functions
Added test function
parent 3332a7f7
function [fval,exit_flag,info,PHI,SIGMAu,iXX,prior] = DsgeVarLikelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults)
function [fval,grad,hess,exit_flag,info,PHI,SIGMAu,iXX,prior] = DsgeVarLikelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults)
% Evaluates the posterior kernel of the bvar-dsge model.
%
% INPUTS
......@@ -37,6 +37,9 @@ function [fval,exit_flag,info,PHI,SIGMAu,iXX,prior] = DsgeVarLikelihood(xparam1,
% Declaration of the persistent variables.
persistent penalty dsge_prior_weight_idx
grad=[];
hess=[];
% Initialization of the penalty
if ~nargin || isempty(penalty)
penalty = 1e8;
......
......@@ -63,7 +63,7 @@ snit=100;
% stailstr=[' P' num2str(i) stailstr];
%end
[f0,cost_flag] = feval(fcn,x0,varargin{:});
[f0,junk1,junk2,cost_flag] = feval(fcn,x0,varargin{:});
if ~cost_flag
disp('Bad initial parameter.')
......@@ -79,8 +79,11 @@ if NumGrad
case 5
[g,badg] = numgrad5(fcn, f0, x0, epsilon, varargin{:});
end
else
elseif ischar(grad)
[g,badg] = feval(grad,x0,varargin{:});
else
g=junk1;
badg=0;
end
retcode3=101;
x=x0;
......@@ -126,8 +129,11 @@ while ~done
case 5
[g1,badg1] = numgrad5(fcn, f1, x1, epsilon, varargin{:});
end
else
elseif ischar(grad),
[g1 badg1] = feval(grad,x1,varargin{:});
else
[junk1,g1,junk2, cost_flag] = feval(fcn,x1,varargin{:});
badg1 = ~cost_flag;
end
wall1=badg1;
% g1
......@@ -160,8 +166,11 @@ while ~done
case 5
[g2,badg2] = numgrad5(fcn, f2, x2, epsilon, varargin{:});
end
else
elseif ischar(grad),
[g2 badg2] = feval(grad,x2,varargin{:});
else
[junk1,g2,junk2, cost_flag] = feval(fcn,x1,varargin{:});
badg2 = ~cost_flag;
end
wall2=badg2;
% g2
......@@ -195,8 +204,11 @@ while ~done
case 5
[g3,badg3] = numgrad5(fcn, f3, x3, epsilon, varargin{:});
end
else
elseif ischar(grad),
[g3 badg3] = feval(grad,x3,varargin{:});
else
[junk1,g3,junk2, cost_flag] = feval(fcn,x1,varargin{:});
badg3 = ~cost_flag;
end
wall3=badg3;
% g3
......@@ -259,8 +271,11 @@ while ~done
case 5
[gh,badgh] = numgrad5(fcn, fh, xh, epsilon, varargin{:});
end
else
elseif ischar(grad),
[gh badgh] = feval(grad, xh,varargin{:});
else
[junk1,gh,junk2, cost_flag] = feval(fcn,x1,varargin{:});
badgh = ~cost_flag;
end
end
badgh=1;
......@@ -273,7 +288,7 @@ while ~done
%badgh
stuck = (abs(fh-f) < crit);
if (~badg) && (~badgh) && (~stuck)
H = bfgsi1(H,gh-g,xh-x);
H = bfgsi(H,gh-g,xh-x);
end
if Verbose
disp('----')
......
function [fval,exit_flag,ys,trend_coeff,info,Model,DynareOptions,BayesInfo,DynareResults,DLIK,AHess] = dsge_likelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults,derivatives_info)
function [fval,DLIK,Hess,exit_flag,ys,trend_coeff,info,Model,DynareOptions,BayesInfo,DynareResults] = dsge_likelihood(xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults,derivatives_info)
% Evaluates the posterior kernel of a dsge model.
%@info:
......@@ -151,7 +151,7 @@ exit_flag = 1;
info = 0;
singularity_flag = 0;
DLIK = [];
AHess = [];
Hess = [];
if DynareOptions.estimation_dll
[fval,exit_flag,ys,trend_coeff,info,params,H,Q] ...
......@@ -167,12 +167,11 @@ if DynareOptions.estimation_dll
end
% Set flag related to analytical derivatives.
if nargout > 9
analytic_derivation=1;
else
analytic_derivation = DynareOptions.analytic_derivation;
if nargout==1,
analytic_derivation=0;
end
%------------------------------------------------------------------------------
% 1. Get the structural parameters & define penalties
%------------------------------------------------------------------------------
......@@ -183,6 +182,9 @@ if ~isequal(DynareOptions.mode_compute,1) && any(xparam1<BayesInfo.lb)
fval = penalty+sum((BayesInfo.lb(k)-xparam1(k)).^2);
exit_flag = 0;
info = 41;
if analytic_derivation,
DLIK=ones(length(xparam1),1);
end
return
end
......@@ -192,6 +194,9 @@ if ~isequal(DynareOptions.mode_compute,1) && any(xparam1>BayesInfo.ub)
fval = penalty+sum((xparam1(k)-BayesInfo.ub(k)).^2);
exit_flag = 0;
info = 42;
if analytic_derivation,
DLIK=ones(length(xparam1),1);
end
return
end
......@@ -282,11 +287,17 @@ if info(1) == 1 || info(1) == 2 || info(1) == 5 || info(1) == 7 || info(1) == 22
fval = penalty+1;
info = info(1);
exit_flag = 0;
if analytic_derivation,
DLIK=ones(length(xparam1),1);
end
return
elseif info(1) == 3 || info(1) == 4 || info(1)==6 ||info(1) == 19 || info(1) == 20 || info(1) == 21 || info(1) == 23
fval = penalty+info(2);
info = info(1);
exit_flag = 0;
if analytic_derivation,
DLIK=ones(length(xparam1),1);
end
return
end
......@@ -472,7 +483,11 @@ end
if analytic_derivation
no_DLIK = 0;
full_Hess = 0;
full_Hess = analytic_derivation==2;
asy_Hess = analytic_derivation==-2;
if asy_Hess,
analytic_derivation=1;
end
DLIK = [];
AHess = [];
if nargin<8 || isempty(derivatives_info)
......@@ -489,9 +504,9 @@ if analytic_derivation
end
if full_Hess,
[dum, DT, DOm, DYss, dum2, D2T, D2Om, D2Yss] = getH(A, B, Model,DynareResults,0,indparam,indexo);
[dum, DT, DOm, DYss, dum2, D2T, D2Om, D2Yss] = getH(A, B, Model,DynareResults,0,indparam,indexo);
else
[dum, DT, DOm, DYss] = getH(A, B, Model,DynareResults,0,indparam,indexo);
[dum, DT, DOm, DYss] = getH(A, B, Model,DynareResults,0,indparam,indexo);
end
else
DT = derivatives_info.DT;
......@@ -576,6 +591,13 @@ if analytic_derivation
end
end
end
if analytic_derivation==1,
analytic_deriv_info={analytic_derivation,DT,DYss,DOm,DH,DP};
else
analytic_deriv_info={analytic_derivation,DT,DYss,DOm,DH,DP,D2T,D2Yss,D2Om,D2H,D2P};
end
else
analytic_deriv_info={0};
end
%------------------------------------------------------------------------------
......@@ -592,19 +614,9 @@ if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter
a,Pstar, ...
kalman_tol, riccati_tol, ...
DynareOptions.presample, ...
T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods);
end
if analytic_derivation
if no_DLIK==0
[DLIK] = score(T,R,Q,H,Pstar,Y,DT,DYss,DOm,DH,DP,start,Z,kalman_tol,riccati_tol);
end
if nargout==11
[AHess] = AHessian(T,R,Q,H,Pstar,Y,DT,DYss,DOm,DH,DP,start,Z,kalman_tol,riccati_tol);
if full_Hess,
Hess = get_Hessian(T,R,Q,H,Pstar,Y,DT,DYss,DOm,DH,DP,D2T,D2Yss,D2Om,D2H,D2P,start,Z,kalman_tol,riccati_tol);
Hess0 = getHessian(Y,T,DT,D2T, R*Q*transpose(R),DOm,D2Om,Z,DYss,D2Yss);
end
end
T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods, ...
analytic_deriv_info{:});
end
else
[LIK,lik] = missing_observations_kalman_filter(DynareDataset.missing.aindex,DynareDataset.missing.number_of_observations,DynareDataset.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ...
......@@ -613,6 +625,10 @@ if ((kalman_algo==1) || (kalman_algo==3))% Multivariate Kalman Filter
DynareOptions.presample, ...
T,Q,R,H,Z,mm,pp,rr,Zflag,diffuse_periods);
end
if analytic_derivation,
LIK1=LIK;
LIK=LIK1{1};
end
if isinf(LIK)
if kalman_algo == 1
kalman_algo = 2;
......@@ -636,10 +652,19 @@ if (kalman_algo==2) || (kalman_algo==4)
if isequal(H,0)
H = zeros(pp,1);
mmm = mm;
if analytic_derivation,
DH = zeros(pp,length(xparam1));
end
else
if all(all(abs(H-diag(diag(H)))<1e-14))% ie, the covariance matrix is diagonal...
H = diag(H);
mmm = mm;
if analytic_derivation,
for j=1:pp,
tmp(j,:)=DH(j,j,:);
end
DH=tmp;
end
else
Z = [Z, eye(pp)];
T = blkdiag(T,zeros(pp));
......@@ -651,6 +676,9 @@ if (kalman_algo==2) || (kalman_algo==4)
mmm = mm+pp;
end
end
if analytic_derivation,
analytic_deriv_info{5}=DH;
end
end
[LIK, lik] = univariate_kalman_filter(DynareDataset.missing.aindex,DynareDataset.missing.number_of_observations,DynareDataset.missing.no_more_missing_observations,Y,diffuse_periods+1,size(Y,2), ...
......@@ -658,7 +686,11 @@ if (kalman_algo==2) || (kalman_algo==4)
DynareOptions.kalman_tol, ...
DynareOptions.riccati_tol, ...
DynareOptions.presample, ...
T,Q,R,H,Z,mmm,pp,rr,Zflag,diffuse_periods);
T,Q,R,H,Z,mmm,pp,rr,Zflag,diffuse_periods,analytic_deriv_info{:});
if analytic_derivation,
LIK1=LIK;
LIK=LIK1{1};
end
if DynareOptions.lik_init==3
LIK = LIK+dLIK;
if analytic_derivation==0 && nargout==2,
......@@ -667,6 +699,22 @@ if (kalman_algo==2) || (kalman_algo==4)
end
end
if analytic_derivation
if no_DLIK==0
DLIK = LIK1{2};
% [DLIK] = score(T,R,Q,H,Pstar,Y,DT,DYss,DOm,DH,DP,start,Z,kalman_tol,riccati_tol);
end
if full_Hess,
Hess = -LIK1{3};
% [Hess, DLL] = get_Hessian(T,R,Q,H,Pstar,Y,DT,DYss,DOm,DH,DP,D2T,D2Yss,D2Om,D2H,D2P,start,Z,kalman_tol,riccati_tol);
% Hess0 = getHessian(Y,T,DT,D2T, R*Q*transpose(R),DOm,D2Om,Z,DYss,D2Yss);
end
if asy_Hess,
[Hess] = AHessian(T,R,Q,H,Pstar,Y,DT,DYss,DOm,DH,DP,start,Z,kalman_tol,riccati_tol);
end
end
if isnan(LIK)
info = 45;
exit_flag = 0;
......@@ -684,7 +732,7 @@ end
if analytic_derivation
if full_Hess,
[lnprior, dlnprior, d2lnprior] = priordens(xparam1,BayesInfo.pshape,BayesInfo.p6,BayesInfo.p7,BayesInfo.p3,BayesInfo.p4);
AHess = Hess + d2lnprior;
Hess = Hess - d2lnprior;
else
[lnprior, dlnprior] = priordens(xparam1,BayesInfo.pshape,BayesInfo.p6,BayesInfo.p7,BayesInfo.p3,BayesInfo.p4);
end
......@@ -705,4 +753,4 @@ penalty = fval;
if analytic_derivation==0 && nargout==2,
lik=lik(start:end,:);
DLIK=[-lnprior; lik(:)];
end
end
\ No newline at end of file
......@@ -53,6 +53,12 @@ end
M_.dname = dname;
if options_.mode_compute && options_.analytic_derivation,
analytic_derivation0=options_.analytic_derivation;
options_.analytic_derivation=1;
end
if nnobs > 1
for i=1:nnobs
options_.nobs = nobs(i);
......@@ -64,6 +70,10 @@ else
dynare_estimation_1(var_list,dname);
end
if options_.mode_compute && options_.analytic_derivation,
options_.analytic_derivation=analytic_derivation0;
end
if nnobs > 1 && horizon > 0
mh_replic = options_.mh_replic;
rawdata = read_variables(options_.datafile,options_.varobs,[],options_.xls_sheet,options_.xls_range);
......
......@@ -167,6 +167,9 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
'MaxFunEvals',100000,'TolFun',1e-8,'TolX',1e-6);
if isfield(options_,'optim_opt')
eval(['optim_options = optimset(optim_options,' options_.optim_opt ');']);
end
if options_.analytic_derivation,
optim_options = optimset(optim_options,'GradObj','on');
end
[xparam1,fval,exitflag,output,lamdba,grad,hessian_fmincon] = ...
fmincon(objective_function,xparam1,[],[],[],[],lb,ub,[],optim_options,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
......@@ -177,14 +180,23 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
if isfield(options_,'optim_opt')
eval(['optim_options = optimset(optim_options,' options_.optim_opt ');']);
end
if options_.analytic_derivation,
optim_options = optimset(optim_options,'GradObj','on');
end
[xparam1,fval,exitflag] = fminunc(objective_function,xparam1,optim_options,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
case 4
H0 = 1e-4*eye(nx);
crit = 1e-7;
nit = 1000;
verbose = 2;
if options_.analytic_derivation,
analytic_grad=1;
else
analytic_grad=[];
end
[fval,xparam1,grad,hessian_csminwel,itct,fcount,retcodehat] = ...
csminwel1(objective_function,xparam1,H0,[],crit,nit,options_.gradient_method,options_.gradient_epsilon,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
csminwel1(objective_function,xparam1,H0,analytic_grad,crit,nit,options_.gradient_method,options_.gradient_epsilon,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
disp(sprintf('Objective function at mode: %f',fval))
case 5
if isfield(options_,'hess')
......@@ -350,8 +362,17 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation
end
if ~isequal(options_.mode_compute,6) && ~isequal(options_.mode_compute,'prior')
if options_.cova_compute == 1
hh = reshape(hessian(objective_function,xparam1, ...
options_.gstep,dataset_,options_,M_,estim_params_,bayestopt_,oo_),nx,nx);
if options_.analytic_derivation && strcmp(func2str(objective_function),'dsge_likelihood'),
ana_deriv = options_.analytic_derivation;
options_.analytic_derivation = 2;
[junk1, junk2, hh] = feval(objective_function,xparam1, ...
dataset_,options_,M_,estim_params_,bayestopt_,oo_);
options_.analytic_derivation = ana_deriv;
else
hh = reshape(hessian(objective_function,xparam1, ...
options_.gstep,dataset_,options_,M_,estim_params_,bayestopt_,oo_),nx,nx);
end
end
end
parameter_names = bayestopt_.name;
......@@ -865,11 +886,14 @@ if (any(bayestopt_.pshape >0 ) && options_.mh_replic) || ...
if options_.load_mh_file && options_.use_mh_covariance_matrix
invhess = compute_mh_covariance_matrix;
end
ana_deriv = options_.analytic_derivation;
options_.analytic_derivation = 0;
if options_.cova_compute
feval(options_.posterior_sampling_method,objective_function,options_.proposal_distribution,xparam1,invhess,bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_);
else
error('I Cannot start the MCMC because the hessian of the posterior kernel at the mode was not computed.')
end
options_.analytic_derivation = ana_deriv;
end
if options_.mh_posterior_mode_estimation
CutSample(M_, options_, estim_params_);
......
......@@ -284,6 +284,13 @@ else
bayestopt_.smoother_var_list);
end;
if options_.analytic_derivation,
if ~(exist('sylvester3','file')==2),
dynareroot = strrep(which('dynare'),'dynare.m','');
addpath([dynareroot 'gensylv'])
end
end
% Test if the data file is declared.
if isempty(options_.datafile)
if gsa_flag
......
......@@ -52,11 +52,11 @@ for i=1:m
else
h = H(:,i);
end
[Fh,flag] = feval(fcn, x+transpose(h), varargin{:});
[Fh,junk1,junk2,flag] = feval(fcn, x+transpose(h), varargin{:});
if flag
G(:,i) = (Fh-F)/epsilon;
else
[Fh,flag] = feval(fcn, x-transpose(h), varargin{:});
[Fh,junk1,junk2,flag] = feval(fcn, x-transpose(h), varargin{:});
if flag
G(:,i) = (F-Fh)/epsilon;
else
......
......@@ -131,11 +131,12 @@ if info(1)==0,
options_.order = 1;
options_.periods = data_info.info.ntobs+100;
options_.kalman_algo = 1;
options_.analytic_derivation = -2;
info = stoch_simul(options_.varobs);
data_info.data=oo_.endo_simul(options_.varobs_id,100+1:end);
% datax=data;
derivatives_info.no_DLIK=1;
[fval,cost_flag,ys,trend_coeff,info,M_,options_,bayestopt_,oo_,DLIK,AHess] = dsge_likelihood(params',data_info,options_,M_,estim_params_,bayestopt_,oo_,derivatives_info);
[fval,DLIK,AHess,cost_flag,ys,trend_coeff,info,M_,options_,bayestopt_,oo_] = dsge_likelihood(params',data_info,options_,M_,estim_params_,bayestopt_,oo_,derivatives_info);
% fval = DsgeLikelihood(xparam1,data_info,options_,M_,estim_params_,bayestopt_,oo_);
AHess=-AHess;
if min(eig(AHess))<0,
......
......@@ -38,7 +38,7 @@ end
[DynareResults.steady_state] = evaluate_steady_state(DynareResults.steady_state,Model,DynareOptions,DynareResults,DynareOptions.diffuse_filter==0);
% Evaluate the likelihood.
[fval,a,b,c,d] = feval(objective_function,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults);
[fval,junk1,junk2,a,b,c,d] = feval(objective_function,xparam1,DynareDataset,DynareOptions,Model,EstimatedParameters,BayesInfo,DynareResults);
if DynareOptions.dsge_var
info = b;
......
function [Da,DP1,DLIK,D2a,D2P1,Hesst] = computeDLIK(k,tmp,Z,Zflag,v,T,K,P,iF,Da,DYss,DT,DOm,DP,DH,notsteady,D2a,D2Yss,D2T,D2Om,D2P)
% Copyright (C) 2012 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
% AUTHOR(S) marco.ratto@jrc.ec.europa.eu
persistent DK DF D2K D2F
if notsteady
if Zflag
[DK,DF,DP1] = computeDKalmanZ(T,DT,DOm,P,DP,DH,Z,iF,K);
if nargout>3,
[D2K,D2F,D2P1] = computeD2KalmanZ(T,DT,D2T,D2Om,P,DP,D2P,DH,Z,iF,K,DK);
end
else
[DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,Z,iF,K);
if nargout>3,
[D2K,D2F,D2P1] = computeD2Kalman(T,DT,D2T,D2Om,P,DP,D2P,DH,Z,iF,K,DK);
end
end
else
DP1=DP;
if nargout>3,
D2P1=D2P;
end
end
Dv=zeros(length(v),k);
% D2v=zeros(length(v),k,k);
for ii = 1:k
if Zflag
Dv(:,ii) = -Z*Da(:,ii) - Z*DYss(:,ii);
% if nargout>4,
% for jj = 1:ii
% D2v(:,jj,ii) = -Z*D2Yss(:,jj,ii) - Z*D2a(:,jj,ii);
% D2v(:,ii,jj) = D2v(:,jj,ii);
% end
% end
else
Dv(:,ii) = -Da(Z,ii) - DYss(Z,ii);
% if nargout>4,
% for jj = 1:ii
% D2v(:,jj,ii) = -D2Yss(Z,jj,ii) - D2a(Z,jj,ii);
% D2v(:,ii,jj) = D2v(:,jj,ii);
% end
% end
end
end
Hesst = zeros(k,k);
DLIK=zeros(k,1);
for ii = 1:k
% dai = da(:,:,ii);
dKi = DK(:,:,ii);
dtmp(:,ii) = Da(:,ii)+dKi*v+K*Dv(:,ii);
if nargout>4,
diFi = -iF*DF(:,:,ii)*iF;
for jj = 1:ii
dFj = DF(:,:,jj);
diFj = -iF*DF(:,:,jj)*iF;
dKj = DK(:,:,jj);
d2Kij = D2K(:,:,jj,ii);
d2Fij = D2F(:,:,jj,ii);
d2iFij = -diFi*dFj*iF -iF*d2Fij*iF -iF*dFj*diFi;
% dtmpj = Da(:,jj)+dKj*v+K*Dv(:,jj);
% d2vij = D2v(:,ii,jj);
if Zflag
d2vij = -Z*D2Yss(:,jj,ii) - Z*D2a(:,jj,ii);
else
d2vij = -D2Yss(Z,jj,ii) - D2a(Z,jj,ii);
end
d2tmpij = D2a(:,jj,ii) + d2Kij*v + dKj*Dv(:,ii) + dKi*Dv(:,jj) + K*d2vij;
D2a(:,jj,ii) = D2T(:,:,jj,ii)*tmp + DT(:,:,jj)*dtmp(:,ii) + DT(:,:,ii)*dtmp(:,jj) + T*d2tmpij;
D2a(:,ii,jj) = D2a(:,jj,ii);
if nargout==6,
Hesst(ii,jj) = getHesst_ij(v,Dv(:,ii),Dv(:,jj),d2vij,iF,diFi,diFj,d2iFij,dFj,d2Fij);
end
end
end
Da(:,ii) = DT(:,:,ii)*tmp + T*dtmp(:,ii);
DLIK(ii,1) = trace( iF*DF(:,:,ii) ) + 2*Dv(:,ii)'*iF*v - v'*(iF*DF(:,:,ii)*iF)*v;
end
% end of computeDLIK
function Hesst_ij = getHesst_ij(e,dei,dej,d2eij,iS,diSi,diSj,d2iSij,dSj,d2Sij);
% computes (i,j) term in the Hessian
Hesst_ij = trace(diSi*dSj + iS*d2Sij) + e'*d2iSij*e + 2*(dei'*diSj*e + dei'*iS*dej + e'*diSi*dej + e'*iS*d2eij);
% end of getHesst_ij
function [DK,DF,DP1] = computeDKalman(T,DT,DOm,P,DP,DH,Z,iF,K)
k = size(DT,3);
tmp = P-K*P(Z,:);
DF = zeros([size(iF),k]);
DK = zeros([size(K),k]);
DP1 = zeros([size(P),k]);
for ii = 1:k
DF(:,:,ii) = DP(Z,Z,ii) + DH(:,:,ii);
DiF = -iF*DF(:,:,ii)*iF;
DK(:,:,ii) = DP(:,Z,ii)*iF + P(:,Z)*DiF;
Dtmp = DP(:,:,ii) - DK(:,:,ii)*P(Z,:) - K*DP(Z,:,ii);
DP1(:,:,ii) = DT(:,:,ii)*tmp*T' + T*Dtmp*T' + T*tmp*DT(:,:,ii)' + DOm(:,:,ii);
end
% end of computeDKalman