function reduced_form_mapping(dirname,options_gsa_,M_,estim_params_,options_,oo_)
% reduced_form_mapping(dirname,options_gsa_,M_,estim_params_,options_,oo_)
% Inputs:
% - dirname             [string]    name of the output directory
% - options_gsa_        [structure] GSA options_
% - M_                  [structure] describing the model
% - estim_params_       [structure] characterizing parameters to be estimated
% - options_            [structure] describing the options
% - oo_                 [structure] storing the results
%
% Written by Marco Ratto
% Joint Research Centre, The European Commission,
% marco.ratto@ec.europa.eu

% Copyright © 2012-2016 European Commission
% Copyright © 2012-2023 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/>.

anamendo = options_gsa_.namendo;
anamlagendo = options_gsa_.namlagendo;
anamexo = options_gsa_.namexo;
anamendo_tex = options_gsa_.namendo_tex;
anamlagendo_tex = options_gsa_.namlagendo_tex;
anamexo_tex = options_gsa_.namexo_tex;
iload = options_gsa_.load_redform;
pprior = options_gsa_.pprior;
ilog = options_gsa_.logtrans_redform;
threshold = options_gsa_.threshold_redform;

np = estim_params_.np;
nshock = estim_params_.nvx + estim_params_.nvn + estim_params_.ncx + estim_params_.ncn;
pnames=cell(np,1);
pnames_tex=cell(np,1);
for jj=1:np
    if options_.TeX
        [param_name_temp, param_name_tex_temp]= get_the_name(nshock+jj,options_.TeX,M_,estim_params_,options_.varobs);
        pnames_tex{jj,1} = param_name_tex_temp;
        pnames{jj,1} = param_name_temp;
    else
        param_name_temp = get_the_name(nshock+jj,options_.TeX,M_,estim_params_,options_.varobs);
        pnames{jj,1} = param_name_temp;
    end
end

fname_ = M_.fname;

Prior = dprior(estim_params_, M_, options_.prior_trunc);
bounds = prior_bounds(Prior, options_.prior_trunc);

if nargin==0
    dirname='';
end

if pprior
    load([dirname,filesep,M_.fname,'_prior'],'lpmat', 'lpmat0', 'istable','T');
    adir=[dirname filesep 'redform_prior'];
    type = 'prior';
else
    load([dirname,filesep,M_.fname,'_mc'],'lpmat', 'lpmat0', 'istable','T');
    adir=[dirname filesep 'redform_mc'];
    type = 'mc';
end
options_mcf.pvalue_ks = options_gsa_.ksstat_redform;
options_mcf.pvalue_corr = options_gsa_.alpha2_redform;
options_mcf.alpha2 = options_gsa_.alpha2_redform;
options_mcf.param_names = pnames;
if options_.TeX
    options_mcf.param_names_tex = pnames_tex;
end
options_mcf.fname_ = M_.fname;
options_mcf.OutputDirectoryName = adir;

if ~exist('T','var')
    gsa.stability_mapping(dirname,options_gsa_,M_,oo_,options_,estim_params_);
    if pprior
        load([dirname,filesep,M_.fname,'_prior'],'T');
    else
        load([dirname,filesep,M_.fname,'_mc'],'T');
    end
    if ~exist('T','var')
        disp('The model is too large!')
        disp('Reduced form mapping stopped!')
        return
    end
end
if isempty(dir(adir))
    mkdir(adir)
end

nspred=size(T,2)-M_.exo_nbr;
x0=lpmat(istable,:);
if isempty(lpmat0)
    xx0=[];
    nshocks=0;
else
    xx0=lpmat0(istable,:);
    nshocks=size(xx0,2);
end
[~, np]=size(x0);
offset = length(Prior)-np;
if options_gsa_.prior_range
    pshape=5*(ones(np,1));
    pd =  [NaN(np,1) NaN(np,1) bounds.lb(offset+1:end) bounds.ub(offset+1:end)];
else
    prior_shape = Prior.pshape();
    pshape = prior_shape(offset+1:end);
    pd =  [Prior.p6(offset+1:end) Prior.p7(offset+1:end) Prior.p3(offset+1:end) Prior.p4(offset+1:end)];
end

options_map.param_names = pnames;
if options_.TeX
    options_map.param_names_tex = pnames_tex;
end
options_map.fname_ = M_.fname;
options_map.OutputDirectoryName = adir;
options_map.iload = iload;
options_map.log_trans = ilog;
options_map.prior_range = options_gsa_.prior_range;
options_map.pshape = pshape;
options_map.pd = pd;

