function PrintFEVD(DSGEModel,CurrINI,VDs,PrintGroups,VarType,NumDraws,TotalDraws,CurrChain)
% PrintFEVD: Writes the forecast error variance decompositions for the observed variables to a text file.
%
% USAGE:
%
%       PrintFEVD(DSGEModel,CurrINI,CVDs,PrintGroups,VarType,NumDraws,TotalDraws,CurrChain)
%
% REQUIRED INPUT: DSGEModel (structure) whose fields contain all required information
%                           about the model, such as input files, variable and sample
%                           data. Actual observations are not stored in this file.
%
%                 CurrINI (structure), with initialization information.
%
%                 VDs (structure) with fields "FEVD", "LRVD", "Econ", "EconLR", and "Quantiles". The "FEVD" field holds a
%                           3D matrix of dimension n x (n+q+1) x h, where n is the number of observed variables, q
%                           the number of shocks, and h the impulse response horizon. The values are the posterior mean
%                           forecast error variance decomposition. The "LRVD" field holds a matrix of dimension nx(n+q)
%                           with the posterior mean long-run forecast error variance decomposition. The "Econ" field holds
%                           an nxh matrix with the posterior mean of forecast error variance decomposition for all
%                           economic (structural) shocks. Similarly, "EconLR" is an nx1 vector with the posterior mean
%                           long-run forecast error variance decomposition of all economic shocks. The field "Quantiles"
%                           is a vector structure with fields "FEVD", "LRVD", "Econ", "EconLR", and "percent", where "FEVD"
%                           holds a 3D matrix of dimension n x (n+q+1) x h with values from the percent quantile of the
%                           marginal distribution of the forecast error variance decomposition, "LRVD" holds a matrix of
%                           dimension nx(n+q) with values from the percent quantile of the marginal distribution of the
%                           long-run forecast error variance decomposition, "Econ" is a matrix of dimension nxh with values
%                           from the percent quantile of the marginal distribution of the forecast error variance
%                           decomposition of all the economci shocks, "EconLR" is a matrix of dimension nx1 with values
%                           from the percent quantile of the marginal distribution of the long-run forecast error variance
%                           decomposition of all the economic shocks, while "percent" holds the percentile value in percent.
%
%                 PrintGroups (boolean) which determines if shocks groups should be printed (1) or not (0).
%
%                 VarType (string vector) that takes on the values "Original" or "Levels".
%
%                 NumDraws (integer) with the number of draws from the posterior distribution
%                           of the DSGE model parameters that were used in the computations.
%
%                 TotalDraws (integer) with the total number of draws from the posterior
%                           distribution of the DSGE model parameters that could have been
%                           used for the computations.
%
%                 CurrChain (integer) with the value of the current MCMC chain.
%
%
%                       Written by: Anders Warne
%                                   New Area Wide Model Project
%                                   DG-R/EMO
%                                   European Central Bank (ECB)
%                                   Email: anders.warne@ecb.europa.eu
%                                   Copyright © 2006-2009 European Central Bank.
%
%                       First version: April 23, 2008.
%                        This version: January 21, 2009.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LICENSE INFORMATION:
%
%      YADA 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.
%
%      This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
%
%      YADA is released under the GNU General Public License, Version 3,
%      29 June 2007 <http://www.gnu.org/licenses/>. The current release of
%      the program was last modified by the ECB on the "This version" date
%      above.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CHANGELOG:
%
% * 24-4-2088:  Fixed an issue where writing of shock group members always started with "All Measure Error", i.e.,
%               the "NamesMatrix" string matrix was used without taking into account that the first row had nothing
%               to do with the shock groups.
%
% * 23-5-2008:  Updated the documentation.
%
% * 21-01-2009: Updated the documentation.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

if PrintGroups==0;
   ResFile = [DSGEModel.OutputDirectory '\PosteriorDist-VD-' VarType '-' num2str(CurrChain,'%0.0f') '-' DSGEModel.NameOfModel '-' num2str(NumDraws,'%0.0f') '.' num2str(TotalDraws,'%0.0f') '.txt'];
