1function WriteShockDecomp2Excel(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions,opts_decomp)
2%function WriteShockDecomp2Excel(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions)
3% Saves the results from the shock_decomposition command to xls
4%
5% Inputs
6%   z               [n_var*(nshock+2)*nperiods]     shock decomposition array, see shock_decomposition.m for details
7%   shock_names     [endo_nbr*string length]        shock names from M_.exo_names
8%   endo_names      [exo_nbr*string length]         variable names from M_.endo_names
9%   i_var           [n_var*1]                       vector indices of requested variables in M_.endo_names and z
10%   initial_date    [dseries object]                first period of decomposition to plot
11%   DynareModel     [structure]                     Dynare model structure
12%   DynareOptions   [structure]                     Dynare options structure
13
14% Copyright (C) 2016-2018 Dynare Team
15%
16% This file is part of Dynare.
17%
18% Dynare is free software: you can redistribute it and/or modify
19% it under the terms of the GNU General Public License as published by
20% the Free Software Foundation, either version 3 of the License, or
21% (at your option) any later version.
22%
23% Dynare is distributed in the hope that it will be useful,
24% but WITHOUT ANY WARRANTY; without even the implied warranty of
25% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26% GNU General Public License for more details.
27%
28% You should have received a copy of the GNU General Public License
29% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
30
31SteadyState=[];
32fig_mode='';
33fig_mode1='';
34fig_name='';
35screen_shocks=0;
36use_shock_groups = DynareOptions.plot_shock_decomp.use_shock_groups;
37if use_shock_groups
38    shock_groups = DynareModel.shock_groups.(use_shock_groups);
39    shock_ind = fieldnames(shock_groups);
40end
41
42% number of components equals number of shocks + 1 (initial conditions)
43comp_nbr = size(z,2)-1;
44
45if nargin==8
46    if isfield(opts_decomp,'steady_state')
47        SteadyState = opts_decomp.steady_state;
48    end
49    if isfield(opts_decomp,'fig_mode') && ~isempty(opts_decomp.fig_mode)
50        fig_mode = opts_decomp.fig_mode;
51        fig_mode1 = ['_' fig_mode];
52        fig_mode = [fig_mode '_'];
53    end
54    if isfield(opts_decomp,'screen_shocks')
55        if use_shock_groups
56            screen_shocks=0;
57        elseif comp_nbr>18
58            screen_shocks = opts_decomp.screen_shocks;
59        end
60    end
61    if isfield(opts_decomp,'fig_name')
62        fig_name = opts_decomp.fig_name;
63        %         fig_name = ['_' fig_name];
64        fig_name1 = [fig_name];
65        fig_name = [fig_name '_'];
66    end
67    if screen_shocks
68        fig_name1 = [fig_name1 '_screen'];
69        fig_name = [fig_name 'screen_'];
70    end
71end
72
73
74gend = size(z,3);
75if isempty(initial_date)
76    x = 1:gend;
77else
78    freq = initial_date.freq;
79    initial_period = initial_date.time(1) + (initial_date.time(2)-1)/freq;
80    x = initial_period:(1/freq):initial_period+(gend-1)/freq;
81end
82
83
84nvar = length(i_var);
85
86labels = char(char(shock_names),'Initial values');
87if ~(screen_shocks && comp_nbr>18)
88    screen_shocks=0;
89end
90comp_nbr0=comp_nbr;
91%%plot decomposition
92for j=1:nvar
93    d0={};
94    z1 = squeeze(z(i_var(j),:,:));
95    if screen_shocks
96        [~, isort] = sort(mean(abs(z1(1:end-2,:)')), 'descend');
97        labels = char(char(shock_names(isort(1:16))),'Others', 'Initial values');
98        zres = sum(z1(isort(17:end),:),1);
99        z1 = [z1(isort(1:16),:); zres; z1(comp_nbr0:end,:)];
100        comp_nbr=18;
101    end
102
103    d0(1,:)=[{'Decomposition'} cellstr(labels(1:comp_nbr,:))' {'Smoot Var'} {'Steady State'}];
104    d0=[d0; num2cell([x' z1' ]), [num2cell(SteadyState(i_var(j))); cell(size(z1,2)-1,1)]];
105    LastRow=size(d0,1);
106    if use_shock_groups
107        d0(LastRow+2,1)={'Legend.'};
108        d0(LastRow+2,2)={'Shocks include:'};
109        d0(LastRow+3:LastRow+3+comp_nbr-1,1)=cellstr(labels(1:comp_nbr,:));
110        for ic=1:comp_nbr
111            group_members = shock_groups.(shock_ind{ic}).shocks;
112            d0(LastRow+2+ic,2:1+length(group_members))=group_members;
113        end
114    end
115
116    warning off
117    try
118        [STATUS,MESSAGE] = xlswrite([DynareModel.fname,'_shock_decomposition',fig_mode,fig_name1],d0,endo_names{i_var(j)});
119    catch
120        if exist('xlwrite.m','file')
121            [STATUS] = xlwrite([DynareModel.fname,'_shock_decomposition',fig_mode,fig_name1],d0,endo_names{i_var(j)});
122        else
123            fprintf('\nWriteShockDecomp2Excel: could not write Excel file. It seems Excel is not installed on your machine.\n')
124            fprintf('Please install the free xlwrite.m from https://mathworks.com/matlabcentral/fileexchange/38591-xlwrite-generate-xls-x-files-without-excel-on-mac-linux-win\n')
125        end
126    end
127    warning on
128
129    clear d0
130
131end
132