nsok = length(find(M_.lead_lag_incidence(M_.maximum_lag,:)));
lpmat0=[];
js=0;
for j = 1:length(anamendo)
    namendo = anamendo{j};
    namendo_tex = anamendo_tex{j};
    iendo = strmatch(namendo, M_.endo_names(oo_.dr.order_var), 'exact');
    ifig = 0;
    iplo = 0;
    for jx = 1:length(anamexo)
        namexo = anamexo{jx};
        namexo_tex = anamexo_tex{jx};
        iexo=strmatch(namexo, M_.exo_names, 'exact');
        skipline()
        disp(['[', namendo,' vs ',namexo,']'])

        if ~isempty(iexo)
            y0=squeeze(T(iendo,iexo+nspred,:));
            if (max(y0)-min(y0))>1.e-10
                if mod(iplo,9)==0 && isempty(threshold) && ~options_.nograph
                    ifig=ifig+1;
                    hh_fig = dyn_figure(options_.nodisplay,'name',['Reduced Form Mapping: ', namendo,' vs shocks ',int2str(ifig)]);
                    iplo=0;
                end
                iplo=iplo+1;
                js=js+1;
                xdir0 = [adir,filesep,namendo,'_vs_', namexo];
                if ilog==0 || ~isempty(threshold)
                    if isempty(threshold)
                        if isempty(dir(xdir0))
                            mkdir(xdir0)
                        end
                        atitle0=['Reduced Form Mapping (ANOVA) for ',namendo,' vs ', namexo];
                        aname=[type '_' namendo '_vs_' namexo];
                        atitle=[type ' Reduced Form Mapping (ANOVA): Parameter(s) driving ',namendo,' vs ',namexo];
                        options_map.amap_name = aname;
                        options_map.amap_title = atitle;
                        options_map.figtitle = atitle0;
                        options_map.title = [namendo,' vs ', namexo];
                        options_map.OutputDirectoryName = xdir0;
                        si(:,js) = redform_private(x0, y0, options_map, options_);
                    else
                        iy=find( (y0>threshold(1)) & (y0<threshold(2)));
                        iyc=find( (y0<=threshold(1)) | (y0>=threshold(2)));
                        xdir = [xdir0,'_threshold'];
                        if isempty(dir(xdir))
                            mkdir(xdir)
                        end
                        if ~options_.nograph
                            hf=dyn_figure(options_.nodisplay,'name',['Reduced Form Mapping (Monte Carlo Filtering): ',namendo,' vs ', namexo]);
                            hc = gsa.cumplot(y0);
                            a=axis; delete(hc);
                            x1val=max(threshold(1),a(1));
                            x2val=min(threshold(2),a(2));
                            hp = patch([x1val x2val x2val x1val],a([3 3 4 4]),'b');
                            set(hp,'FaceColor', [0.7 0.8 1])
                            hold all,
                            hc = gsa.cumplot(y0);
                            set(hc,'color','k','linewidth',2)
                            hold off,
                            if options_.TeX
                                title([namendo_tex,' vs ', namexo_tex ' - threshold [' num2str(threshold(1)) ' ' num2str(threshold(2)) ']'],'interpreter','latex')
                            else
                                title([namendo,' vs ', namexo ' - threshold [' num2str(threshold(1)) ' ' num2str(threshold(2)) ']'],'interpreter','none')
                            end
                            dyn_saveas(hf,[xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namexo],options_.nodisplay,options_.graph_format);
                            create_TeX_loader(options_,[xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namexo],['Reduced Form Mapping (Monte Carlo Filtering): ',namendo_tex,' vs ', namexo_tex],[type '_' namendo,'_vs_', namexo])
                        end
                        si(:,js) = NaN(np,1);
                        delete([xdir, '/*threshold*.*'])

                        atitle0=['Reduced Form Mapping (Monte Carlo Filtering) for ',namendo,' vs ', namexo];
                        aname=[type '_' namendo '_vs_' namexo '_threshold'];
                        atitle=[type ' Reduced Form Mapping (Monte Carlo Filtering): Parameter(s) driving ',namendo,' vs ',namexo];
                        options_mcf.amcf_name = aname;
                        options_mcf.amcf_title = atitle;
                        options_mcf.beha_title = 'inside threshold';
                        options_mcf.nobeha_title = 'outside threshold';
                        if options_.TeX
                            options_mcf.beha_title_latex = 'inside threshold';
                            options_mcf.nobeha_title_latex = 'outside threshold';
                        end
                        options_mcf.title = atitle0;
                        options_mcf.OutputDirectoryName = xdir;
                        if ~isempty(iy) && ~isempty(iyc)
                            fprintf(['%4.1f%% of the ',type,' support matches ',atitle0,'\n'],length(iy)/length(y0)*100)
                            icheck = gsa.monte_carlo_filtering_analysis(x0, iy, iyc, options_mcf, M_, options_, estim_params_);

                            lpmat=x0(iy,:);
                            if nshocks
                                lpmat0=xx0(iy,:);
                            end
                            istable=1:length(iy);
                            save([xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namexo '_threshold' ],'lpmat','lpmat0','istable','y0','x0','xx0','iy','iyc')
                            lpmat0=[];
                            if length(iy)<=10 || length(iyc)<=10
                                icheck = [];  % do the generic plot in any case
                            end
                        else
                            icheck=[];
                        end
                        if isempty(icheck)
                            if length(iy)<=10
                                if isempty(iy)
                                    disp(['There are NO MC samples in the desired range [' num2str(threshold) ']!'])
                                else
                                    disp(['There are TOO FEW (<=10) MC samples  in the desired range [' num2str(threshold) ']!'])
                                end
                            elseif length(iyc)<=10
                                if isempty(iyc)
                                    disp(['ALL MC samples are in the desired range [' num2str(threshold) ']!'])
                                else
                                    disp(['Almost ALL MC samples are in the desired range [' num2str(threshold) ']!'])
                                    disp('There are TOO FEW (<=10) MC samples OUTSIDE the desired range!')
                                end
                            end
                            atitle0=['Monte Carlo Filtering for ',namendo,' vs ', namexo];
                            options_mcf.title = atitle0;
                            redform_mcf(y0, x0, options_mcf, options_, M_.fname, Prior.name, estim_params_);
                        end
                    end
                else
                    atitle0=['Reduced Form Mapping (ANOVA) for log-transformed ',namendo,' vs ', namexo];
                    aname=[type '_' namendo '_vs_' namexo];
                    atitle=[type ' Reduced Form Mapping (ANOVA): Parameter(s) driving ',namendo,' vs ',namexo];
                    options_map.amap_name = aname;
                    options_map.amap_title = atitle;
                    options_map.figtitle = atitle0;
                    options_map.title = ['log(' namendo ' vs ' namexo ')'];
                    options_map.OutputDirectoryName = xdir0;
                    silog(:,js) = redform_private(x0, y0, options_map, options_);
                end

                if isempty(threshold) && ~options_.nograph
                    figure(hh_fig)
                    subplot(3,3,iplo),
                    if ilog
                        [~, iso] = sort(-silog(:,js));
                        bar([silog(iso(1:min(np,10)),js)])
                        logflag='log';
                    else
                        [~, iso] = sort(-si(:,js));
                        bar(si(iso(1:min(np,10)),js))
                        logflag='';
                    end
                    set(gca,'xticklabel',' ','fontsize',10)
                    set(gca,'xlim',[0.5 10.5])
                    for ip=1:min(np,10)
                        if options_.TeX
                            text(ip,-0.02,deblank(pnames_tex(iso(ip),:)),'rotation',90,'HorizontalAlignment','right','interpreter','latex')
                        else
                            text(ip,-0.02,deblank(pnames(iso(ip),:)),'rotation',90,'HorizontalAlignment','right','interpreter','none')
                        end
                    end
                    if options_.TeX
                        title([logflag,' ',namendo_tex,' vs ',namexo_tex],'interpreter','none')
                    else
                        title([logflag,' ',namendo,' vs ',namexo],'interpreter','none')
                    end
                    if iplo==9
                        dyn_saveas(hh_fig,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_shocks_',logflag,num2str(ifig)],options_.nodisplay,options_.graph_format);
                        create_TeX_loader(options_,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_shocks_',logflag,num2str(ifig)],[logflag,' ',namendo_tex,' vs ',namexo_tex],['redform_', namendo,'_vs_shocks_',logflag,num2str(ifig)],1)
                    end
                end

            else
                disp(['This entry in the shock matrix is CONSTANT = ' num2str(mean(y0),3)])
            end
        end
    end
    if iplo<9 && iplo>0 && ifig && ~options_.nograph
        dyn_saveas(hh_fig,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_shocks_',logflag,num2str(ifig)],options_.nodisplay,options_.graph_format);
        create_TeX_loader(options_,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_shocks_',logflag,num2str(ifig)],[logflag,' ',strrep(namendo,'_','\_'),' vs ',strrep(namexo,'_','\_')],['redform_', namendo,'_vs_shocks_',logflag,num2str(ifig)],options_.figures.textwidth*min(iplo/3,1))
    end
    ifig=0;
    iplo=0;
    for je=1:length(anamlagendo)
        namlagendo = anamlagendo{je};
        namlagendo_tex = anamlagendo_tex{je};
        ilagendo=strmatch(namlagendo, M_.endo_names(oo_.dr.order_var(M_.nstatic+1:M_.nstatic+nsok)), 'exact');
        skipline()
        disp(['[', namendo,' vs lagged ',namlagendo,']'])

        if ~isempty(ilagendo)
            y0=squeeze(T(iendo,ilagendo,:));
            if (max(y0)-min(y0))>1.e-10
                if mod(iplo,9)==0 && isempty(threshold) && ~options_.nograph
                    ifig=ifig+1;
                    hh_fig = dyn_figure(options_.nodisplay,'name',['Reduced Form Mapping: ' namendo,' vs lags ',int2str(ifig)]);
                    iplo=0;
                end
                iplo=iplo+1;
                js=js+1;
                xdir0 = [adir,filesep,namendo,'_vs_', namlagendo];
                if ilog==0 || ~isempty(threshold)
                    if isempty(threshold)
                        if isempty(dir(xdir0))
                            mkdir(xdir0)
                        end
                        atitle0=['Reduced Form Mapping (ANOVA) for ',namendo,' vs lagged', namlagendo];
                        aname=[type '_' namendo '_vs_lag_' namlagendo];
                        atitle=[type ' Reduced Form Mapping (ANOVA): Parameter(s) driving ',namendo,' vs lagged',namlagendo];
                        options_map.amap_name = aname;
                        options_map.amap_title = atitle;
                        options_map.figtitle = atitle0;
                        options_map.title = [namendo,' vs ', namlagendo];
                        options_map.OutputDirectoryName = xdir0;
                        si(:,js) = redform_private(x0, y0, options_map, options_);
                    else
                        iy=find( (y0>threshold(1)) & (y0<threshold(2)));
                        iyc=find( (y0<=threshold(1)) | (y0>=threshold(2)));
                        xdir = [xdir0,'_threshold'];
                        if isempty(dir(xdir))
                            mkdir(xdir)
                        end
                        if ~options_.nograph
                            hf=dyn_figure(options_.nodisplay,'name',['Reduced Form Mapping (Monte Carlo Filtering): ',namendo,' vs lagged ', namlagendo]);
                            hc = gsa.cumplot(y0);
                            a=axis; delete(hc);
                            x1val=max(threshold(1),a(1));
                            x2val=min(threshold(2),a(2));
                            hp = patch([x1val x2val x2val x1val],a([3 3 4 4]),'b');
                            set(hp,'FaceColor', [0.7 0.8 1])
                            hold all,
                            hc = gsa.cumplot(y0);
                            set(hc,'color','k','linewidth',2)
                            hold off
                            if options_.TeX
                                title([namendo_tex,' vs lagged ', namlagendo_tex ' - threshold [' num2str(threshold(1)) ' ' num2str(threshold(2)) ']'],'interpreter','latex')
                            else
                                title([namendo,' vs lagged ', namlagendo ' - threshold [' num2str(threshold(1)) ' ' num2str(threshold(2)) ']'],'interpreter','none')
                            end
                            dyn_saveas(hf,[xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namlagendo],options_.nodisplay,options_.graph_format);
                            create_TeX_loader(options_,[xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namlagendo],['Reduced Form Mapping (Monte Carlo Filtering): ',namendo_tex,' vs lagged ', namlagendo_tex],[type '_' namendo,'_vs_', namlagendo],1)
                        end

                        delete([xdir, '/*threshold*.*'])

                        atitle0=['Reduced Form Mapping (Monte Carlo Filtering) for ',namendo,' vs ', namlagendo];
                        aname=[type '_' namendo '_vs_' namlagendo '_threshold'];
                        atitle=[type ' Reduced Form Mapping (Monte Carlo Filtering): Parameter(s) driving ',namendo,' vs ',namlagendo];
                        options_mcf.amcf_name = aname;
                        options_mcf.amcf_title = atitle;
                        options_mcf.beha_title = 'inside threshold';
                        options_mcf.nobeha_title = 'outside threshold';
                        if options_.TeX
                            options_mcf.beha_title_latex = 'inside threshold';
                            options_mcf.nobeha_title_latex = 'outside threshold';
                        end

                        options_mcf.title = atitle0;
                        options_mcf.OutputDirectoryName = xdir;
                        if ~isempty(iy) && ~isempty(iyc)

                            fprintf(['%4.1f%% of the ',type,' support matches ',atitle0,'\n'],length(iy)/length(y0)*100)
                            icheck = gsa.monte_carlo_filtering_analysis(x0, iy, iyc, options_mcf, M_, options_, estim_params_);

                            lpmat=x0(iy,:);
                            if nshocks
                                lpmat0=xx0(iy,:);
                            end
                            istable=1:length(iy);
                            save([xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namlagendo '_threshold' ],'lpmat','lpmat0','istable','y0','x0','xx0','iy','iyc')
                            lpmat0=[];
                            if length(iy)<=10 || length(iyc)<=10
                                icheck = [];  % do the generic plot in any case
                            end
                        else
                            icheck = [];
                        end
                        if isempty(icheck)
                            if length(iy)<=10
                                if isempty(iy)
                                    disp(['There are NO MC samples in the desired range [' num2str(threshold) ']!'])
                                else
                                    disp(['There are TOO FEW (<=10) MC samples  in the desired range [' num2str(threshold) ']!'])
                                end
                            elseif length(iyc)<=10
                                if isempty(iyc)
                                    disp(['ALL MC samples are in the desired range [' num2str(threshold) ']!'])
                                else
                                    disp(['Almost ALL MC samples are in the desired range [' num2str(threshold) ']!'])
                                    disp('There are TOO FEW (<=10) MC samples OUTSIDE the desired range!')
                                end
                            end
                            atitle0=['Monte Carlo Filtering for ',namendo,' vs ', namlagendo];
                            options_mcf.title = atitle0;
                            redform_mcf(y0, x0, options_mcf, options_, M_.fname, Prior.name, estim_params_);
                        end
                    end
                else
                    atitle0=['Reduced Form Mapping (ANOVA) for log-transformed ',namendo,' vs ', namlagendo];
                    aname=[type '_' namendo '_vs_' namlagendo];
                    atitle=[type ' Reduced Form Mapping (ANOVA): Parameter(s) driving ',namendo,' vs ',namlagendo];
                    options_map.amap_name = aname;
                    options_map.amap_title = atitle;
                    options_map.figtitle = atitle0;
                    options_map.title = ['log(' namendo ' vs ' namlagendo ')'];
                    options_map.OutputDirectoryName = xdir0;
                    silog(:,js) = redform_private(x0, y0, options_map, options_);
                end

                if isempty(threshold) && ~options_.nograph
                    figure(hh_fig),
                    subplot(3,3,iplo),
                    if ilog
                        [~, iso] = sort(-silog(:,js));
                        bar([silog(iso(1:min(np,10)),js)])
                        logflag='log';
                    else
                        [~, iso] = sort(-si(:,js));
                        bar(si(iso(1:min(np,10)),js))
                        logflag='';
                    end
                    set(gca,'xticklabel',' ','fontsize',10)
                    set(gca,'xlim',[0.5 10.5])
                    for ip=1:min(np,10)
                        if options_.TeX
                            text(ip,-0.02,deblank(pnames_tex(iso(ip),:)),'rotation',90,'HorizontalAlignment','right','interpreter','latex')
                        else
                            text(ip,-0.02,deblank(pnames(iso(ip),:)),'rotation',90,'HorizontalAlignment','right','interpreter','none')
                        end
                    end
                    title([logflag,' ',namendo,' vs ',namlagendo,'(-1)'],'interpreter','none')
                    if iplo==9
                        dyn_saveas(hh_fig,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_lags_',logflag,num2str(ifig)],options_.nodisplay,options_.graph_format);
                        create_TeX_loader(options_,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_lags_',logflag,num2str(ifig)],[logflag,' ',namendo_tex,' vs ',namlagendo_tex,'(-1)'],['redform_', namendo,'_vs_lags_',logflag,':',num2str(ifig)],1)
                    end
                end

            else
                disp(['This entry in the transition matrix is CONSTANT = ' num2str(mean(y0),3)])
            end
        end
    end
    if iplo<9 && iplo>0 && ifig && ~options_.nograph
        dyn_saveas(hh_fig,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_lags_',logflag,num2str(ifig)],options_.nodisplay,options_.graph_format);
        create_TeX_loader(options_,[dirname,filesep,M_.fname,'_redform_', namendo,'_vs_lags_',logflag,num2str(ifig)],[logflag,' ',namendo_tex,' vs ',namlagendo_tex,'(-1)'],['redform_', namendo,'_vs_lags_',logflag,':',num2str(ifig)],options_.figures.textwidth*min(iplo/3,1));
    end
end

if isempty(threshold) && ~options_.nograph
    hh_fig=dyn_figure(options_.nodisplay,'name','Reduced Form GSA');
    if ilog==0
        gsa.boxplot(si',[],'.',[],10)
    else
        gsa.boxplot(silog',[],'.',[],10)
    end
    xlabel(' ')
    set(gca,'xticklabel',' ','fontsize',10,'xtick',1:np)
    set(gca,'xlim',[0.5 np+0.5])
    set(gca,'ylim',[0 1])
    set(gca,'position',[0.13 0.2 0.775 0.7])
    for ip=1:np
        text(ip,-0.02,deblank(pnames(ip,:)),'rotation',90,'HorizontalAlignment','right','interpreter','none')
    end
    if ilog==0
        title('Reduced form GSA')
        dyn_saveas(hh_fig,[dirname,filesep,M_.fname,'_redform_gsa'],options_.nodisplay,options_.graph_format);
        create_TeX_loader(options_,[dirname,filesep,M_.fname,'_redform_gsa'],'Reduced Form GSA','redform_gsa')
    else
        title('Reduced form GSA - Log-transformed elements')
        dyn_saveas(hh_fig,[dirname,filesep,M_.fname,'_redform_gsa_log'],options_.nodisplay,options_.graph_format);
        create_TeX_loader(options_,[dirname,filesep,M_.fname,'_redform_gsa_log'],'Reduced form GSA - Log-transformed elements','redform_gsa_log')
    end
end

function si  = redform_private(x0, y0, options_map, options_)
np=size(x0,2);
x00=x0;
ilog = options_map.log_trans;
iload = options_map.iload;
pnames = options_map.param_names;
pd = options_map.pd;
pshape = options_map.pshape;
xdir = options_map.OutputDirectoryName;
if options_map.prior_range
    for j=1:np
        x0(:,j)=(x0(:,j)-pd(j,3))./(pd(j,4)-pd(j,3));
    end
else
    x0=gsa.priorcdf(x0,pshape, pd(:,1), pd(:,2), pd(:,3), pd(:,4));
end

if ilog
    fname=[xdir filesep options_map.fname_ '_' options_map.amap_name '_log'];
else
    fname=[xdir filesep options_map.fname_ '_' options_map.amap_name];
end
if iload==0
    if isempty(dir(xdir))
        mkdir(xdir)
    end
    nrun=length(y0);
    nest=max(50,nrun/2);
    nest=min(250,nest);
    nfit=min(1000,nrun);
    [~,is] = sort(y0);
    istep = ceil(nrun/nest);
    if istep>1
        iest = is(floor(istep/2):istep:end);
        nest = length(iest);
        irest = is(setdiff(1:nrun,floor(istep/2):istep:nrun));
        istep = ceil(length(irest)/(nfit-nest));
        ifit = union(iest, irest(1:istep:end));
    else
        warning('the number of samples is too small for ANOVA estimation')
        si=nan(np,1);
        return
    end
    if ~ismember(irest(end),ifit)
        ifit = union(ifit, irest(end));
    end
    nfit=length(ifit);
    ipred = setdiff(1:nrun,ifit);

    if ilog
        [~, ~, isig, lam] = gsa.log_transform(y0(iest));
        y1 = log(y0*isig+lam);
    end
    if ~options_.nograph
        hh_fig=dyn_figure(options_.nodisplay,'name',options_map.figtitle);
        subplot(221)
        if ilog
            if isoctave
                hist(y1,30)
            else
                histogram(y1,30)
            end
        else
            if isoctave
                hist(y0,30)
            else
                histogram(y0,30)
            end
        end
        title(options_map.title,'interpreter','none')
        subplot(222)
        if ilog
            hc = gsa.cumplot(y1);
        else
            hc = gsa.cumplot(y0);
        end
        set(hc,'color','k','linewidth',2)
        title([options_map.title ' CDF'],'interpreter','none')
    end

    gsa0 = ss_anova(y0(iest), x0(iest,:), 1);
    if ilog
        [gsa22, gsa1, gsax] = ss_anova_log(y1(iest), x0(iest,:), isig, lam, gsa0);
    end
    if nfit>nest
        nvr =  gsa0.nvr*nest^3/nfit^3;
        nvr(gsa0.stat<2) = gsa0.nvr(gsa0.stat<2)*nest^5/nfit^5;
        gsa_ = ss_anova(y0(ifit), x0(ifit,:), 1, 0, 2, nvr);
        if ilog
            gsa0 = gsa_;
            nvr1 =  gsa1.nvr*nest^3/nfit^3;
            nvr1(gsa1.stat<2) = gsa1.nvr(gsa1.stat<2)*nest^5/nfit^5;
            nvrx =  gsax.nvr*nest^3/nfit^3;
            nvrx(gsax.stat<2) = gsax.nvr(gsax.stat<2)*nest^5/nfit^5;
            [gsa22, gsa1, gsax] = ss_anova_log(y1(ifit), x0(ifit,:), isig, lam, gsa0, [nvr1' nvrx']);
            gsa_ = gsa22;
        end
    else
        if ilog
            gsa_ = gsa22;
        else
            gsa_ = gsa0;
        end
    end
    save([fname,'_map.mat'],'gsa_')
    [~, iii]=sort(-gsa_.si);
    gsa_.x0=x00(ifit,:);
    if ~options_.nograph
        hmap=gsa_sdp_plot(gsa_,[fname '_map'],pnames,iii(1:min(12,np)));
        set(hmap,'name',options_map.amap_title);
    end
    gsa_.x0=x0(ifit,:);
    if ~options_.nograph
        figure(hh_fig);
        subplot(223),
        plot(y0(ifit),[gsa_.fit y0(ifit)],'.'),
        r2 = gsa_.r2;
        title(['Learning sample fit - R2=' num2str(r2,2)],'interpreter','none')
        if nfit<nrun
            if ilog
                yf = ss_anova_fcast(x0(ipred,:), gsa1);
                yf = gsa.log_transform(yf,'',isig,lam)+ss_anova_fcast(x0(ipred,:), gsax);
            else
                yf = ss_anova_fcast(x0(ipred,:), gsa_);
            end
            yn = y0(ipred);
            r2  = 1-cov(yf-yn)/cov(yn);
            subplot(224),
            plot(yn,[yf yn],'.'),
            title(['Out-of-sample prediction - R2=' num2str(r2,2)],'interpreter','none')
        end
        dyn_saveas(hh_fig,fname,options_.nodisplay,options_.graph_format);
        create_TeX_loader(options_,fname,['Out-of-sample prediction - R2=' num2str(r2,2)],'redform_gsa_log')

        if options_.nodisplay
            close(hmap);
        end
    end
else
    load([fname,'_map.mat'],'gsa_')
    if ~options_.nograph
        yf = ss_anova_fcast(x0, gsa_);
        hh_fig=dyn_figure(options_.nodisplay,'name',options_map.title);
        plot(y0,[yf y0],'.'),
        title([namy,' vs ', namx,' pred'],'interpreter','none')
        dyn_saveas(hh_fig,[fname '_pred'],options_.nodisplay,options_.graph_format);
        create_TeX_loader(options_,[fname '_pred'],options_map.title,[namy,' vs ', namx,' pred'])
    end
end
si = gsa_.si;

return

function gsa2 = log2level_map(gsa1, isig, lam)

nest=length(gsa1.y);
np = size(gsa1.x0,2);
gsa2=gsa1;
gsa2.y = gsa.log_transform(gsa1.y,'',isig,lam);
gsa2.fit = (exp(gsa1.fit)-lam)*isig;
gsa2.f0 = mean(gsa2.fit);
gsa2.out.SSE = sum((gsa2.fit-gsa2.y).^2);
gsa2.out.bic = gsa2.out.bic-nest*log(gsa1.out.SSE)+nest*log(gsa2.out.SSE);
gsa2.r2 = 1-cov(gsa2.fit-gsa2.y)/cov(gsa2.y);
for j=1:np
    gsa2.fs(:,j) = exp(gsa1.fs(:,j)).*mean(exp(gsa1.fit-gsa1.f(:,j)))*isig-lam*isig-gsa2.f0;
    gsa2.fses(:,j) = exp(gsa1.fs(:,j)+gsa1.fses(:,j)).*mean(exp(gsa1.fit-gsa1.f(:,j)))*isig-lam*isig-gsa2.f0-gsa2.fs(:,j);
    gsa2.f(:,j) = exp(gsa1.f(:,j)).*mean(exp(gsa1.fit-gsa1.f(:,j)))*isig-lam*isig-gsa2.f0;
    gsa2.si(j) = var(gsa2.f(:,j))/var(gsa2.y);
end

return


function [gsa22, gsa1, gsax] = ss_anova_log(y,x,isig,lam,gsa0,nvrs)

[nest, np]=size(x);

if nargin==6
    gsa1 = ss_anova(y, x, 1, 0, 2, nvrs(:,1));
else
    gsa1 = ss_anova(y, x, 1);
end
gsa2 = log2level_map(gsa1, isig, lam);
if nargin >=5 && ~isempty(gsa0)
    nvr2=NaN(np,1);
    nvr0=NaN(np,1);
    for j=1:np
        nvr2(j) = var(diff(gsa2.fs(:,j),2));
        nvr0(j) = var(diff(gsa0.fs(:,j),2));
    end
    inda = find((gsa0.stat<2)&(gsa1.stat>2));
    inda = inda(log10(nvr0(inda)./nvr2(inda))/2<0);
    gsa1.nvr(inda)=gsa1.nvr(inda).*10.^(log10(nvr0(inda)./nvr2(inda)));
    gsa1 = ss_anova(y, x, 1, 0, 2, gsa1.nvr);
    gsa2 = log2level_map(gsa1, isig, lam);
end
if nargin==6
    gsax = ss_anova(gsa2.y-gsa2.fit, x, 1, 0, 2, nvrs(:,2));
else
    gsax = ss_anova(gsa2.y-gsa2.fit, x, 1);
end
gsa22=gsa2;
gsa22.fit = gsa2.fit+gsax.fit;
gsa22.f0 = mean(gsa22.fit);
gsa22.out.SSE = sum((gsa22.fit-gsa22.y).^2);
gsa22.out.bic = nest*log(gsa22.out.SSE/nest) + (gsax.out.df+gsa2.out.df-1)*log(nest);
gsa22.r2 = 1-sum((gsa22.fit-gsa22.y).^2)/sum((gsa22.y-mean(gsa22.y)).^2);
for j=1:np
    gsa22.fs(:,j) = gsa2.fs(:,j)+gsax.fs(:,j);
    gsa22.fses(:,j) = gsax.fses(:,j);
    gsa22.f(:,j) = gsa2.f(:,j)+gsax.f(:,j);
    gsa22.si(j) = var(gsa22.f(:,j))/var(gsa22.y);
end

return

function indmcf = redform_mcf(y0, x0, options_mcf, options_, fname, parnames, estim_params_)

hh_fig=dyn_figure(options_.nodisplay,'name',options_mcf.amcf_title);

[~, ~, ~, ~, post_deciles] = posterior_moments(y0,0.9);
post_deciles = [-inf; post_deciles; inf];

for jt=1:10
    indy{jt}=find( (y0>post_deciles(jt)) & (y0<=post_deciles(jt+1)));
    leg{jt}=[int2str(jt) '-dec'];
end
[proba] = gsa.stability_mapping_univariate(x0, indy{1}, indy{end}, [], fname, options_, parnames, estim_params_,0);
indmcf=find(proba<options_mcf.pvalue_ks);
if isempty(indmcf)
    [~,jtmp] = sort(proba,1,'ascend');
    indmcf = jtmp(1);
end
[~,jtmp] = sort(proba(indmcf),1,'ascend');
indmcf = indmcf(jtmp);
nbr_par = length(indmcf);
nrow=ceil(sqrt(nbr_par+1));
ncol=nrow;
if nrow*(nrow-1)>nbr_par
    ncol=nrow-1;
end

cmap = colormap(jet(10));
for jx=1:nbr_par
    subplot(nrow,ncol,jx)
    hold off
    for jt=1:10
        h=gsa.cumplot(x0(indy{jt},indmcf(jx)));
        set(h,'color', cmap(jt,:), 'linewidth', 2)
        hold all
    end
    if options_.TeX
        title(options_mcf.param_names_tex(indmcf(jx),:),'interpreter','latex')
    else
        title(options_mcf.param_names(indmcf(jx),:),'interpreter','none')
    end
end
hleg = legend(leg);
aa=get(hleg,'Position');
aa(1)=1-aa(3)-0.02;
aa(2)=0.02;
set(hleg,'Position',aa);
if ~isoctave
    annotation('textbox', [0.25,0.01,0.5,0.05], ...
               'String', options_mcf.title, ...
               'Color','black',...
               'FontWeight','bold',...
               'interpreter','none',...
               'horizontalalignment','center');
end

dyn_saveas(hh_fig,[options_mcf.OutputDirectoryName filesep options_mcf.fname_,'_',options_mcf.amcf_name],options_.nodisplay,options_.graph_format);
create_TeX_loader(options_,[options_mcf.OutputDirectoryName filesep options_mcf.fname_,'_',options_mcf.amcf_name],strrep(options_mcf.amcf_title,'_','\_'),[options_mcf.fname_,'_',options_mcf.amcf_name])

return

function []=create_TeX_loader(options_,figpath,caption,label_name,scale_factor)
if nargin<5
    scale_factor=1;
end
if options_.TeX && any(strcmp('eps',cellstr(options_.graph_format)))
    fidTeX = fopen([figpath '.tex'],'w');
    fprintf(fidTeX,'%% TeX eps-loader file generated by reduced_form_mapping.m (Dynare).\n');
    fprintf(fidTeX,['%% ' datestr(now,0) '\n\n']);
    fprintf(fidTeX,'\\begin{figure}[H]\n');
    fprintf(fidTeX,'\\centering \n');
    fprintf(fidTeX,'\\includegraphics[width=%2.2f\\textwidth]{%s}\n',scale_factor,strrep(figpath,'\','/'));
    fprintf(fidTeX,'\\caption{%s.}',caption);
    fprintf(fidTeX,'\\label{Fig:%s}\n',label_name);
    fprintf(fidTeX,'\\end{figure}\n\n');
    fprintf(fidTeX,'%% End Of TeX file. \n');
    fclose(fidTeX);
end