else;
   ResFile = [DSGEModel.OutputDirectory '\PosteriorDist-VD-ShockGroups-' VarType '-' num2str(CurrChain,'%0.0f') '-' DSGEModel.NameOfModel '-' num2str(NumDraws,'%0.0f') '.' num2str(TotalDraws,'%0.0f') '.txt'];
end;
fid = fopen(ResFile,'wt');
fprintf(fid,'********************************************************************************\n');
fprintf(fid,'*                                                                              *\n');
fprintf(fid,'* F O R E C A S T   E R R O R   V A R I A N C E   D E C O M P O S I T I O N S  *\n');
fprintf(fid,'*                                                                              *\n');
fprintf(fid,'********************************************************************************\n\n');
fprintf(fid,'Number of parameter draws used:      %0.0f \n',NumDraws);
fprintf(fid,'Number of available parameter draws: %0.0f \n',TotalDraws);
fprintf(fid,'Current MCMC chain:                  %0.0f \n\n',CurrChain);
%
fprintf(fid,'NOTE: The Signal Extraction Error row is explained in "YADA Manual - Computational Details".\n\n');
fprintf(fid,'      Posterior mean values of the variance decompositions for the %s\n      data along with quantiles.\n\n',lower(VarType));
%
%
% check if we should relate the shocks to shock groups
%
if PrintGroups==1;
   for i=1:size(DSGEModel.ShockGroupNames,1);
      iGroup = (DSGEModel.ShockGroups==i) .* (1:length(DSGEModel.ShockGroups));
      iGroup = iGroup(iGroup>0);
      ShockNames = StrWrap(vecstr(DSGEModel.StateShockNames(iGroup,:),' '),60);
      GroupName = StringTrim(strrep(DSGEModel.ShockGroupNames(i,:),'_',' '));
      if size(GroupName,2)<25;
         AddSpace = SpaceStr(25-size(GroupName,2));
      else;
         AddSpace = '';
      end;
      fprintf(fid,'%s:%s %s\n',GroupName,AddSpace,ShockNames(1,:));
      for j=2:size(ShockNames,1);
         if strcmp(StringTrim(ShockNames(j,:)),'')==0;
            fprintf(fid,'%s%s\n',SpaceStr(27),ShockNames(j,:));
         end;
      end;
   end;
   fprintf(fid,'\n');
end;
%
[n,q,h] = size(VDs.FEVD);
vn = size(DSGEModel.VariableNames,2);
if PrintGroups==0;
   NamesMatrix = '';
   for i=1:n;
      NamesMatrix = strvcat(NamesMatrix,sprintf('Measure Error %3.0f',i));
   end;
   NamesMatrix = strvcat(NamesMatrix,DSGEModel.StateShockNames,'Signal Extract Error');
   q = q-(n+1);
   n1 = n;
else;
   NamesMatrix = char(zeros(size(DSGEModel.ShockGroupNames)));
   for i=1:size(DSGEModel.ShockGroupNames,1);
      NamesMatrix(i,:) = strrep(DSGEModel.ShockGroupNames(i,:),'_',' ');
   end;
   NamesMatrix = strvcat('All Measure Error   ',NamesMatrix,'Signal Extract Error');
   q = q-2;
   n1 = 1;
end;
vq = size(NamesMatrix,2);
if vn<15;
   add_name_str = SpaceStr(15-vn);
else;
   add_name_str = '';
end;
if vq<20;
   add_shock_str = SpaceStr(20-vq);
else;
   add_shock_str = '';
end;
%
NameStr = '                    ';
MEStr = '';
prt_str = '%s';
prt_val = ['%' num2str(6+CurrINI.decimals,'%0.0f') '.' num2str(CurrINI.decimals,'%0.0f') 'f'];
q_prt_str = '       %4.1f quantile';
for i=1:n;
   NameStr = [NameStr '   ' add_name_str DSGEModel.VariableNames(i,:)];
   prt_str = [prt_str '      ' prt_val];
   q_prt_str = [q_prt_str '      ' prt_val];
end;
%
for i=1:size(NamesMatrix,1);
   MEStr = strvcat(MEStr,sprintf('%s%s',add_shock_str,NamesMatrix(i,:)));
