dynare/matlab/+pruned_SS/pruned_state_space_system.m

1234 lines
70 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

function pruned_state_space = pruned_state_space_system(M_, options_, dr, indy, nlags, useautocorr, compute_derivs)
% Set up the pruned state space ABCD representation:
% z = c + A*z(-1) + B*inov
% y = ys + d + C*z(-1) + D*inov
% References:
% - Andreasen, Martin M., Jesús Fernández-Villaverde and Juan F. Rubio-Ramírez (2018):
% "The Pruned State-Space System for Non-Linear DSGE Models: Theory and Empirical Applications",
% Review of Economic Studies, Volume 85, Issue 1, Pages 149.
% - Mutschler, Willi (2018): "Higher-order statistics for DSGE models",
% Econometrics and Statistics, Volume 6, Pages 44-56.
% =========================================================================
% INPUTS
% M_: [structure] storing the model information
% options_: [structure] storing the options
% dr: [structure] storing the results from perturbation approximation
% indy: [vector] index of control variables in DR order
% nlags: [integer] number of lags in autocovariances and autocorrelations
% useautocorr: [boolean] true: compute autocorrelations
% compute_derivs: [boolean] true: compute derivatives
% -------------------------------------------------------------------------
% OUTPUTS
% pruned_state_space: [structure] with the following fields:
% indx: [x_nbr by 1]
% index of state variables
% indy: [y_nbr by 1]
% index of control variables
% A: [z_nbr by z_nbr]
% state space transition matrix A mapping previous states to current states
% B: [z_nbr by inov_nbr]
% state space transition matrix B mapping current inovations to current states
% c: [z_nbr by 1]
% state space transition matrix c mapping constants to current states
% C: [y_nbr by z_nbr]
% state space measurement matrix C mapping previous states to current controls
% D: [y_nbr by inov_nbr]
% state space measurement matrix D mapping current inovations to current controls
% d: [y_nbr by 1]
% state space measurement matrix d mapping constants to current controls
% Var_inov [inov_nbr by inov_nbr]
% contemporenous covariance matrix of innovations, i.e. E[inov*inov']
% Var_z [z_nbr by z_nbr]
% contemporenous covariance matrix of states z
% Var_y [y_nbr by y_nbr]
% contemporenous covariance matrix of controls y
% Var_yi [y_nbr by y_nbr by nlags]
% autocovariance matrix of controls y
% Corr_y [y_nbr by y_nbr]
% contemporenous correlation matrix of controls y
% Corr_yi [y_nbr by y_nbr by nlags]
% autocorrelation matrix of controls y
% E_y [y_nbr by 1]
% unconditional theoretical mean of control variables y
%
% if compute_derivs == 1, then the following additional fields are outputed:
% dA: [z_nbr by z_nbr by totparam_nbr]
% parameter Jacobian of A
% dB: [z_nbr by inov_nbr by totparam_nbr]
% parameter Jacobian of B
% dc: [z_nbr by totparam_nbr]
% parameter Jacobian of c
% dC: [y_nbr by z_nbr by totparam_nbr]
% parameter Jacobian of C
% dD: [y_nbr by inov_nbr by totparam_nbr]
% parameter Jacobian of D
% dd: [y_nbr by totparam_nbr]
% parameter Jacobian of d
% dVar_inov [inov_nbr by inov_nbr by totparam_nbr]
% parameter Jacobian of Var_inov
% dVar_z [z_nbr by z_nbr by totparam_nbr]
% parameter Jacobian of Var_z
% dVar_y [y_nbr by y_nbr by totparam_nbr]
% parameter Jacobian of Var_y
% dVar_yi [y_nbr by y_nbr by nlags by totparam_nbr]
% parameter Jacobian of Var_yi
% dCorr_y [y_nbr by y_nbr by totparam_nbr]
% parameter Jacobian of Corr_y
% dCorr_yi [y_nbr by y_nbr by nlags by totparam_nbr]
% parameter Jacobian of Corr_yi
% dE_y [y_nbr by totparam_nbr]
% parameter Jacobian of E_y
% -------------------------------------------------------------------------
% This function is called by
% * identification.get_jacobians.m
% * identification.numerical_objective.m
% -------------------------------------------------------------------------
% This function calls
% * allVL1.m
% * commutation.m
% * disclyap_fast (MEX)
% * duplication.m
% * lyapunov_symm.m
% * prodmom
% * prodmom_deriv
% * Q6_plication
% * quadruplication.m
% * vec.m
% =========================================================================
% Copyright © 2019-2020 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 <https://www.gnu.org/licenses/>.
% =========================================================================
%% MAIN IDEA:
% Decompose the state vector x into first-order effects xf, second-order
% effects xs, and third-order effects xrd, i.e. x=xf+xs+xrd. Then, Dynare's
% perturbation approximation for the state vector up to third order
% (with Gaussian innovations u, i.e. no odd moments, hxxs=huus=hxus=hsss=0) is:
% x = hx*( xf(-1)+xs(-1)+xrd(-1) )
% + hu*u
% + 1/2*hxx*kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) )
% + hxu*kron( xf(-1)+xs(-1)+xrd(-1) , u )
% + 1/2*huu*kron( u , u )
% + 1/2*hss*sig^2
% + 1/6*hxxx*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , xf(-1)+xs(-1)+xrd(-1) )
% + 1/6*huuu*kron( kron( u , u ) , u )
% + 3/6*hxxu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , u )
% + 3/6*hxuu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , u ) , u)
% + 3/6*hxss*( xf(-1)+xs(-1)+xrd(-1) )*sig^2
% + 3/6*huss*u*sig^2
% where:
% hx = dr.ghx(indx,:); hu = dr.ghu(indx,:);
% hxx = dr.ghxx(indx,:); hxu = dr.ghxu(indx,:); huu = dr.ghuu(indx,:); hss = dr.ghs2(indx,:);
% hxxx = dr.ghxxx(indx,:); huuu = dr.ghuuu(indx,:); hxxu = dr.ghxxu(indx,:); hxuu = dr.ghxxu(indx,:); hxss = dr.ghxss(indx,:); huss = dr.ghuss(indx,:);
% and similarly for control variables:
% y = gx*( xf(-1)+xs(-1)+xrd(-1) )
% + gu*u
% + 1/2*gxx*kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) )
% + gxu*kron( xf(-1)+xs(-1)+xrd(-1) , u )
% + 1/2*guu*kron( u , u )
% + 1/2*gss*sig^2
% + 1/6*gxxx*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , xf(-1)+xs(-1)+xrd(-1) )
% + 1/6*guuu*kron( kron( u , u ) , u )
% + 3/6*gxxu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , xf(-1)+xs(-1)+xrd(-1) ) , u )
% + 3/6*gxuu*kron( kron( xf(-1)+xs(-1)+xrd(-1) , u ) , u)
% + 3/6*gxss*( xf(-1)+xs(-1)+xrd(-1) )*sig^2
% + 3/6*guss*u*sig^2
% where:
% gx = dr.ghx(indy,:); gu = dr.ghu(indy,:);
% gxx = dr.ghxx(indy,:); gxu = dr.ghxu(indy,:); guu = dr.ghuu(indy,:); gss = dr.ghs2(indy,:);
% gxxx = dr.ghxxx(indy,:); guuu = dr.ghuuu(indy,:); gxxu = dr.ghxxu(indy,:); gxuu = dr.ghxxu(indy,:); gxss = dr.ghxss(indy,:); guss = dr.ghuss(indy,:);
%
% PRUNING means getting rid of terms higher than the approximation order, i.e.
% - involving fourth-order effects: kron(xf,xrd), kron(xs,xs), kron(xrd,xf), kron(xrd,u),
% kron(kron(xf,xf),xs), kron(kron(xf,xs),xf), kron(kron(xs,xf),xf)
% kron(kron(xf,xs),u), kron(kron(xs,xf),u)
% kron(kron(xs,u),u)
% xs*sig^2
% - involving fifth-order effects: kron(xs,xrd), kron(xrd,xs),
% kron(kron(xf,xf),xrd), kron(kron(xf,xs),xs), kron(kron(xf,xrd),xf), kron(kron(xs,xf),xs), kron(kron(xs,xs),xf), kron(kron(xrd,xf),xf)
% kron(kron(xf,xrd),u), kron(kron(xs,xs),u), kron(kron(xrd,xf),u)
% kron(kron(xrd,u),u)
% xrd*sig^2
% - involving sixth-order effects: kron(xrd,xrd),
% kron(kron(xf,xs),xrd), kron(kron(xf,xrd),xs), kron(kron(xs,xrd),xrd), kron(kron(xs,xs),xs), kron(kron(xs,xrd),xf), kron(kron(xf,xf),xs), kron(kron(xrd,xs),xf)
% kron(kron(xs,xrd),u), kron(kron(xrd,xs),u)
% - involving seventh-order effects: kron(kron(xf,xrd),xrd), kron(kron(xs,xs),xrd), kron(kron(xs,xrd),xs), kron(kron(xrd,xf),xrd), kron(kron(xrd,xs),xs), kron(kron(xrd,xrd),xf)
% kron(kron(xrd,xrd),u)
% - involving eighth-order effects: kron(kron(xs,xrd),xrd), kron(kron(xrd,xs),xrd), kron(kron(xrd,xrd),xs)
% - involving ninth-order effects: kron(kron(xrd,xrd),xrd)
% Note that u is treated as a first-order effect and the perturbation parameter sig as a variable.
%
% SUMMARY OF LAW OF MOTIONS: Set up the law of motions for the individual effects, but keep only effects of same order
% Notation: I_n=eye(n) and K_m_n=commutation(m,n)
%
% First-order effects: keep xf and u
% xf = hx*xf(-1) + hu*u
% Note that we
%
% Second-order effects: keep xs, kron(xf,xf), kron(u,u), kron(xf,u), and sig^2
% xs = hx*xs(-1) + 1/2*hxx*kron(xf(-1),xf(-1)) + 1/2*huu*(kron(u,u)-Sigma_e(:)+Sigma_e(:)) + hxu*kron(xf(-1),u) + 1/2*hss*sig^2%
%
% Third-order effects: keep xrd, kron(xf,xs), kron(xs,xf), kron(xs,u), kron(kron(xf,xf),xf), kron(kron(u,u),u), kron(kron(xf,xf),u), kron(kron(xf,u),u), xf*sig^2, u*sig^2
% xrd = hx*xrd(-1) + 1/2*hxx*(kron(xf(-1),xs(-1))+kron(xs(-1),xf(-1))) + hxu*kron(xs(-1),u) + 1/6*hxxx*kron(xf(-1),kron(xf(-1),xf(-1))) + 1/6*huuu*kron(u,kron(u,u)) + 3/6*hxxu*kron(xf(-1),kron(xf(-1),u)) + 3/6*hxuu*kron(xf(-1),kron(u,u)) + 3/6*hxss*xf(-1)*sig^2 + 3/6*huss*u*sig^2
% Simplified (due to symmetry in hxx):
% xrd = hx*xrd(-1) + hxx*(kron(xf(-1),xs(-1)) + hxu*kron(xs(-1),u) + 1/6*hxxx*kron(xf(-1),kron(xf(-1),xf(-1))) + 1/6*huuu*kron(u,kron(u,u)) + 3/6*hxxu*kron(xf(-1),kron(xf(-1),u)) + 3/6*hxuu*kron(xf(-1),kron(u,u)) + 3/6*hxss*xf(-1)*sig^2 + 3/6*huss*u*sig^2%
%
% Auxiliary equation kron(xf,xf) to set up the VAR(1) pruned state space system
% kron(xf,xf) = kron(hx,hx)*kron(xf(-1),xf(-1)) + kron(hu,hu)*(kron(u,u)-Sigma_e(:)+Sigma_e(:)) + kron(hx,u)*kron(xf(-1),u) + kron(u,hx)*kron(u,xf(-1))
% Simplified using commutation matrix:
% kron(xf,xf) = kron(hx,hx)*kron(xf(-1),xf(-1)) + (I_xx+K_x_x)*kron(hx,hu)*kron(xf(-1),u) + kron(hu,hu)*kron(u,u)
%
% Auxiliary equation kron(xf,xs) to set up the VAR(1) pruned state space system
% kron(xf,xs) = kron(hx,hx)*kron(xf(-1),xs(-1)) + kron(hu,hx)*kron(u,xs(-1))
% + kron(hx,1/2*hxx)*kron(kron(xf(-1),xf(-1)),xf(-1)) + kron(hu,1/2*hxx)*kron(kron(u,xf(-1)),xf(-1))
% + kron(hx,1/2*huu)*kron(kron(xf(-1),u),u) + kron(hu,1/2*huu)*kron(kron(u,u),u)
% + kron(hx,hxu)*kron(kron(xf(-1),xf(-1)),u) + kron(hu,hxu)*kron(kron(u,xf(-1)),u)
% + kron(hx,1/2*hss)*xf(-1)*sig^2 + kron(hu,1/2*hss)*u*sig^2
% Simplified using commutation matrix:
% kron(xf,xs) = kron(hx,hx)*kron(xf(-1),xs(-1))
% + K_x_x*kron(hx,hu)*kron(xs(-1),u)
% + kron(hx,1/2*hxx)*kron(kron(xf(-1),xf(-1)),xf(-1))
% + ( kron(hx,hxu) + K_x_x*kron(1/2*hxx,hu) )*kron(kron(xf(-1),xf(-1)),u)
% + ( kron(hx,1/2*huu) + K_x_x*kron(hxu,hu) )*kron(kron(xf(-1),u),u)
% + kron(hu,1/2*huu)*kron(kron(u,u),u)
% + kron(hx,1/2*hss)*xf(-1)*sig^2
% + kron(hu,1/2*hss)*u*sig^2
%
% Auxiliary equation kron(kron(xf,xf),xf) to set up the VAR(1) pruned state space system
% kron(kron(xf,xf),xf) = kron(kron(hx,hx),hx)*kron(kron(xf(-1),xf(-1)),xf(-1))
% + kron(kron(hx,hu),hx)*kron(kron(xf(-1),u),xf(-1))
% + kron(kron(hx,hx),hu)*kron(kron(xf(-1),xf(-1)),u)
% + kron(kron(hx,hu),hu)*kron(kron(xf(-1),u),u)
% + kron(kron(hu,hx),hx)*kron(kron(u,xf(-1)),xf(-1))
% + kron(kron(hu,hu),hx)*kron(kron(u,u),xf(-1))
% + kron(kron(hu,hx),hu)*kron(kron(u,xf(-1)),u)
% + kron(kron(hu,hu),hu)*kron(kron(u,u),u)
% Simplified using commutation matrix:
% kron(kron(xf,xf),xf) = kron(kron(hx,hx),hx)*kron(kron(xf(-1),xf(-1)),xf(-1))
% + ( kron(kron(hx,hx),hu) + K_xx_x*kron(hx,(I_xx+K_x_x)*kron(hx,hu)) )*kron(kron(xf(-1),xf(-1)),u)
% + ( kron((I_xx+K_x_x)*kron(hx,hu),hu) + K_xx_x*kron(kron(hx,hu),hu) )*kron(kron(xf(-1),u),u)
% + kron(kron(hu,hu),hu)*kron(kron(u,u),u)
%
% Law of motion for control variables y (either VAROBS variables or if no VAROBS statement is given then for all endogenous variables)
% y = steady_state(y)
% + gx*( xf(-1)+xs(-1)+xrd(-1) )
% + gu*u
% + 1/2*gxx*kron(xf(-1),xf(-1)) + gxx*kron(xf(-1),xs(-1))
% + gxu*kron(xf(-1),u) + gxu*kron(xs(-1),u)
% + 1/2*guu*(kron(u,u)-Sigma_e+Sigma_e)
% + 1/2*gss*sig^2
% + 1/6*gxxx*kron(kron(xf(-1),xf(-1)),xf(-1))
% + 1/6*guuu*kron(kron(u,u),u)
% + 3/6*gxxu*kron(kron(xf(-1),xf(-1),u)
% + 3/6*gxuu*kron(kron(xf(-1),u),u)
% + 3/6*gxss*xf(-1)*sig^2
% + 3/6*guss*u*sig^2
%
% See code below how z and inov are defined at first, second, and third order,
% and how to set up A, B, C, D and compute unconditional first and second moments of inov, z and y
persistent QPu COMBOS4 Q6Pu COMBOS6 K_u_xx K_u_ux K_xx_x
%% Auxiliary indices and objects
order = options_.order;
if isempty(options_.qz_criterium)
% set default value for qz_criterium: if there are no unit roots one can use 1.0
% If they are possible, you may have have multiple unit roots and the accuracy
% decreases when computing the eigenvalues in lyapunov_symm. Hence, we normally use 1+1e-6
% Note that unit roots are only possible at first-order, at higher order we set it to 1
options_.qz_criterium = 1+1e-6;
end
indx = [M_.nstatic+(1:M_.nspred) M_.endo_nbr+(1:size(dr.ghx,2)-M_.nspred)]';
if isempty(indy)
indy = (1:M_.endo_nbr)'; %by default select all variables in DR order
end
u_nbr = M_.exo_nbr;
x_nbr = length(indx);
y_nbr = length(indy);
Yss = dr.ys(dr.order_var);
hx = dr.ghx(indx,:);
gx = dr.ghx(indy,:);
hu = dr.ghu(indx,:);
gu = dr.ghu(indy,:);
E_uu = M_.Sigma_e; %this is E[u*u']
if compute_derivs
stderrparam_nbr = length(dr.derivs.indpstderr);
corrparam_nbr = size(dr.derivs.indpcorr,1);
modparam_nbr = length(dr.derivs.indpmodel);
totparam_nbr = stderrparam_nbr+corrparam_nbr+modparam_nbr;
dYss = dr.derivs.dYss;
dhx = dr.derivs.dghx(indx,:,:);
dgx = dr.derivs.dghx(indy,:,:);
dhu = dr.derivs.dghu(indx,:,:);
dgu = dr.derivs.dghu(indy,:,:);
dE_uu = dr.derivs.dSigma_e;
end
% first-order approximation indices for extended state vector z and extended innovations vector inov
id_z1_xf = (1:x_nbr);
id_inov1_u = (1:u_nbr);
if order > 1
% second-order approximation indices for extended state vector z and extended innovations vector inov
id_z2_xs = id_z1_xf(end) + (1:x_nbr);
id_z3_xf_xf = id_z2_xs(end) + (1:x_nbr*x_nbr);
id_inov2_u_u = id_inov1_u(end) + (1:u_nbr*u_nbr);
id_inov3_xf_u = id_inov2_u_u(end) + (1:x_nbr*u_nbr);
hxx = dr.ghxx(indx,:);
gxx = dr.ghxx(indy,:);
hxu = dr.ghxu(indx,:);
gxu = dr.ghxu(indy,:);
huu = dr.ghuu(indx,:);
guu = dr.ghuu(indy,:);
hss = dr.ghs2(indx,:);
gss = dr.ghs2(indy,:);
if compute_derivs
dhxx = dr.derivs.dghxx(indx,:,:);
dgxx = dr.derivs.dghxx(indy,:,:);
dhxu = dr.derivs.dghxu(indx,:,:);
dgxu = dr.derivs.dghxu(indy,:,:);
dhuu = dr.derivs.dghuu(indx,:,:);
dguu = dr.derivs.dghuu(indy,:,:);
dhss = dr.derivs.dghs2(indx,:);
dgss = dr.derivs.dghs2(indy,:);
end
end
if order > 2
% third-order approximation indices for extended state vector z and extended innovations vector inov
id_z4_xrd = id_z3_xf_xf(end) + (1:x_nbr);
id_z5_xf_xs = id_z4_xrd(end) + (1:x_nbr*x_nbr);
id_z6_xf_xf_xf = id_z5_xf_xs(end) + (1:x_nbr*x_nbr*x_nbr);
id_inov4_xs_u = id_inov3_xf_u(end) + (1:x_nbr*u_nbr);
id_inov5_xf_xf_u = id_inov4_xs_u(end) + (1:x_nbr*x_nbr*u_nbr);
id_inov6_xf_u_u = id_inov5_xf_xf_u(end) + (1:x_nbr*u_nbr*u_nbr);
id_inov7_u_u_u = id_inov6_xf_u_u(end) + (1:u_nbr*u_nbr*u_nbr);
hxxx = dr.ghxxx(indx,:);
gxxx = dr.ghxxx(indy,:);
hxxu = dr.ghxxu(indx,:);
gxxu = dr.ghxxu(indy,:);
hxuu = dr.ghxuu(indx,:);
gxuu = dr.ghxuu(indy,:);
huuu = dr.ghuuu(indx,:);
guuu = dr.ghuuu(indy,:);
hxss = dr.ghxss(indx,:);
gxss = dr.ghxss(indy,:);
huss = dr.ghuss(indx,:);
guss = dr.ghuss(indy,:);
if compute_derivs
dhxxx = dr.derivs.dghxxx(indx,:,:);
dgxxx = dr.derivs.dghxxx(indy,:,:);
dhxxu = dr.derivs.dghxxu(indx,:,:);
dgxxu = dr.derivs.dghxxu(indy,:,:);
dhxuu = dr.derivs.dghxuu(indx,:,:);
dgxuu = dr.derivs.dghxuu(indy,:,:);
dhuuu = dr.derivs.dghuuu(indx,:,:);
dguuu = dr.derivs.dghuuu(indy,:,:);
dhxss = dr.derivs.dghxss(indx,:,:);
dgxss = dr.derivs.dghxss(indy,:,:);
dhuss = dr.derivs.dghuss(indx,:,:);
dguss = dr.derivs.dghuss(indy,:,:);
end
end
%% First-order state space system
% Auxiliary state vector z is defined by: z = [xf]
% Auxiliary innovations vector inov is defined by: inov = [u]
z_nbr = x_nbr;
inov_nbr = M_.exo_nbr;
A = hx;
B = hu;
c = zeros(x_nbr,1);
C = gx;
D = gu;
d = zeros(y_nbr,1);
Varinov = E_uu;
E_inovzlag1 = zeros(inov_nbr,z_nbr); %at first-order E[inov*z(-1)'] = 0
Om_z = B*Varinov*B';
E_xf = zeros(x_nbr,1);
lyapunov_symm_method = 1; %method=1 to initialize persistent variables
[Var_z,Schur_u] = lyapunov_symm(A, Om_z,... %at first-order this algorithm is well established and also used in th_autocovariances.m
options_.lyapunov_fixed_point_tol, options_.qz_criterium, options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug); %we use Schur_u to take care of (possible) nonstationary VAROBS variables in moment computations
%find stationary vars
stationary_vars = (1:y_nbr)';
if ~isempty(Schur_u)
if order>1
error('pruned_state_space_system: the pruned state space currently does not support unit roots at higher order.')
end
%base this only on first order, because if first-order is stable so are the higher-order pruned systems
x = abs(gx*Schur_u);
stationary_vars = find(all(x < options_.schur_vec_tol,2));
end
if compute_derivs == 1
dA = dhx;
dB = dhu;
dc = zeros(x_nbr,totparam_nbr);
dC = dgx;
dD = dgu;
dd = zeros(y_nbr,totparam_nbr);
dVarinov = dE_uu;
dE_xf = zeros(x_nbr,totparam_nbr);
dE_inovzlag1 = zeros(z_nbr,inov_nbr,totparam_nbr);
dVar_z = zeros(z_nbr,z_nbr,totparam_nbr);
lyapunov_symm_method = 2;%to spare a lot of computing time while not repeating Schur every time
for jp1 = 1:totparam_nbr
if jp1 <= stderrparam_nbr+corrparam_nbr
dOm_z_jp1 = B*dVarinov(:,:,jp1)*B';
dVar_z(:,:,jp1) = lyapunov_symm(A, dOm_z_jp1,...
options_.lyapunov_fixed_point_tol,options_.qz_criterium,options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug);
else
dOm_z_jp1 = dB(:,:,jp1)*Varinov*B' + B*Varinov*dB(:,:,jp1)';
dVar_z(:,:,jp1) = lyapunov_symm(A, dA(:,:,jp1)*Var_z*A' + A*Var_z*dA(:,:,jp1)' + dOm_z_jp1,...
options_.lyapunov_fixed_point_tol,options_.qz_criterium,options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug);
end
end
end
if order > 1
options_.qz_criterium = 1; %pruned state space has no unit roots
% Some common and useful objects for order > 1
E_xfxf = Var_z;
if compute_derivs
dE_xfxf = dVar_z;
end
hx_hx = kron(hx,hx);
hx_hu = kron(hx,hu);
hu_hu = kron(hu,hu);
I_xx = eye(x_nbr^2);
K_x_x = pruned_SS.commutation(x_nbr,x_nbr,1);
invIx_hx = (eye(x_nbr)-hx)\eye(x_nbr);
%Compute unique fourth order product moments of u, i.e. unique(E[kron(kron(kron(u,u),u),u)],'stable')
u_nbr4 = u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4;
if isempty(QPu)
QPu = pruned_SS.quadruplication(u_nbr);
COMBOS4 = flipud(pruned_SS.allVL1(u_nbr, 4)); %all possible (unique) combinations of powers that sum up to four
end
E_u_u_u_u = zeros(u_nbr4,1); %only unique entries
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
dE_u_u_u_u = zeros(u_nbr4,stderrparam_nbr+corrparam_nbr);
end
for j4 = 1:size(COMBOS4,1)
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
[E_u_u_u_u(j4), dE_u_u_u_u(j4,:)] = pruned_SS.prodmom_deriv(E_uu, 1:u_nbr, COMBOS4(j4,:), dE_uu(:,:,1:(stderrparam_nbr+corrparam_nbr)), dr.derivs.dCorrelation_matrix(:,:,1:(stderrparam_nbr+corrparam_nbr)));
else
E_u_u_u_u(j4) = pruned_SS.prodmom(E_uu, 1:u_nbr, COMBOS4(j4,:));
end
end
E_xfxf_uu = kron(E_xfxf,E_uu');
%% Second-order pruned state space system
% Auxiliary state vector z is defined by: z = [xf;xs;kron(xf,xf)]
% Auxiliary innovations vector inov is defined by: inov = [u;kron(u,u)-E_uu(:);kron(xf,u)]
z_nbr = x_nbr + x_nbr + x_nbr^2;
inov_nbr = u_nbr + u_nbr^2 + x_nbr*u_nbr;
A = zeros(z_nbr, z_nbr);
A(id_z1_xf , id_z1_xf ) = hx;
A(id_z2_xs , id_z2_xs ) = hx;
A(id_z2_xs , id_z3_xf_xf) = 1/2*hxx;
A(id_z3_xf_xf , id_z3_xf_xf) = hx_hx;
B = zeros(z_nbr, inov_nbr);
B(id_z1_xf , id_inov1_u ) = hu;
B(id_z2_xs , id_inov2_u_u ) = 1/2*huu;
B(id_z2_xs , id_inov3_xf_u) = hxu;
B(id_z3_xf_xf , id_inov2_u_u ) = hu_hu;
B(id_z3_xf_xf , id_inov3_xf_u) = (I_xx+K_x_x)*hx_hu;
c = zeros(z_nbr, 1);
c(id_z2_xs , 1) = 1/2*hss + 1/2*huu*E_uu(:);
c(id_z3_xf_xf , 1) = hu_hu*E_uu(:);
C = zeros(y_nbr, z_nbr);
C(: , id_z1_xf ) = gx;
C(: , id_z2_xs ) = gx;
C(: , id_z3_xf_xf) = 1/2*gxx;
D = zeros(y_nbr, inov_nbr);
D(: , id_inov1_u ) = gu;
D(: , id_inov2_u_u ) = 1/2*guu;
D(: , id_inov3_xf_u) = gxu;
d = 1/2*gss + 1/2*guu*E_uu(:);
Varinov = zeros(inov_nbr,inov_nbr);
Varinov(id_inov1_u , id_inov1_u) = E_uu;
%Varinov(id_inov1_u , id_inov2_u_u ) = zeros(u_nbr,u_nbr^2);
%Varinov(id_inov1_u , id_inov3_xf_u) = zeros(u_nbr,x_nbr*u_nbr);
%Varinov(id_inov2_u_u , id_inov1_u ) = zeros(u_nbr^2,u_nbr);
Varinov(id_inov2_u_u , id_inov2_u_u ) = reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)-E_uu(:)*E_uu(:)';
%Varinov(id_inov2_u_u , id_inov3_xf_u) = zeros(u_nbr^2,x_nbr*u_nbr);
%Varinov(id_inov3_xf_u , id_inov1_u ) = zeros(x_nbr*u_nbr,u_nbr);
%Varinov(id_inov3_xf_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr,u_nbr^2);
Varinov(id_inov3_xf_u , id_inov3_xf_u) = E_xfxf_uu;
E_xs = invIx_hx*(1/2*hxx*E_xfxf(:) + c(id_z2_xs,1));
E_inovzlag1 = zeros(inov_nbr,z_nbr); %at second-order E[z(-1)*inov'] = 0
Om_z = B*Varinov*transpose(B);
lyapunov_symm_method = 1; %method=1 to initialize persistent variables (if errorflag)
[Var_z, errorflag] = disclyap_fast(A,Om_z,options_.lyapunov_doubling_tol);
if errorflag %use Schur-based method
fprintf('PRUNED_STATE_SPACE_SYSTEM: error flag in disclyap_fast at order=2, use lyapunov_symm\n');
Var_z = lyapunov_symm(A,Om_z,...
options_.lyapunov_fixed_point_tol,options_.qz_criterium,options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug);
lyapunov_symm_method = 2; %in the following we can reuse persistent variables
end
% Make sure some stuff is zero due to Gaussianity
Var_z(id_z1_xf , id_z2_xs ) = zeros(x_nbr,x_nbr);
Var_z(id_z1_xf , id_z3_xf_xf) = zeros(x_nbr,x_nbr^2);
Var_z(id_z2_xs , id_z1_xf ) = zeros(x_nbr,x_nbr);
Var_z(id_z3_xf_xf , id_z1_xf ) = zeros(x_nbr^2,x_nbr);
if compute_derivs
dA = zeros(z_nbr,z_nbr,totparam_nbr);
dB = zeros(z_nbr,inov_nbr,totparam_nbr);
dc = zeros(z_nbr,totparam_nbr);
dC = zeros(y_nbr,z_nbr,totparam_nbr);
dD = zeros(y_nbr,inov_nbr,totparam_nbr);
dd = zeros(y_nbr,totparam_nbr);
dVarinov = zeros(inov_nbr,inov_nbr,totparam_nbr);
dE_xs = zeros(x_nbr,totparam_nbr);
dE_inovzlag1 = zeros(inov_nbr,z_nbr,totparam_nbr);
dVar_z = zeros(z_nbr,z_nbr,totparam_nbr);
for jp2 = 1:totparam_nbr
if jp2 <= (stderrparam_nbr+corrparam_nbr)
dE_uu_jp2 = dE_uu(:,:,jp2);
dE_u_u_u_u_jp2 = QPu*dE_u_u_u_u(:,jp2);
else
dE_uu_jp2 = zeros(u_nbr,u_nbr);
dE_u_u_u_u_jp2 = zeros(u_nbr^4,1);
end
dhx_jp2 = dhx(:,:,jp2);
dhu_jp2 = dhu(:,:,jp2);
dhxx_jp2 = dhxx(:,:,jp2);
dhxu_jp2 = dhxu(:,:,jp2);
dhuu_jp2 = dhuu(:,:,jp2);
dhss_jp2 = dhss(:,jp2);
dgx_jp2 = dgx(:,:,jp2);
dgu_jp2 = dgu(:,:,jp2);
dgxx_jp2 = dgxx(:,:,jp2);
dgxu_jp2 = dgxu(:,:,jp2);
dguu_jp2 = dguu(:,:,jp2);
dgss_jp2 = dgss(:,jp2);
dhx_hx_jp2 = kron(dhx_jp2,hx) + kron(hx,dhx_jp2);
dhu_hu_jp2 = kron(dhu_jp2,hu) + kron(hu,dhu_jp2);
dhx_hu_jp2 = kron(dhx_jp2,hu) + kron(hx,dhu_jp2);
dE_xfxf_jp2 = dE_xfxf(:,:,jp2);
dE_xfxf_uu_jp2 = kron(dE_xfxf_jp2,E_uu) + kron(E_xfxf,dE_uu_jp2);
dA(id_z1_xf , id_z1_xf , jp2) = dhx_jp2;
dA(id_z2_xs , id_z2_xs , jp2) = dhx_jp2;
dA(id_z2_xs , id_z3_xf_xf , jp2) = 1/2*dhxx_jp2;
dA(id_z3_xf_xf , id_z3_xf_xf , jp2) = dhx_hx_jp2;
dB(id_z1_xf , id_inov1_u , jp2) = dhu_jp2;
dB(id_z2_xs , id_inov2_u_u , jp2) = 1/2*dhuu_jp2;
dB(id_z2_xs , id_inov3_xf_u , jp2) = dhxu_jp2;
dB(id_z3_xf_xf , id_inov2_u_u , jp2) = dhu_hu_jp2;
dB(id_z3_xf_xf , id_inov3_xf_u , jp2) = (I_xx+K_x_x)*dhx_hu_jp2;
dc(id_z2_xs , jp2) = 1/2*dhss_jp2 + 1/2*dhuu_jp2*E_uu(:) + 1/2*huu*dE_uu_jp2(:);
dc(id_z3_xf_xf , jp2) = dhu_hu_jp2*E_uu(:) + hu_hu*dE_uu_jp2(:);
dC(: , id_z1_xf , jp2) = dgx_jp2;
dC(: , id_z2_xs , jp2) = dgx_jp2;
dC(: , id_z3_xf_xf , jp2) = 1/2*dgxx_jp2;
dD(: , id_inov1_u , jp2) = dgu_jp2;
dD(: , id_inov2_u_u , jp2) = 1/2*dguu_jp2;
dD(: , id_inov3_xf_u , jp2) = dgxu_jp2;
dd(:,jp2) = 1/2*dgss_jp2 + 1/2*guu*dE_uu_jp2(:) + 1/2*dguu_jp2*E_uu(:);
dVarinov(id_inov1_u , id_inov1_u , jp2) = dE_uu_jp2;
dVarinov(id_inov2_u_u , id_inov2_u_u , jp2) = reshape(dE_u_u_u_u_jp2,u_nbr^2,u_nbr^2) - dE_uu_jp2(:)*E_uu(:)' - E_uu(:)*dE_uu_jp2(:)';
dVarinov(id_inov3_xf_u , id_inov3_xf_u , jp2) = dE_xfxf_uu_jp2;
dE_xs(:,jp2) = invIx_hx*( dhx_jp2*E_xs + 1/2*dhxx_jp2*E_xfxf(:) + 1/2*hxx*dE_xfxf_jp2(:) + dc(id_z2_xs,jp2) );
dOm_z_jp2 = dB(:,:,jp2)*Varinov*B' + B*dVarinov(:,:,jp2)*B' + B*Varinov*dB(:,:,jp2)';
[dVar_z(:,:,jp2), errorflag] = disclyap_fast(A, dA(:,:,jp2)*Var_z*A' + A*Var_z*dA(:,:,jp2)' + dOm_z_jp2, options_.lyapunov_doubling_tol);
if errorflag
dVar_z(:,:,jp2) = lyapunov_symm(A, dA(:,:,jp2)*Var_z*A' + A*Var_z*dA(:,:,jp2)' + dOm_z_jp2,...
options_.lyapunov_fixed_point_tol,options_.qz_criterium,options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug);
if lyapunov_symm_method == 1
lyapunov_symm_method = 2; %now we can reuse persistent schur
end
end
% Make sure some stuff is zero due to Gaussianity
dVar_z(id_z1_xf , id_z2_xs , jp2) = zeros(x_nbr,x_nbr);
dVar_z(id_z1_xf , id_z3_xf_xf , jp2) = zeros(x_nbr,x_nbr^2);
dVar_z(id_z2_xs , id_z1_xf , jp2) = zeros(x_nbr,x_nbr);
dVar_z(id_z3_xf_xf , id_z1_xf , jp2) = zeros(x_nbr^2,x_nbr);
end
end
if order > 2
% Some common and useful objects for order > 2
if isempty(K_u_xx)
K_u_xx = pruned_SS.commutation(u_nbr,x_nbr^2,1);
K_u_ux = pruned_SS.commutation(u_nbr,u_nbr*x_nbr,1);
K_xx_x = pruned_SS.commutation(x_nbr^2,x_nbr);
end
hx_hss2 = kron(hx,1/2*hss);
hu_hss2 = kron(hu,1/2*hss);
hx_hxx2 = kron(hx,1/2*hxx);
hxx2_hu = kron(1/2*hxx,hu);
hx_hxu = kron(hx,hxu);
hxu_hu = kron(hxu,hu);
hx_huu2 = kron(hx,1/2*huu);
hu_huu2 = kron(hu,1/2*huu);
hx_hx_hx = kron(hx,hx_hx);
hx_hx_hu = kron(hx_hx,hu);
hu_hx_hx = kron(hu,hx_hx);
hu_hu_hu = kron(hu_hu,hu);
hx_hu_hu = kron(hx,hu_hu);
hu_hx_hu = kron(hu,hx_hu);
invIxx_hx_hx = (eye(x_nbr^2)-hx_hx)\eye(x_nbr^2);
% Reuse second-order results
%E_xfxf = Var_z(id_z1_xf, id_z1_xf ); %this is E[xf*xf'], we already have that
%E_xfxs = Var_z(id_z1_xf, id_z2_xs ); %this is E[xf*xs']=0 due to gaussianity
%E_xfxf_xf = Var_z(id_z1_xf, id_z3_xf_xf ); %this is E[xf*kron(xf_xf)']=0 due to gaussianity
%E_xsxf = Var_z(id_z2_xs, id_z1_xf ); %this is E[xs*xf']=0 due to gaussianity
E_xsxs = Var_z(id_z2_xs, id_z2_xs ) + E_xs*transpose(E_xs); %this is E[xs*xs']
E_xsxf_xf = Var_z(id_z2_xs, id_z3_xf_xf ) + E_xs*E_xfxf(:)'; %this is E[xs*kron(xf,xf)']
%E_xf_xfxf = Var_z(id_z3_xf_xf, id_z1_xf ); %this is E[kron(xf,xf)*xf']=0 due to gaussianity
E_xf_xfxs = Var_z(id_z3_xf_xf, id_z2_xs ) + E_xfxf(:)*E_xs'; %this is E[kron(xf,xf)*xs']
E_xf_xfxf_xf = Var_z(id_z3_xf_xf, id_z3_xf_xf) + E_xfxf(:)*E_xfxf(:)'; %this is E[kron(xf,xf)*kron(xf,xf)']
E_xrdxf = reshape(invIxx_hx_hx*vec(...
hxx*reshape( pruned_SS.commutation(x_nbr^2,x_nbr,1)*E_xf_xfxs(:), x_nbr^2,x_nbr)*hx'...
+ hxu*kron(E_xs,E_uu)*hu'...
+ 1/6*hxxx*reshape(E_xf_xfxf_xf,x_nbr^3,x_nbr)*hx'...
+ 1/6*huuu*reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)*hu'...
+ 3/6*hxxu*kron(E_xfxf(:),E_uu)*hu'...
+ 3/6*hxuu*kron(E_xfxf,E_uu(:))*hx'...
+ 3/6*hxss*E_xfxf*hx'...
+ 3/6*huss*E_uu*hu'...
),...
x_nbr,x_nbr); %this is E[xrd*xf']
if compute_derivs
dE_xsxs = zeros(x_nbr,x_nbr,totparam_nbr);
dE_xsxf_xf = zeros(x_nbr,x_nbr^2,totparam_nbr);
dE_xf_xfxs = zeros(x_nbr^2,x_nbr,totparam_nbr);
dE_xf_xfxf_xf = zeros(x_nbr^2,x_nbr^2,totparam_nbr);
dE_xrdxf = zeros(x_nbr,x_nbr,totparam_nbr);
for jp2 = 1:totparam_nbr
if jp2 < (stderrparam_nbr+corrparam_nbr)
dE_u_u_u_u_jp2 = QPu*dE_u_u_u_u(:,jp2);
else
dE_u_u_u_u_jp2 = zeros(u_nbr^4,1);
end
dE_xsxs(:,:,jp2) = dVar_z(id_z2_xs , id_z2_xs , jp2) + dE_xs(:,jp2)*transpose(E_xs) + E_xs*transpose(dE_xs(:,jp2));
dE_xsxf_xf(:,:,jp2) = dVar_z(id_z2_xs , id_z3_xf_xf , jp2) + dE_xs(:,jp2)*E_xfxf(:)' + E_xs*vec(dE_xfxf(:,:,jp2))';
dE_xf_xfxs(:,:,jp2) = dVar_z(id_z3_xf_xf , id_z2_xs , jp2) + vec(dE_xfxf(:,:,jp2))*E_xs' + E_xfxf(:)*dE_xs(:,jp2)';
dE_xf_xfxf_xf(:,:,jp2) = dVar_z(id_z3_xf_xf , id_z3_xf_xf , jp2) + vec(dE_xfxf(:,:,jp2))*E_xfxf(:)' + E_xfxf(:)*vec(dE_xfxf(:,:,jp2))';
dE_xrdxf(:,:,jp2) = reshape(invIxx_hx_hx*vec(...
dhx(:,:,jp2)*E_xrdxf*hx' + hx*E_xrdxf*dhx(:,:,jp2)'...
+ dhxx(:,:,jp2)*reshape( pruned_SS.commutation(x_nbr^2,x_nbr,1)*E_xf_xfxs(:), x_nbr^2,x_nbr)*hx' + hxx*reshape( pruned_SS.commutation(x_nbr^2,x_nbr,1)*vec(dE_xf_xfxs(:,:,jp2)), x_nbr^2,x_nbr)*hx' + hxx*reshape( pruned_SS.commutation(x_nbr^2,x_nbr,1)*E_xf_xfxs(:), x_nbr^2,x_nbr)*dhx(:,:,jp2)'...
+ dhxu(:,:,jp2)*kron(E_xs,E_uu)*hu' + hxu*kron(dE_xs(:,jp2),E_uu)*hu' + hxu*kron(E_xs,dE_uu(:,:,jp2))*hu' + hxu*kron(E_xs,E_uu)*dhu(:,:,jp2)'...
+ 1/6*dhxxx(:,:,jp2)*reshape(E_xf_xfxf_xf,x_nbr^3,x_nbr)*hx' + 1/6*hxxx*reshape(dE_xf_xfxf_xf(:,:,jp2),x_nbr^3,x_nbr)*hx' + 1/6*hxxx*reshape(E_xf_xfxf_xf,x_nbr^3,x_nbr)*dhx(:,:,jp2)'...
+ 1/6*dhuuu(:,:,jp2)*reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)*hu' + 1/6*huuu*reshape(dE_u_u_u_u_jp2,u_nbr^3,u_nbr)*hu' + 1/6*huuu*reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)*dhu(:,:,jp2)'...
+ 3/6*dhxxu(:,:,jp2)*kron(E_xfxf(:),E_uu)*hu' + 3/6*hxxu*kron(vec(dE_xfxf(:,:,jp2)),E_uu)*hu' + 3/6*hxxu*kron(E_xfxf(:),dE_uu(:,:,jp2))*hu' + 3/6*hxxu*kron(E_xfxf(:),E_uu)*dhu(:,:,jp2)'...
+ 3/6*dhxuu(:,:,jp2)*kron(E_xfxf,E_uu(:))*hx' + 3/6*hxuu*kron(dE_xfxf(:,:,jp2),E_uu(:))*hx' + 3/6*hxuu*kron(E_xfxf,vec(dE_uu(:,:,jp2)))*hx' + 3/6*hxuu*kron(E_xfxf,E_uu(:))*dhx(:,:,jp2)'...
+ 3/6*dhxss(:,:,jp2)*E_xfxf*hx' + 3/6*hxss*dE_xfxf(:,:,jp2)*hx' + 3/6*hxss*E_xfxf*dhx(:,:,jp2)'...
+ 3/6*dhuss(:,:,jp2)*E_uu*hu' + 3/6*huss*dE_uu(:,:,jp2)*hu' + 3/6*huss*E_uu*dhu(:,:,jp2)'...
), x_nbr, x_nbr);
end
end
% Compute unique sixth-order product moments of u, i.e. unique(E[kron(kron(kron(kron(kron(u,u),u),u),u),u)],'stable')
u_nbr6 = u_nbr*(u_nbr+1)/2*(u_nbr+2)/3*(u_nbr+3)/4*(u_nbr+4)/5*(u_nbr+5)/6;
if isempty(Q6Pu)
Q6Pu = pruned_SS.Q6_plication(u_nbr);
COMBOS6 = flipud(pruned_SS.allVL1(u_nbr, 6)); %all possible (unique) combinations of powers that sum up to six
end
E_u_u_u_u_u_u = zeros(u_nbr6,1); %only unique entries
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
dE_u_u_u_u_u_u = zeros(u_nbr6,stderrparam_nbr+corrparam_nbr);
end
for j6 = 1:size(COMBOS6,1)
if compute_derivs && (stderrparam_nbr+corrparam_nbr>0)
[E_u_u_u_u_u_u(j6), dE_u_u_u_u_u_u(j6,:)] = pruned_SS.prodmom_deriv(E_uu, 1:u_nbr, COMBOS6(j6,:), dE_uu(:,:,1:(stderrparam_nbr+corrparam_nbr)), dr.derivs.dCorrelation_matrix(:,:,1:(stderrparam_nbr+corrparam_nbr)));
else
E_u_u_u_u_u_u(j6) = pruned_SS.prodmom(E_uu, 1:u_nbr, COMBOS6(j6,:));
end
end
%% Third-order pruned state space system
% Auxiliary state vector z is defined by: z = [xf; xs; kron(xf,xf); xrd; kron(xf,xs); kron(kron(xf,xf),xf)]
% Auxiliary innovations vector inov is defined by: inov = [u; kron(u,u)-E_uu(:); kron(xf,u); kron(xs,u); kron(kron(xf,xf),u); kron(kron(xf,u),u); kron(kron(u,u),u))]
z_nbr = x_nbr + x_nbr + x_nbr^2 + x_nbr + x_nbr^2 + x_nbr^3;
inov_nbr = u_nbr + u_nbr^2 + x_nbr*u_nbr + x_nbr*u_nbr + x_nbr^2*u_nbr + x_nbr*u_nbr^2 + u_nbr^3;
A = zeros(z_nbr,z_nbr);
A(id_z1_xf , id_z1_xf ) = hx;
A(id_z2_xs , id_z2_xs ) = hx;
A(id_z2_xs , id_z3_xf_xf ) = 1/2*hxx;
A(id_z3_xf_xf , id_z3_xf_xf ) = hx_hx;
A(id_z4_xrd , id_z1_xf ) = 3/6*hxss;
A(id_z4_xrd , id_z4_xrd ) = hx;
A(id_z4_xrd , id_z5_xf_xs ) = hxx;
A(id_z4_xrd , id_z6_xf_xf_xf) = 1/6*hxxx;
A(id_z5_xf_xs , id_z1_xf ) = hx_hss2;
A(id_z5_xf_xs , id_z5_xf_xs ) = hx_hx;
A(id_z5_xf_xs , id_z6_xf_xf_xf) = hx_hxx2;
A(id_z6_xf_xf_xf , id_z6_xf_xf_xf) = hx_hx_hx;
B = zeros(z_nbr,inov_nbr);
B(id_z1_xf , id_inov1_u ) = hu;
B(id_z2_xs , id_inov2_u_u ) = 1/2*huu;
B(id_z2_xs , id_inov3_xf_u ) = hxu;
B(id_z3_xf_xf , id_inov2_u_u ) = hu_hu;
B(id_z3_xf_xf , id_inov3_xf_u ) = (I_xx+K_x_x)*hx_hu;
B(id_z4_xrd , id_inov1_u ) = 3/6*huss;
B(id_z4_xrd , id_inov4_xs_u ) = hxu;
B(id_z4_xrd , id_inov5_xf_xf_u) = 3/6*hxxu;
B(id_z4_xrd , id_inov6_xf_u_u ) = 3/6*hxuu;
B(id_z4_xrd , id_inov7_u_u_u ) = 1/6*huuu;
B(id_z5_xf_xs , id_inov1_u ) = hu_hss2;
B(id_z5_xf_xs , id_inov4_xs_u ) = K_x_x*hx_hu;
B(id_z5_xf_xs , id_inov5_xf_xf_u) = hx_hxu + K_x_x*hxx2_hu;
B(id_z5_xf_xs , id_inov6_xf_u_u ) = hx_huu2 + K_x_x*hxu_hu;
B(id_z5_xf_xs , id_inov7_u_u_u ) = hu_huu2;
B(id_z6_xf_xf_xf , id_inov5_xf_xf_u) = hx_hx_hu + kron(hx,K_x_x*hx_hu) + hu_hx_hx*K_u_xx;
B(id_z6_xf_xf_xf , id_inov6_xf_u_u ) = hx_hu_hu + hu_hx_hu*K_u_ux + kron(hu,K_x_x*hx_hu)*K_u_ux;
B(id_z6_xf_xf_xf , id_inov7_u_u_u ) = hu_hu_hu;
c = zeros(z_nbr, 1);
c(id_z2_xs , 1) = 1/2*hss + 1/2*huu*E_uu(:);
c(id_z3_xf_xf , 1) = hu_hu*E_uu(:);
C = zeros(y_nbr,z_nbr);
C(: , id_z1_xf ) = gx + 3/6*gxss;
C(: , id_z2_xs ) = gx;
C(: , id_z3_xf_xf ) = 1/2*gxx;
C(: , id_z4_xrd ) = gx;
C(: , id_z5_xf_xs ) = gxx;
C(: , id_z6_xf_xf_xf) = 1/6*gxxx;
D = zeros(y_nbr,inov_nbr);
D(: , id_inov1_u ) = gu + 3/6*guss;
D(: , id_inov2_u_u ) = 1/2*guu;
D(: , id_inov3_xf_u ) = gxu;
D(: , id_inov4_xs_u ) = gxu;
D(: , id_inov5_xf_xf_u) = 3/6*gxxu;
D(: , id_inov6_xf_u_u) = 3/6*gxuu;
D(: , id_inov7_u_u_u ) = 1/6*guuu;
d = 1/2*gss + 1/2*guu*E_uu(:);
Varinov = zeros(inov_nbr,inov_nbr);
Varinov(id_inov1_u , id_inov1_u ) = E_uu;
%Varinov(id_inov1_u , id_inov2_u_u ) = zeros(u_nbr,u_nbr^2);
%Varinov(id_inov1_u , id_inov3_xf_u ) = zeros(u_nbr,x_nbr*u_nbr);
Varinov(id_inov1_u , id_inov4_xs_u ) = kron(E_xs',E_uu);
Varinov(id_inov1_u , id_inov5_xf_xf_u) = kron(E_xfxf(:)',E_uu);
%Varinov(id_inov1_u , id_inov6_xf_u_u ) = zeros(u_nbr,x_nbr*u_nbr^2);
Varinov(id_inov1_u , id_inov7_u_u_u ) = reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3);
%Varinov(id_inov2_u_u , id_inov1_u ) = zeros(u_nbr^2,u_nbr);
Varinov(id_inov2_u_u , id_inov2_u_u ) = reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)-E_uu(:)*E_uu(:)';
%Varinov(id_inov2_u_u , id_inov3_xf_u ) = zeros(u_nbr^2,x_nbr*u_nbr);
%Varinov(id_inov2_u_u , id_inov4_xs_u ) = zeros(u_nbr^2,x_nbr*u_nbr);
%Varinov(id_inov2_u_u , id_inov5_xf_xf_u) = zeros(u_nbr^2,x_nbr^2,u_nbr);
%Varinov(id_inov2_u_u , id_inov6_xf_u_u ) = zeros(u_nbr^2,x_nbr*u_nbr^2);
%Varinov(id_inov2_u_u , id_inov7_u_u_u ) = zeros(u_nbr^2,u_nbr^3);
%Varinov(id_inov3_xf_u , id_inov1_u ) = zeros(x_nbr*u_nbr,u_nbr);
%Varinov(id_inov3_xf_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr,u_nbr^2);
Varinov(id_inov3_xf_u , id_inov3_xf_u ) = E_xfxf_uu;
%Varinov(id_inov3_xf_u , id_inov4_xs_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr);
%Varinov(id_inov3_xf_u , id_inov5_xf_xf_u) = zeros(x_nbr*u_nbr,x_nbr^2*u_nbr);
%Varinov(id_inov3_xf_u , id_inov6_xf_u_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr^2);
%Varinov(id_inov3_xf_u , id_inov7_u_u_u ) = zeros(x_nbr*u_nbr,u_nbr^3);
Varinov(id_inov4_xs_u , id_inov1_u ) = kron(E_xs,E_uu);
%Varinov(id_inov4_xs_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr,u_nbr^2);
%Varinov(id_inov4_xs_u , id_inov3_xf_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr);
Varinov(id_inov4_xs_u , id_inov4_xs_u ) = kron(E_xsxs,E_uu);
Varinov(id_inov4_xs_u , id_inov5_xf_xf_u) = kron(E_xsxf_xf, E_uu);
%Varinov(id_inov4_xs_u , id_inov6_xf_u_u ) = zeros(x_nbr*u_nbr,x_nbr*u_nbr^2);
Varinov(id_inov4_xs_u , id_inov7_u_u_u ) = kron(E_xs,reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3));
Varinov(id_inov5_xf_xf_u , id_inov1_u ) = kron(E_xfxf(:),E_uu);
%Varinov(id_inov5_xf_xf_u , id_inov2_u_u ) = zeros(x_nbr^2*u_nbr,u_nbr^2);
%Varinov(id_inov5_xf_xf_u , id_inov3_xf_u ) = zeros(x_nbr^2*u_nbr,x_nbr*u_nbr);
Varinov(id_inov5_xf_xf_u , id_inov4_xs_u ) = kron(E_xf_xfxs,E_uu);
Varinov(id_inov5_xf_xf_u , id_inov5_xf_xf_u) = kron(E_xf_xfxf_xf,E_uu);
%Varinov(id_inov5_xf_xf_u , id_inov6_xf_u_u ) = zeros(x_nbr^2*u_nbr,x_nbr*u_nbr^2);
Varinov(id_inov5_xf_xf_u , id_inov7_u_u_u ) = kron(E_xfxf(:),reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3));
%Varinov(id_inov6_xf_u_u , id_inov1_u ) = zeros(x_nbr*u_nbr^2,u_nbr);
%Varinov(id_inov6_xf_u_u , id_inov2_u_u ) = zeros(x_nbr*u_nbr^2,u_nbr^2);
%Varinov(id_inov6_xf_u_u , id_inov3_xf_u ) = zeros(x_nbr*u_nbr^2,x_nbr*u_nbr);
%Varinov(id_inov6_xf_u_u , id_inov4_xs_u ) = zeros(x_nbr*u_nbr^2,x_nbr*u_nbr);
%Varinov(id_inov6_xf_u_u , id_inov5_xf_xf_u) = zeros(x_nbr*u_nbr^2,x_nbr^2*u_nbr);
Varinov(id_inov6_xf_u_u , id_inov6_xf_u_u ) = kron(E_xfxf,reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2));
%Varinov(id_inov6_xf_u_u , id_inov7_u_u_u ) = zeros(x_nbr*u_nbr^2,u_nbr^3);
Varinov(id_inov7_u_u_u , id_inov1_u ) = reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr);
%Varinov(id_inov7_u_u_u , id_inov2_u_u ) = zeros(u_nbr^3,u_nbr^2);
%Varinov(id_inov7_u_u_u , id_inov3_xf_u ) = zeros(u_nbr^3,x_nbr*u_nbr);
Varinov(id_inov7_u_u_u , id_inov4_xs_u ) = kron(E_xs',reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr));
Varinov(id_inov7_u_u_u , id_inov5_xf_xf_u) = kron(transpose(E_xfxf(:)),reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr));
%Varinov(id_inov7_u_u_u , id_inov6_xf_u_u ) = zeros(u_nbr^3,x_nbr*u_nbr^2);
Varinov(id_inov7_u_u_u , id_inov7_u_u_u ) = reshape(Q6Pu*E_u_u_u_u_u_u,u_nbr^3,u_nbr^3);
E_xrd = zeros(x_nbr,1);%due to gaussianity
E_inovzlag1 = zeros(inov_nbr,z_nbr); % Attention: E[inov*z(-1)'] is not equal to zero for a third-order approximation due to kron(kron(xf(-1),u),u)
E_inovzlag1(id_inov6_xf_u_u , id_z1_xf ) = kron(E_xfxf,E_uu(:));
E_inovzlag1(id_inov6_xf_u_u , id_z4_xrd ) = kron(E_xrdxf',E_uu(:));
E_inovzlag1(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(reshape(K_xx_x*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu)) ;
E_inovzlag1(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:));
Binovzlag1A= B*E_inovzlag1*transpose(A);
Om_z = B*Varinov*transpose(B) + Binovzlag1A + transpose(Binovzlag1A);
lyapunov_symm_method = 1; %method=1 to initialize persistent variables
[Var_z, errorflag] = disclyap_fast(A,Om_z,options_.lyapunov_doubling_tol);
if errorflag %use Schur-based method
fprintf('PRUNED_STATE_SPACE_SYSTEM: error flag in disclyap_fast at order=3, use lyapunov_symm\n');
Var_z = lyapunov_symm(A,Om_z,...
options_.lyapunov_fixed_point_tol,options_.qz_criterium,options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug);
lyapunov_symm_method = 2; %we can now make use of persistent variables from shur
end
%make sure some stuff is zero due to Gaussianity
Var_z(id_z1_xf , id_z2_xs) = zeros(x_nbr,x_nbr);
Var_z(id_z1_xf , id_z3_xf_xf) = zeros(x_nbr,x_nbr^2);
Var_z(id_z2_xs , id_z1_xf) = zeros(x_nbr,x_nbr);
Var_z(id_z2_xs , id_z4_xrd) = zeros(x_nbr,x_nbr);
Var_z(id_z2_xs , id_z5_xf_xs) = zeros(x_nbr,x_nbr^2);
Var_z(id_z2_xs , id_z6_xf_xf_xf) = zeros(x_nbr,x_nbr^3);
Var_z(id_z3_xf_xf , id_z1_xf) = zeros(x_nbr^2,x_nbr);
Var_z(id_z3_xf_xf , id_z4_xrd) = zeros(x_nbr^2,x_nbr);
Var_z(id_z3_xf_xf , id_z5_xf_xs) = zeros(x_nbr^2,x_nbr^2);
Var_z(id_z3_xf_xf , id_z6_xf_xf_xf) = zeros(x_nbr^2,x_nbr^3);
Var_z(id_z4_xrd , id_z2_xs) = zeros(x_nbr,x_nbr);
Var_z(id_z4_xrd , id_z3_xf_xf) = zeros(x_nbr,x_nbr^2);
Var_z(id_z5_xf_xs , id_z2_xs) = zeros(x_nbr^2,x_nbr);
Var_z(id_z5_xf_xs , id_z3_xf_xf) = zeros(x_nbr^2,x_nbr^2);
Var_z(id_z6_xf_xf_xf , id_z2_xs) = zeros(x_nbr^3,x_nbr);
Var_z(id_z6_xf_xf_xf , id_z3_xf_xf) = zeros(x_nbr^3,x_nbr^2);
if compute_derivs
dA = zeros(z_nbr,z_nbr,totparam_nbr);
dB = zeros(z_nbr,inov_nbr,totparam_nbr);
dc = zeros(z_nbr,totparam_nbr);
dC = zeros(y_nbr,z_nbr,totparam_nbr);
dD = zeros(y_nbr,inov_nbr,totparam_nbr);
dd = zeros(y_nbr,totparam_nbr);
dVarinov = zeros(inov_nbr,inov_nbr,totparam_nbr);
dE_xrd = zeros(x_nbr,totparam_nbr);
dE_inovzlag1 = zeros(inov_nbr,z_nbr,totparam_nbr);
dVar_z = zeros(z_nbr,z_nbr,totparam_nbr);
for jp3 = 1:totparam_nbr
if jp3 <= (stderrparam_nbr+corrparam_nbr)
dE_uu_jp3 = dE_uu(:,:,jp3);
dE_u_u_u_u_jp3 = QPu*dE_u_u_u_u(:,jp3);
dE_u_u_u_u_u_u_jp3 = Q6Pu*dE_u_u_u_u_u_u(:,jp3);
else
dE_uu_jp3 = zeros(u_nbr,u_nbr);
dE_u_u_u_u_jp3 = zeros(u_nbr^4,1);
dE_u_u_u_u_u_u_jp3 = zeros(u_nbr^6,1);
end
dhx_jp3 = dhx(:,:,jp3);
dhu_jp3 = dhu(:,:,jp3);
dhxx_jp3 = dhxx(:,:,jp3);
dhxu_jp3 = dhxu(:,:,jp3);
dhuu_jp3 = dhuu(:,:,jp3);
dhss_jp3 = dhss(:,jp3);
dhxxx_jp3 = dhxxx(:,:,jp3);
dhxxu_jp3 = dhxxu(:,:,jp3);
dhxuu_jp3 = dhxuu(:,:,jp3);
dhuuu_jp3 = dhuuu(:,:,jp3);
dhxss_jp3 = dhxss(:,:,jp3);
dhuss_jp3 = dhuss(:,:,jp3);
dgx_jp3 = dgx(:,:,jp3);
dgu_jp3 = dgu(:,:,jp3);
dgxx_jp3 = dgxx(:,:,jp3);
dgxu_jp3 = dgxu(:,:,jp3);
dguu_jp3 = dguu(:,:,jp3);
dgss_jp3 = dgss(:,jp3);
dgxxx_jp3 = dgxxx(:,:,jp3);
dgxxu_jp3 = dgxxu(:,:,jp3);
dgxuu_jp3 = dgxuu(:,:,jp3);
dguuu_jp3 = dguuu(:,:,jp3);
dgxss_jp3 = dgxss(:,:,jp3);
dguss_jp3 = dguss(:,:,jp3);
dhx_hx_jp3 = kron(dhx_jp3,hx) + kron(hx,dhx_jp3);
dhx_hu_jp3 = kron(dhx_jp3,hu) + kron(hx,dhu_jp3);
dhu_hu_jp3 = kron(dhu_jp3,hu) + kron(hu,dhu_jp3);
dhx_hss2_jp3 = kron(dhx_jp3,1/2*hss) + kron(hx,1/2*dhss_jp3);
dhu_hss2_jp3 = kron(dhu_jp3,1/2*hss) + kron(hu,1/2*dhss_jp3);
dhx_hxx2_jp3 = kron(dhx_jp3,1/2*hxx) + kron(hx,1/2*dhxx_jp3);
dhxx2_hu_jp3 = kron(1/2*dhxx_jp3,hu) + kron(1/2*hxx,dhu_jp3);
dhx_hxu_jp3 = kron(dhx_jp3,hxu) + kron(hx,dhxu_jp3);
dhxu_hu_jp3 = kron(dhxu_jp3,hu) + kron(hxu,dhu_jp3);
dhx_huu2_jp3 = kron(dhx_jp3,1/2*huu) + kron(hx,1/2*dhuu_jp3);
dhu_huu2_jp3 = kron(dhu_jp3,1/2*huu) + kron(hu,1/2*dhuu_jp3);
dhx_hx_hx_jp3 = kron(dhx_jp3,hx_hx) + kron(hx,dhx_hx_jp3);
dhx_hx_hu_jp3 = kron(dhx_hx_jp3,hu) + kron(hx_hx,dhu_jp3);
dhu_hx_hx_jp3 = kron(dhu_jp3,hx_hx) + kron(hu,dhx_hx_jp3);
dhu_hu_hu_jp3 = kron(dhu_hu_jp3,hu) + kron(hu_hu,dhu_jp3);
dhx_hu_hu_jp3 = kron(dhx_jp3,hu_hu) + kron(hx,dhu_hu_jp3);
dhu_hx_hu_jp3 = kron(dhu_jp3,hx_hu) + kron(hu,dhx_hu_jp3);
dE_xs_jp3 = dE_xs(:,jp3);
dE_xfxf_jp3 = dE_xfxf(:,:,jp3);
dE_xsxs_jp3 = dE_xsxs(:,:,jp3);
dE_xsxf_xf_jp3 = dE_xsxf_xf(:,:,jp3);
dE_xfxf_uu_jp3 = kron(dE_xfxf_jp3,E_uu) + kron(E_xfxf,dE_uu_jp3);
dE_xf_xfxs_jp3 = dE_xf_xfxs(:,:,jp3);
dE_xf_xfxf_xf_jp3 = dE_xf_xfxf_xf(:,:,jp3);
dE_xrdxf_jp3 = dE_xrdxf(:,:,jp3);
dA(id_z1_xf , id_z1_xf , jp3) = dhx_jp3;
dA(id_z2_xs , id_z2_xs , jp3) = dhx_jp3;
dA(id_z2_xs , id_z3_xf_xf , jp3) = 1/2*dhxx_jp3;
dA(id_z3_xf_xf , id_z3_xf_xf , jp3) = dhx_hx_jp3;
dA(id_z4_xrd , id_z1_xf , jp3) = 3/6*dhxss_jp3;
dA(id_z4_xrd , id_z4_xrd , jp3) = dhx_jp3;
dA(id_z4_xrd , id_z5_xf_xs , jp3) = dhxx_jp3;
dA(id_z4_xrd , id_z6_xf_xf_xf , jp3) = 1/6*dhxxx_jp3;
dA(id_z5_xf_xs , id_z1_xf , jp3) = dhx_hss2_jp3;
dA(id_z5_xf_xs , id_z5_xf_xs , jp3) = dhx_hx_jp3;
dA(id_z5_xf_xs , id_z6_xf_xf_xf , jp3) = dhx_hxx2_jp3;
dA(id_z6_xf_xf_xf , id_z6_xf_xf_xf , jp3) = dhx_hx_hx_jp3;
dB(id_z1_xf , id_inov1_u , jp3) = dhu_jp3;
dB(id_z2_xs , id_inov2_u_u , jp3) = 1/2*dhuu_jp3;
dB(id_z2_xs , id_inov3_xf_u , jp3) = dhxu_jp3;
dB(id_z3_xf_xf , id_inov2_u_u , jp3) = dhu_hu_jp3;
dB(id_z3_xf_xf , id_inov3_xf_u , jp3) = (I_xx+K_x_x)*dhx_hu_jp3;
dB(id_z4_xrd , id_inov1_u , jp3) = 3/6*dhuss_jp3;
dB(id_z4_xrd , id_inov4_xs_u , jp3) = dhxu_jp3;
dB(id_z4_xrd , id_inov5_xf_xf_u , jp3) = 3/6*dhxxu_jp3;
dB(id_z4_xrd , id_inov6_xf_u_u , jp3) = 3/6*dhxuu_jp3;
dB(id_z4_xrd , id_inov7_u_u_u , jp3) = 1/6*dhuuu_jp3;
dB(id_z5_xf_xs , id_inov1_u , jp3) = dhu_hss2_jp3;
dB(id_z5_xf_xs , id_inov4_xs_u , jp3) = K_x_x*dhx_hu_jp3;
dB(id_z5_xf_xs , id_inov5_xf_xf_u , jp3) = dhx_hxu_jp3 + K_x_x*dhxx2_hu_jp3;
dB(id_z5_xf_xs , id_inov6_xf_u_u , jp3) = dhx_huu2_jp3 + K_x_x*dhxu_hu_jp3;
dB(id_z5_xf_xs , id_inov7_u_u_u , jp3) = dhu_huu2_jp3;
dB(id_z6_xf_xf_xf , id_inov5_xf_xf_u , jp3) = dhx_hx_hu_jp3 + kron(dhx_jp3,K_x_x*hx_hu) + kron(hx,K_x_x*dhx_hu_jp3) + dhu_hx_hx_jp3*K_u_xx;
dB(id_z6_xf_xf_xf , id_inov6_xf_u_u , jp3) = dhx_hu_hu_jp3 + dhu_hx_hu_jp3*K_u_ux + kron(dhu_jp3,K_x_x*hx_hu)*K_u_ux + kron(hu,K_x_x*dhx_hu_jp3)*K_u_ux;
dB(id_z6_xf_xf_xf , id_inov7_u_u_u , jp3) = dhu_hu_hu_jp3;
dc(id_z2_xs , jp3) = 1/2*dhss_jp3 + 1/2*dhuu_jp3*E_uu(:) + 1/2*huu*dE_uu_jp3(:);
dc(id_z3_xf_xf , jp3) = dhu_hu_jp3*E_uu(:) + hu_hu*dE_uu_jp3(:);
dC(: , id_z1_xf , jp3) = dgx_jp3 + 3/6*dgxss_jp3;
dC(: , id_z2_xs , jp3) = dgx_jp3;
dC(: , id_z3_xf_xf , jp3) = 1/2*dgxx_jp3;
dC(: , id_z4_xrd , jp3) = dgx_jp3;
dC(: , id_z5_xf_xs , jp3) = dgxx_jp3;
dC(: , id_z6_xf_xf_xf , jp3) = 1/6*dgxxx_jp3;
dD(: , id_inov1_u , jp3) = dgu_jp3 + 3/6*dguss_jp3;
dD(: , id_inov2_u_u , jp3) = 1/2*dguu_jp3;
dD(: , id_inov3_xf_u , jp3) = dgxu_jp3;
dD(: , id_inov4_xs_u , jp3) = dgxu_jp3;
dD(: , id_inov5_xf_xf_u , jp3) = 3/6*dgxxu_jp3;
dD(: , id_inov6_xf_u_u , jp3) = 3/6*dgxuu_jp3;
dD(: , id_inov7_u_u_u , jp3) = 1/6*dguuu_jp3;
dd(:,jp3) = 1/2*dgss_jp3 + 1/2*dguu_jp3*E_uu(:) + 1/2*guu*dE_uu_jp3(:);
dVarinov(id_inov1_u , id_inov1_u , jp3) = dE_uu_jp3;
dVarinov(id_inov1_u , id_inov4_xs_u , jp3) = kron(dE_xs_jp3',E_uu) + kron(E_xs',dE_uu_jp3);
dVarinov(id_inov1_u , id_inov5_xf_xf_u , jp3) = kron(dE_xfxf_jp3(:)',E_uu) + kron(E_xfxf(:)',dE_uu_jp3);
dVarinov(id_inov1_u , id_inov7_u_u_u , jp3) = reshape(dE_u_u_u_u_jp3,u_nbr,u_nbr^3);
dVarinov(id_inov2_u_u , id_inov2_u_u , jp3) = reshape(dE_u_u_u_u_jp3,u_nbr^2,u_nbr^2) - dE_uu_jp3(:)*E_uu(:)' - E_uu(:)*dE_uu_jp3(:)';
dVarinov(id_inov3_xf_u , id_inov3_xf_u , jp3) = dE_xfxf_uu_jp3;
dVarinov(id_inov4_xs_u , id_inov1_u , jp3) = kron(dE_xs_jp3,E_uu) + kron(E_xs,dE_uu_jp3);
dVarinov(id_inov4_xs_u , id_inov4_xs_u , jp3) = kron(dE_xsxs_jp3,E_uu) + kron(E_xsxs,dE_uu_jp3);
dVarinov(id_inov4_xs_u , id_inov5_xf_xf_u , jp3) = kron(dE_xsxf_xf_jp3, E_uu) + kron(E_xsxf_xf, dE_uu_jp3);
dVarinov(id_inov4_xs_u , id_inov7_u_u_u , jp3) = kron(dE_xs_jp3,reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xs,reshape(dE_u_u_u_u_jp3,u_nbr,u_nbr^3));
dVarinov(id_inov5_xf_xf_u , id_inov1_u , jp3) = kron(dE_xfxf_jp3(:),E_uu) + kron(E_xfxf(:),dE_uu_jp3);
dVarinov(id_inov5_xf_xf_u , id_inov4_xs_u , jp3) = kron(dE_xf_xfxs_jp3,E_uu) + kron(E_xf_xfxs,dE_uu_jp3);
dVarinov(id_inov5_xf_xf_u , id_inov5_xf_xf_u , jp3) = kron(dE_xf_xfxf_xf_jp3,E_uu) + kron(E_xf_xfxf_xf,dE_uu_jp3);
dVarinov(id_inov5_xf_xf_u , id_inov7_u_u_u , jp3) = kron(dE_xfxf_jp3(:),reshape(QPu*E_u_u_u_u,u_nbr,u_nbr^3)) + kron(E_xfxf(:),reshape(dE_u_u_u_u_jp3,u_nbr,u_nbr^3));
dVarinov(id_inov6_xf_u_u , id_inov6_xf_u_u , jp3) = kron(dE_xfxf_jp3,reshape(QPu*E_u_u_u_u,u_nbr^2,u_nbr^2)) + kron(E_xfxf,reshape(dE_u_u_u_u_jp3,u_nbr^2,u_nbr^2));
dVarinov(id_inov7_u_u_u , id_inov1_u , jp3) = reshape(dE_u_u_u_u_jp3,u_nbr^3,u_nbr);
dVarinov(id_inov7_u_u_u , id_inov4_xs_u , jp3) = kron(dE_xs_jp3',reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)) + kron(E_xs',reshape(dE_u_u_u_u_jp3,u_nbr^3,u_nbr));
dVarinov(id_inov7_u_u_u , id_inov5_xf_xf_u , jp3) = kron(transpose(dE_xfxf_jp3(:)),reshape(QPu*E_u_u_u_u,u_nbr^3,u_nbr)) + kron(transpose(E_xfxf(:)),reshape(dE_u_u_u_u_jp3,u_nbr^3,u_nbr));
dVarinov(id_inov7_u_u_u , id_inov7_u_u_u , jp3) = reshape(dE_u_u_u_u_u_u_jp3,u_nbr^3,u_nbr^3);
dE_inovzlag1(id_inov6_xf_u_u , id_z1_xf , jp3) = kron(dE_xfxf_jp3,E_uu(:)) + kron(E_xfxf,dE_uu_jp3(:));
dE_inovzlag1(id_inov6_xf_u_u , id_z4_xrd , jp3) = kron(dE_xrdxf_jp3',E_uu(:)) + kron(E_xrdxf',dE_uu_jp3(:));
dE_inovzlag1(id_inov6_xf_u_u , id_z5_xf_xs , jp3) = kron(reshape(K_xx_x*vec(dE_xsxf_xf_jp3),x_nbr,x_nbr^2),vec(E_uu)) + kron(reshape(K_xx_x*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(dE_uu_jp3)) ;
dE_inovzlag1(id_inov6_xf_u_u , id_z6_xf_xf_xf , jp3) = kron(reshape(dE_xf_xfxf_xf_jp3,x_nbr,x_nbr^3),E_uu(:)) + kron(reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),dE_uu_jp3(:));
dBinovzlag1A_jp3 = dB(:,:,jp3)*E_inovzlag1*transpose(A) + B*dE_inovzlag1(:,:,jp3)*transpose(A) + B*E_inovzlag1*transpose(dA(:,:,jp3));
dOm_z_jp3 = dB(:,:,jp3)*Varinov*transpose(B) + B*dVarinov(:,:,jp3)*transpose(B) + B*Varinov*transpose(dB(:,:,jp3)) + dBinovzlag1A_jp3 + transpose(dBinovzlag1A_jp3);
[dVar_z(:,:,jp3), errorflag] = disclyap_fast(A, dA(:,:,jp3)*Var_z*A' + A*Var_z*dA(:,:,jp3)' + dOm_z_jp3, options_.lyapunov_doubling_tol);
if errorflag
dVar_z(:,:,jp3) = lyapunov_symm(A, dA(:,:,jp3)*Var_z*A' + A*Var_z*dA(:,:,jp3)' + dOm_z_jp3,...
options_.lyapunov_fixed_point_tol,options_.qz_criterium,options_.lyapunov_complex_threshold,...
lyapunov_symm_method,...
options_.debug);
if lyapunov_symm_method == 1
lyapunov_symm_method = 2; %now we can reuse persistent schur
end
end
%make sure some stuff is zero due to Gaussianity
dVar_z(id_z1_xf , id_z2_xs , jp3) = zeros(x_nbr,x_nbr);
dVar_z(id_z1_xf , id_z3_xf_xf , jp3) = zeros(x_nbr,x_nbr^2);
dVar_z(id_z2_xs , id_z1_xf , jp3) = zeros(x_nbr,x_nbr);
dVar_z(id_z2_xs , id_z4_xrd , jp3) = zeros(x_nbr,x_nbr);
dVar_z(id_z2_xs , id_z5_xf_xs , jp3) = zeros(x_nbr,x_nbr^2);
dVar_z(id_z2_xs , id_z6_xf_xf_xf , jp3) = zeros(x_nbr,x_nbr^3);
dVar_z(id_z3_xf_xf , id_z1_xf , jp3) = zeros(x_nbr^2,x_nbr);
dVar_z(id_z3_xf_xf , id_z4_xrd , jp3) = zeros(x_nbr^2,x_nbr);
dVar_z(id_z3_xf_xf , id_z5_xf_xs , jp3) = zeros(x_nbr^2,x_nbr^2);
dVar_z(id_z3_xf_xf , id_z6_xf_xf_xf , jp3) = zeros(x_nbr^2,x_nbr^3);
dVar_z(id_z4_xrd , id_z2_xs , jp3) = zeros(x_nbr,x_nbr);
dVar_z(id_z4_xrd , id_z3_xf_xf , jp3) = zeros(x_nbr,x_nbr^2);
dVar_z(id_z5_xf_xs , id_z2_xs , jp3) = zeros(x_nbr^2,x_nbr);
dVar_z(id_z5_xf_xs , id_z3_xf_xf , jp3) = zeros(x_nbr^2,x_nbr^2);
dVar_z(id_z6_xf_xf_xf , id_z2_xs , jp3) = zeros(x_nbr^3,x_nbr);
dVar_z(id_z6_xf_xf_xf , id_z3_xf_xf , jp3) = zeros(x_nbr^3,x_nbr^2);
end
end
end
end
%% Covariance/Correlation of control variables
Var_y = NaN*ones(y_nbr,y_nbr);
if order < 3
Var_y(stationary_vars,stationary_vars) = C(stationary_vars,:)*Var_z*C(stationary_vars,:)'...
+ D(stationary_vars,:)*Varinov*D(stationary_vars,:)';
else
Var_y(stationary_vars,stationary_vars) = C(stationary_vars,:)*Var_z*C(stationary_vars,:)'...
+ D(stationary_vars,:)*E_inovzlag1*C(stationary_vars,:)'...
+ C(stationary_vars,:)*transpose(E_inovzlag1)*D(stationary_vars,:)'...
+ D(stationary_vars,:)*Varinov*D(stationary_vars,:)';
end
Var_y(abs(Var_y) < 1e-12) = 0; %find values that are numerical zero
if useautocorr
sdy = sqrt(diag(Var_y)); %theoretical standard deviation
sdy = sdy(stationary_vars);
sy = sdy*sdy'; %cross products of standard deviations
Corr_y = NaN*ones(y_nbr,y_nbr);
Corr_y(stationary_vars,stationary_vars) = Var_y(stationary_vars,stationary_vars)./sy;
Corr_yi = NaN*ones(y_nbr,y_nbr,nlags);
end
if compute_derivs
dVar_y = NaN*ones(y_nbr,y_nbr,totparam_nbr);
if useautocorr
dCorr_y = NaN*ones(y_nbr,y_nbr,totparam_nbr);
dCorr_yi = NaN*ones(y_nbr,y_nbr,nlags,totparam_nbr);
end
for jpV=1:totparam_nbr
if order < 3
dVar_y_tmp = dC(stationary_vars,:,jpV)*Var_z*C(stationary_vars,:)' + C(stationary_vars,:)*dVar_z(:,:,jpV)*C(stationary_vars,:)' + C(stationary_vars,:)*Var_z*dC(stationary_vars,:,jpV)'...
+ dD(stationary_vars,:,jpV)*Varinov*D(stationary_vars,:)' + D(stationary_vars,:)*dVarinov(:,:,jpV)*D(stationary_vars,:)' + D(stationary_vars,:)*Varinov*dD(stationary_vars,:,jpV)';
else
dVar_y_tmp = dC(stationary_vars,:,jpV)*Var_z*C(stationary_vars,:)' + C(stationary_vars,:)*dVar_z(:,:,jpV)*C(stationary_vars,:)' + C(stationary_vars,:)*Var_z*dC(stationary_vars,:,jpV)'...
+ dD(stationary_vars,:,jpV)*E_inovzlag1*C(stationary_vars,:)' + D(stationary_vars,:)*dE_inovzlag1(:,:,jpV)*C(stationary_vars,:)' + D(stationary_vars,:)*E_inovzlag1*dC(stationary_vars,:,jpV)'...
+ dC(stationary_vars,:,jpV)*transpose(E_inovzlag1)*D(stationary_vars,:)' + C(stationary_vars,:)*transpose(dE_inovzlag1(:,:,jpV))*D(stationary_vars,:)' + C(stationary_vars,:)*transpose(E_inovzlag1)*dD(stationary_vars,:,jpV)'...
+ dD(stationary_vars,:,jpV)*Varinov*D(stationary_vars,:)' + D(stationary_vars,:)*dVarinov(:,:,jpV)*D(stationary_vars,:)' + D(stationary_vars,:)*Varinov*dD(stationary_vars,:,jpV)';
end
dVar_y_tmp(abs(dVar_y_tmp) < 1e-12) = 0; %find values that are numerical zero
dVar_y(stationary_vars,stationary_vars,jpV) = dVar_y_tmp;
if useautocorr
dsy = 1/2./sdy.*diag(dVar_y(:,:,jpV));
dsy = dsy(stationary_vars);
dsy = dsy*sdy'+sdy*dsy';
dCorr_y(stationary_vars,stationary_vars,jpV) = (dVar_y(stationary_vars,stationary_vars,jpV).*sy-dsy.*Var_y(stationary_vars,stationary_vars))./(sy.*sy);
dCorr_y(stationary_vars,stationary_vars,jpV) = dCorr_y(stationary_vars,stationary_vars,jpV)-diag(diag(dCorr_y(stationary_vars,stationary_vars,jpV)))+diag(diag(dVar_y(stationary_vars,stationary_vars,jpV)));
end
end
end
%% Autocovariances/autocorrelations of lagged control variables
Var_yi = NaN*ones(y_nbr,y_nbr,nlags);
Ai = eye(z_nbr); %this is A^0
hxi = eye(x_nbr);
E_inovzlagi = E_inovzlag1;
Var_zi = Var_z;
if order <= 2
tmp = A*Var_z*C(stationary_vars,:)' + B*Varinov*D(stationary_vars,:)';
else
tmp = A*E_inovzlag1'*D(stationary_vars,:)' + B*Varinov*D(stationary_vars,:)';
end
for i = 1:nlags
if order <= 2
Var_yi(stationary_vars,stationary_vars,i) = C(stationary_vars,:)*Ai*tmp;
else
Var_zi = A*Var_zi + B*E_inovzlagi;
hxi = hx*hxi;
E_inovzlagi = zeros(inov_nbr,z_nbr);
E_inovzlagi(id_inov6_xf_u_u , id_z1_xf ) = kron(hxi*E_xfxf,E_uu(:));
E_inovzlagi(id_inov6_xf_u_u , id_z4_xrd ) = kron(hxi*E_xrdxf',E_uu(:));
E_inovzlagi(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(hxi*reshape(K_xx_x*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu));
E_inovzlagi(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(hxi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:));
Var_yi(stationary_vars,stationary_vars,i) = C(stationary_vars,:)*Var_zi*C(stationary_vars,:)' + C(stationary_vars,:)*Ai*tmp + D(stationary_vars,:)*E_inovzlagi*C(stationary_vars,:)';
end
if useautocorr
Corr_yi(stationary_vars,stationary_vars,i) = Var_yi(stationary_vars,stationary_vars,i)./sy;
end
Ai = Ai*A; %note that this is A^(i-1)
end
if compute_derivs
dVar_yi = NaN*ones(y_nbr,y_nbr,nlags,totparam_nbr);
for jpVi=1:totparam_nbr
Ai = eye(z_nbr); dAi_jpVi = zeros(z_nbr,z_nbr);
hxi = eye(x_nbr); dhxi_jpVi = zeros(x_nbr,x_nbr);
E_inovzlagi = E_inovzlag1; dE_inovzlagi_jpVi = dE_inovzlag1(:,:,jpVi);
Var_zi = Var_z; dVar_zi_jpVi = dVar_z(:,:,jpVi);
if order <= 2
dtmp_jpVi = dA(:,:,jpVi)*Var_z*C(stationary_vars,:)' + A*dVar_z(:,:,jpVi)*C(stationary_vars,:)' + A*Var_z*dC(stationary_vars,:,jpVi)'...
+ dB(:,:,jpVi)*Varinov*D(stationary_vars,:)' + B*dVarinov(:,:,jpVi)*D(stationary_vars,:)' + B*Varinov*dD(stationary_vars,:,jpVi)';
else
dtmp_jpVi = dA(:,:,jpVi)*E_inovzlag1'*D(stationary_vars,:)' + A*dE_inovzlag1(:,:,jpVi)'*D(stationary_vars,:)' + A*E_inovzlag1'*dD(stationary_vars,:,jpVi)'...
+ dB(:,:,jpVi)*Varinov*D(stationary_vars,:)' + B*dVarinov(:,:,jpVi)*D(stationary_vars,:)' + B*Varinov*dD(stationary_vars,:,jpVi)';
end
for i = 1:nlags
if order <= 2
dVar_yi(stationary_vars,stationary_vars,i,jpVi) = dC(stationary_vars,:,jpVi)*Ai*tmp + C(stationary_vars,:)*dAi_jpVi*tmp + C(stationary_vars,:)*Ai*dtmp_jpVi;
else
Var_zi = A*Var_zi + B*E_inovzlagi;
dVar_zi_jpVi = dA(:,:,jpVi)*Var_zi + A*dVar_zi_jpVi + dB(:,:,jpVi)*E_inovzlagi + + B*dE_inovzlagi_jpVi;
dhxi_jpVi = dhx(:,:,jpVi)*hxi + hx*dhxi_jpVi;
hxi = hx*hxi;
E_inovzlagi = zeros(inov_nbr,z_nbr);
E_inovzlagi(id_inov6_xf_u_u , id_z1_xf ) = kron(hxi*E_xfxf,E_uu(:));
E_inovzlagi(id_inov6_xf_u_u , id_z4_xrd ) = kron(hxi*E_xrdxf',E_uu(:));
E_inovzlagi(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(hxi*reshape(K_xx_x*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu));
E_inovzlagi(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(hxi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:));
dE_inovzlagi_jpVi = zeros(inov_nbr,z_nbr);
dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z1_xf ) = kron(dhxi_jpVi*E_xfxf,E_uu(:)) + kron(hxi*dE_xfxf(:,:,jpVi),E_uu(:)) + kron(hxi*E_xfxf,vec(dE_uu(:,:,jpVi)));
dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z4_xrd ) = kron(dhxi_jpVi*E_xrdxf',E_uu(:)) + kron(hxi*dE_xrdxf(:,:,jpVi)',E_uu(:)) + kron(hxi*E_xrdxf',vec(dE_uu(:,:,jpVi)));
dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z5_xf_xs ) = kron(dhxi_jpVi*reshape(K_xx_x*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(E_uu)) + kron(hxi*reshape(K_xx_x*vec(dE_xsxf_xf(:,:,jpVi)),x_nbr,x_nbr^2),vec(E_uu)) + kron(hxi*reshape(K_xx_x*vec(E_xsxf_xf),x_nbr,x_nbr^2),vec(dE_uu(:,:,jpVi)));
dE_inovzlagi_jpVi(id_inov6_xf_u_u , id_z6_xf_xf_xf ) = kron(dhxi_jpVi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),E_uu(:)) + kron(hxi*reshape(dE_xf_xfxf_xf(:,:,jpVi),x_nbr,x_nbr^3),E_uu(:)) + kron(hxi*reshape(E_xf_xfxf_xf,x_nbr,x_nbr^3),vec(dE_uu(:,:,jpVi)));
dVar_yi(stationary_vars,stationary_vars,i,jpVi) = dC(stationary_vars,:,jpVi)*Var_zi*C(stationary_vars,:)' + C(stationary_vars,:)*dVar_zi_jpVi*C(stationary_vars,:)' + C(stationary_vars,:)*Var_zi*dC(stationary_vars,:,jpVi)'...
+ dC(stationary_vars,:,jpVi)*Ai*tmp + C(stationary_vars,:)*dAi_jpVi*tmp + C(stationary_vars,:)*Ai*dtmp_jpVi...
+ dD(stationary_vars,:,jpVi)*E_inovzlagi*C(stationary_vars,:)' + D(stationary_vars,:)*dE_inovzlagi_jpVi*C(stationary_vars,:)' + D(stationary_vars,:)*E_inovzlagi*dC(stationary_vars,:,jpVi)';
end
if useautocorr
dsy = 1/2./sdy.*diag(dVar_y(:,:,jpVi));
dsy = dsy(stationary_vars);
dsy = dsy*sdy'+sdy*dsy';
dCorr_yi(stationary_vars,stationary_vars,i,jpVi) = (dVar_yi(stationary_vars,stationary_vars,i,jpVi).*sy-dsy.*Var_yi(stationary_vars,stationary_vars,i))./(sy.*sy);
end
dAi_jpVi = dAi_jpVi*A + Ai*dA(:,:,jpVi);
Ai = Ai*A;
end
end
end
%% Mean of control variables
E_z = E_xf;
if order > 1
E_z = [E_xf;E_xs;E_xfxf(:)];
end
if order > 2
E_xf_xs = zeros(x_nbr^2,1);
E_xf_xf_xf = zeros(x_nbr^3,1);
E_z = [E_xf;E_xs;E_xfxf(:);E_xrd;E_xf_xs;E_xf_xf_xf];
end
E_y = Yss(indy,:) + C*E_z + d;
if compute_derivs
dE_y = zeros(y_nbr,totparam_nbr);
for jpE = 1:totparam_nbr
if order == 1
dE_z_jpE = dE_xf(:,jpE);
elseif order == 2
dE_z_jpE = [dE_xf(:,jpE);dE_xs(:,jpE);vec(dE_xfxf(:,:,jpE))];
elseif order == 3
dE_xf_xs_jpE = zeros(x_nbr^2,1);
dE_xf_xf_xf_jpE = zeros(x_nbr^3,1);
dE_z_jpE = [dE_xf(:,jpE);dE_xs(:,jpE);vec(dE_xfxf(:,:,jpE)); dE_xrd(:,jpE); dE_xf_xs_jpE; dE_xf_xf_xf_jpE];
end
dE_y(:,jpE) = dC(:,:,jpE)*E_z + C*dE_z_jpE + dd(:,jpE);
if jpE > (stderrparam_nbr+corrparam_nbr)
dE_y(:,jpE) = dE_y(:,jpE) + dYss(indy,jpE-stderrparam_nbr-corrparam_nbr); %add steady state
end
end
end
non_stationary_vars = ~ismember((1:y_nbr)',stationary_vars);
E_y(non_stationary_vars) = NaN;
if compute_derivs
dE_y(non_stationary_vars,:) = NaN;
end
%% Store into output structure
pruned_state_space.indx = indx;
pruned_state_space.indy = indy;
pruned_state_space.A = A;
pruned_state_space.B = B;
pruned_state_space.C = C;
pruned_state_space.D = D;
pruned_state_space.c = c;
pruned_state_space.d = d;
pruned_state_space.Varinov = Varinov;
% pruned_state_space.Var_z = Var_z; %
pruned_state_space.Var_y = Var_y;
pruned_state_space.Var_yi = Var_yi;
if useautocorr
pruned_state_space.Corr_y = Corr_y;
pruned_state_space.Corr_yi = Corr_yi;
end
pruned_state_space.E_y = E_y;
if compute_derivs == 1
pruned_state_space.dA = dA;
pruned_state_space.dB = dB;
pruned_state_space.dC = dC;
pruned_state_space.dD = dD;
pruned_state_space.dc = dc;
pruned_state_space.dd = dd;
pruned_state_space.dVarinov = dVarinov;
pruned_state_space.dVar_y = dVar_y;
pruned_state_space.dVar_yi = dVar_yi;
if useautocorr
pruned_state_space.dCorr_y = dCorr_y;
pruned_state_space.dCorr_yi = dCorr_yi;
end
pruned_state_space.dE_y = dE_y;
end