function out = irf_fevd_full(Gy,G,scl_par,fac_est_out, est_par, hor, tcode,res_ynews)
% This program computes IRFs and FEVDs.

n_fac=size(fac_est_out.fac,2); % number of factors
ind2yy=scl_par.indstrvar;      % index of the 2-year yield

if isempty(G)
    %-- compute IRFs and FEVDs wrt 1-SD yield shocks
    % Note, the level, slope and yield news shocks are indexed by 1, 2 and 3.
    fac_est_out_tmp=fac_est_out;
    fac_est_out_tmp.varout.coef.G=Gy;
    irf_fevd_out_Gy = irf_fevd(fac_est_out_tmp,est_par,hor,tcode);
    
    %-- scale shocks so that each leads to the same peak decline of the 2-year yield
    % as a 1-SD yield news shock
    imp_ynews=squeeze(irf_fevd_out_Gy.imp_y_fac_mat(:,3,:)); % IRFs wrt to yield news shock
    tmp1=imp_ynews(ind2yy,:);
    N_s=1;
    if sign(tmp1(12))>0
        N_s=-1;
    end
    imp_ynews_scl = N_s*imp_ynews;
    tmp1=imp_ynews_scl(ind2yy,:);
    [min1,ind1]=min(tmp1);
    s1=min1;  % peak effect on the 2-year yield
    
    %- set scale and sign for level and slope shocks
    imp_y_fac_mat_scl=nan(size(fac_est_out.lam_mat,1),n_fac,hor);
    s=ones(n_fac,1);
    for is=1:2
        imp_tmp=squeeze(irf_fevd_out_Gy.imp_y_fac_mat(:,is,:));
        tmp2=imp_tmp(ind2yy,:);
        [max2,ind2]=max(abs(tmp2));
        s2=sign(tmp2(ind2))*max2;
        imp_y_fac_mat_scl(:,is,:)=s1/s2*imp_tmp;
        s(is)=s1/s2;
    end
    
    imp_y_fac_mat_scl(:,3,:)=imp_ynews_scl; 
    s(3)=N_s;
    
	irf_fevd_out=irf_fevd_out_Gy;    
    irf_fevd_out.imp_y_fac_mat_scl=imp_y_fac_mat_scl;  
else
    %- construct IRFs and FEVDs for shocks to measures of volatility, leading economic indicators, etc.
    fac_est_out_tmp=fac_est_out;
    fac_est_out_tmp.varout.coef.G=G;
    irf_fevd_out_G = irf_fevd(fac_est_out_tmp,est_par,hor,tcode);
    
    imp_y_fac_mat_scl=nan(size(fac_est_out.lam_mat,1),n_fac,hor);
    s=ones(n_fac,1);
    if res_ynews==0
        %-- compute peak effect for the 2-year yield wrt a 1-SD yield news shocks 
        fac_est_out_tmp=fac_est_out;
        fac_est_out_tmp.varout.coef.G=Gy;
        irf_fevd_out_tmp = irf_fevd(fac_est_out_tmp,est_par,hor,tcode);
        imp_ynews=squeeze(irf_fevd_out_tmp.imp_y_fac_mat(:,3,:)); % IRFs wrt to yield news shock
        tmp1=imp_ynews(ind2yy,:);
        N_s=1;
        if sign(tmp1(12))>0
            N_s=-1;
        end
        imp_ynews_scl = N_s*imp_ynews;
        tmp1=imp_ynews_scl(ind2yy,:);
        [min1,ind1]=min(tmp1);
        s1=min1;  
        
        % set scale and sign for the other shock
        imp_tmp=squeeze(irf_fevd_out_G.imp_y_fac_mat(:,1,:));
        tmp2=imp_tmp(ind2yy,:);
        [max2,ind2]=max(abs(tmp2));
        s2=sign(tmp2(ind2))*max2;
        imp_y_fac_mat_scl(:,1,:)=s1/s2*imp_tmp;
        s(1)=s1/s2;
    else
        % set sign for residual yield news shock
        imp_resynews=squeeze(irf_fevd_out_G.imp_y_fac_mat(:,1,:));
        tmp1=imp_resynews(ind2yy,:);
        N_s=1;
        if sign(tmp1(12))>0
            N_s=-1;
        end
        imp_y_fac_mat_scl(:,1,:)=N_s*imp_resynews;
        s(1)=N_s;        
    end
    
    irf_fevd_out=irf_fevd_out_G;
    irf_fevd_out.imp_y_fac_mat_scl=imp_y_fac_mat_scl;    
end

%-- compute series of structural shocks
if isempty(G)
    G = Gy(1:n_fac,1:n_fac);      
else
    G = G(1:n_fac,1:n_fac);     
end
SG = diag(s); 
GS = G*SG;
GSI = inv(GS);
eps_reducedform = fac_est_out.varout.resid;
eps_structural = eps_reducedform*GSI';

%-- output
out=irf_fevd_out;
out.eps_structural=eps_structural;
end