end;
FirstStr = MultiCharStr('=',length(NameStr)+1);
DivStr = MultiCharStr('-',length(NameStr)+1);
%
% Write to output for horizon h
%
for j=1:h;
   fprintf(fid,'%s\n',FirstStr);
   fprintf(fid,'Forecast Horizon: %3.0f\n',j);
   fprintf(fid,'%s\n',NameStr);
   for i=1:n1;
      if i==1;
         fprintf(fid,'%s\n',DivStr);
      else;
         fprintf(fid,'%s\n',FirstStr);
      end;
      fprintf(fid,[prt_str '\n'],MEStr(i,:),abs(VDs.FEVD(:,i,j)));
      for k=1:length(VDs.Quantiles);
         fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).FEVD(:,i,j)));
      end;
   end;
   if PrintGroups==0;
      fprintf(fid,'%s\n',FirstStr);
      fprintf(fid,[prt_str '\n'],'All Measure Error   ',abs(sum(VDs.FEVD(:,1:n1,j),2)));
      for k=1:length(VDs.Quantiles);
         fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(sum(VDs.Quantiles(k).FEVD(:,1:n1,j),2)));
      end;
   end;
   for i=n1+1:q+n1;
      if i==n1+1;
         fprintf(fid,'%s\n',FirstStr);
      else;
         fprintf(fid,'%s\n',DivStr);
      end;
      fprintf(fid,[prt_str '\n'],MEStr(i,:),abs(VDs.FEVD(:,i,j)));
      for k=1:length(VDs.Quantiles);
         fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).FEVD(:,i,j)));
      end;
   end;
   fprintf(fid,'%s\n',FirstStr);
   fprintf(fid,[prt_str '\n'],'All Economic Shocks ',abs(VDs.Econ(:,j)));
   for k=1:length(VDs.Quantiles);
      fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).Econ(:,j)));
   end;
   fprintf(fid,'%s\n',FirstStr);
   fprintf(fid,[prt_str '\n'],MEStr(size(MEStr,1),:),abs(VDs.FEVD(:,size(MEStr,1),j)));
   for k=1:length(VDs.Quantiles);
      fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).FEVD(:,size(MEStr,1),j)));
   end;
   fprintf(fid,'%s\n\n',FirstStr);
end;
%
% time for the long-run
%
fprintf(fid,'%s\n',FirstStr);
fprintf(fid,'Forecast Horizon: Long run\n');
fprintf(fid,'%s\n',NameStr);
for i=1:n1;
   if i==1;
      fprintf(fid,'%s\n',DivStr);
   else;
      fprintf(fid,'%s\n',FirstStr);
   end;
   fprintf(fid,[prt_str '\n'],MEStr(i,:),abs(VDs.LRVD(:,i)));
   for k=1:length(VDs.Quantiles);
      fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).LRVD(:,i)));
   end;
end;
if PrintGroups==0;
   fprintf(fid,'%s\n',FirstStr);
   fprintf(fid,[prt_str '\n'],'All Measure Error   ',abs(sum(VDs.LRVD(:,1:n1),2)));
   for k=1:length(VDs.Quantiles);
      fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(sum(VDs.Quantiles(k).LRVD(:,1:n1),2)));
   end;
end;
for i=n1+1:q+n1;
   if i==n1+1;
      fprintf(fid,'%s\n',FirstStr);
   else;
      fprintf(fid,'%s\n',DivStr);
   end;
   fprintf(fid,[prt_str '\n'],MEStr(i,:),abs(VDs.LRVD(:,i)));
   for k=1:length(VDs.Quantiles);
      fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).LRVD(:,i)));
   end;
end;
fprintf(fid,'%s\n',FirstStr);
fprintf(fid,[prt_str '\n'],'All Economic Shocks ',abs(VDs.EconLR));
for k=1:length(VDs.Quantiles);
   fprintf(fid,[q_prt_str '\n'],VDs.Quantiles(k).percent,abs(VDs.Quantiles(k).EconLR));
end;
fprintf(fid,'%s\n\n',FirstStr);
%
% we're all done now
%
fprintf(fid,'Directory for file: %s\n',GetPath(ResFile));
fprintf(fid,'Name of file:       %s\n',GetFilename(ResFile));
fprintf(fid,'Output created on:  %s\n\n',datestr(now,0));
fclose(fid);

%
% end of PrintFEVD.m
%
